From 5fdce34295b3c08e5c16f388875fd3ef56c04be7 Mon Sep 17 00:00:00 2001 From: Sahiba3108 <108404805+Sahiba3108@users.noreply.github.com> Date: Mon, 31 Oct 2022 13:06:47 +0530 Subject: [PATCH] Add cert rotate command for HA Service (#7494) * add cert rotate command Signed-off-by: Sahiba3108 * fix pipelines Signed-off-by: Sahiba3108 * fix review Signed-off-by: Sahiba3108 * fix pipelines Signed-off-by: Sahiba3108 * fix review Signed-off-by: Sahiba3108 * some code change Signed-off-by: Sahiba3108 * resolve syntax error Signed-off-by: Sahiba3108 * cert rotate for automate and chef server Signed-off-by: Sahiba3108 * code review change Signed-off-by: Sahiba3108 Signed-off-by: Sahiba3108 --- .../cmd/chef-automate/certRotate.go | 135 ++++++++++++++++++ .../automate-cli/cmd/chef-automate/config.go | 2 +- .../a2ha-terraform/modules/aws/outputs.tf | 4 +- .../a2ha-terraform/modules/vsphere/outputs.tf | 3 + 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 components/automate-cli/cmd/chef-automate/certRotate.go diff --git a/components/automate-cli/cmd/chef-automate/certRotate.go b/components/automate-cli/cmd/chef-automate/certRotate.go new file mode 100644 index 00000000000..6a23cba524d --- /dev/null +++ b/components/automate-cli/cmd/chef-automate/certRotate.go @@ -0,0 +1,135 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "time" + + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var certFlags = struct { + privateCert string + publicCert string +}{} + +var sshFlag = struct { + automate bool + chefserver bool +}{} + +var certRotateCmd = &cobra.Command{ + Use: "cert-rotate", + Short: "Chef Automate rotate cert", + Long: "Chef Automate CLI command to rotate certificates", + RunE: certRotate, +} + +func init() { + RootCmd.AddCommand(certRotateCmd) + + certRotateCmd.PersistentFlags().BoolVar(&sshFlag.automate, "automate", false, "Automate Certificate Rotation") + certRotateCmd.PersistentFlags().BoolVar(&sshFlag.automate, "a2", false, "Automate Certificate Rotation") + certRotateCmd.PersistentFlags().BoolVar(&sshFlag.chefserver, "chefserver", false, "Chef Infra Server Certificate Rotation") + certRotateCmd.PersistentFlags().BoolVar(&sshFlag.chefserver, "cs", false, "Chef Infra Server Certificate Rotation") + + certRotateCmd.PersistentFlags().StringVar(&certFlags.privateCert, "private-cert", "", "Private certificate") + certRotateCmd.PersistentFlags().StringVar(&certFlags.publicCert, "public-cert", "", "Public certificate") +} + +const ( + FRONTEND_CONFIG = ` + [[load_balancer.v1.sys.frontend_tls]] + cert = """%v""" + key = """%v""" + [[global.v1.frontend_tls]] + cert = """%v""" + key = """%v"""` +) + +func certRotate(cmd *cobra.Command, args []string) error { + privateCertPath := certFlags.privateCert + publicCertPath := certFlags.publicCert + fileName := "cert-rotate.toml" + timestamp := time.Now().Format("20060102150405") + + if privateCertPath == "" || publicCertPath == "" { + return errors.New("Please provide public and private cert paths") + } + privateCert, err := ioutil.ReadFile(privateCertPath) // nosemgrep + if err != nil { + return status.Wrap( + err, + status.FileAccessError, + fmt.Sprintf("failed reading data from file: %s", err.Error()), + ) + } + + publicCert, err := ioutil.ReadFile(publicCertPath) // nosemgrep + if err != nil { + return status.Wrap( + err, + status.FileAccessError, + fmt.Sprintf("failed reading data from file: %s", err.Error()), + ) + } + + f, err := os.Create(fileName) + if err != nil { + log.Fatal(err) + } + + if isA2HARBFileExist() { + + infra, err := getAutomateHAInfraDetails() + if err != nil { + return err + } + sshUser := infra.Outputs.SSHUser.Value + sskKeyFile := infra.Outputs.SSHKeyFile.Value + sshPort := infra.Outputs.SSHPort.Value + + if sshFlag.automate || sshFlag.chefserver { + config := fmt.Sprintf(FRONTEND_CONFIG, string(publicCert), string(privateCert), string(publicCert), string(privateCert)) + _, err = f.Write([]byte(config)) + if err != nil { + log.Fatal(err) + } + f.Close() + + var frontendIps []string + var remoteService string + if sshFlag.automate { + frontendIps = infra.Outputs.AutomatePrivateIps.Value + remoteService = "automate" + } else if sshFlag.chefserver { + frontendIps = infra.Outputs.ChefServerPrivateIps.Value + remoteService = "chefserver" + } + if len(frontendIps) == 0 { + return errors.New(fmt.Sprintf("No %s Ips found", remoteService)) + } + + scriptCommands := fmt.Sprintf(FRONTEND_COMMANDS, remoteService+timestamp, dateFormat) + for i := 0; i < len(frontendIps); i++ { + err := copyFileToRemote(sskKeyFile, fileName, sshUser, frontendIps[i], remoteService+timestamp) + if err != nil { + writer.Errorf("%v", err) + return err + } + output, err := ConnectAndExecuteCommandOnRemote(sshUser, sshPort, sskKeyFile, frontendIps[i], scriptCommands) + if err != nil { + writer.Errorf("%v", err) + return err + } + writer.Printf(output) + } + + } + } + return nil +} diff --git a/components/automate-cli/cmd/chef-automate/config.go b/components/automate-cli/cmd/chef-automate/config.go index 4925f04adbf..d19bd86fcf2 100644 --- a/components/automate-cli/cmd/chef-automate/config.go +++ b/components/automate-cli/cmd/chef-automate/config.go @@ -348,7 +348,7 @@ func runSetCommand(cmd *cobra.Command, args []string) error { func copyFileToRemote(sshKeyFile string, tomlFilePath string, sshUser string, hostIP string, destFileName string) error { cmd := "scp" - exec_args := []string{"-o StrictHostKeyChecking=off", "-i", sshKeyFile, "-r", tomlFilePath, sshUser + "@" + hostIP + ":/tmp/" + destFileName} + exec_args := []string{"-o StrictHostKeyChecking=no", "-i", sshKeyFile, "-r", tomlFilePath, sshUser + "@" + hostIP + ":/tmp/" + destFileName} if err := exec.Command(cmd, exec_args...).Run(); err != nil { writer.Print("Failed to copy TOML file to remote\n") return err diff --git a/terraform/a2ha-terraform/modules/aws/outputs.tf b/terraform/a2ha-terraform/modules/aws/outputs.tf index ae7aefcd968..fa29fe4a5c1 100644 --- a/terraform/a2ha-terraform/modules/aws/outputs.tf +++ b/terraform/a2ha-terraform/modules/aws/outputs.tf @@ -103,4 +103,6 @@ output "aws_cluster_id" { output "ssh_user" { value = var.aws_ssh_user } - +output "ssh_port" { + value = var.aws_ssh_port +} diff --git a/terraform/a2ha-terraform/modules/vsphere/outputs.tf b/terraform/a2ha-terraform/modules/vsphere/outputs.tf index 5f38a98ae33..474922da5d1 100644 --- a/terraform/a2ha-terraform/modules/vsphere/outputs.tf +++ b/terraform/a2ha-terraform/modules/vsphere/outputs.tf @@ -64,3 +64,6 @@ output "opensearch_public_ips" { output "ssh_user" { value = var.aws_ssh_user } +output "ssh_port" { + value = var.aws_ssh_port +}