diff --git a/VERSION b/VERSION index e815b86..04a373e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.15.1 +0.16.0 diff --git a/pkg/deploy/aks.go b/pkg/deploy/aks.go index b0f823b..2c6d713 100644 --- a/pkg/deploy/aks.go +++ b/pkg/deploy/aks.go @@ -18,8 +18,6 @@ type SetupAKSOptions struct { func setupAKS( tenantID string, environment string, - skipAuthentication bool, - skipGettingCredentials bool, options *SetupAKSOptions, ) error { if options == nil { @@ -37,49 +35,45 @@ func setupAKS( return err } - if !skipAuthentication { - err = auth.AuthenticateAzure( - tenantID, - subscriptionID, - options.AzLoginOptions, - ) - if err != nil { - return fmt.Errorf("Failed to authenticate with AKS: %w", err) - } + err = auth.AuthenticateAzure( + tenantID, + subscriptionID, + options.AzLoginOptions, + ) + if err != nil { + return fmt.Errorf("Failed to authenticate with AKS: %w", err) } - if !skipGettingCredentials { - checkKubeLoginInstalledOutput := checkKubeloginInstalledCommand(nil) - if command.IsError(checkKubeLoginInstalledOutput) { - return checkKubeLoginInstalledOutput.Error + checkKubeLoginInstalledOutput := checkKubeloginInstalledCommand(nil) + if command.IsError(checkKubeLoginInstalledOutput) { + return checkKubeLoginInstalledOutput.Error + } + + clusterName := func() string { + if options.ClusterName == "" { + return "akscluster" + environment } + return options.ClusterName + }() - clusterName := func() string { - if options.ClusterName == "" { - return "akscluster" + environment - } - return options.ClusterName - }() - - contextName := "aks" + environment - - resourceGroupName := func() string { - if options.ResourceGroupName == "" { - return "RUNTIMESERVICE-RG" + environment - } - return options.ResourceGroupName - }() - - runKubeloginConvert := options.AzLoginOptions.FederatedToken != "" && options.AzLoginOptions.ClientID != "" - if err := getAKSCredentials( - resourceGroupName, - clusterName, - subscriptionID, - contextName, - runKubeloginConvert, - ); err != nil { - return fmt.Errorf("Failed to get AKS credentials: %w", err) + contextName := "aks" + environment + + resourceGroupName := func() string { + if options.ResourceGroupName == "" { + return "RUNTIMESERVICE-RG" + environment } + return options.ResourceGroupName + }() + + runKubeloginConvert := options.AzLoginOptions.FederatedToken != "" && options.AzLoginOptions.ClientID != "" + if err := getAKSCredentials( + resourceGroupName, + clusterName, + subscriptionID, + contextName, + runKubeloginConvert, + ); err != nil { + return fmt.Errorf("Failed to get AKS credentials: %w", err) } return nil diff --git a/pkg/deploy/deploy.go b/pkg/deploy/deploy.go index d781d0a..388f7b6 100644 --- a/pkg/deploy/deploy.go +++ b/pkg/deploy/deploy.go @@ -72,7 +72,7 @@ var Command *cli.Command = &cli.Command{ Usage: "The runtime cloud provider to use", Value: "aks", Action: func(c *cli.Context, runtimeCloudProvider string) error { - allowedRuntimeCloudProviders := []string{"aks", "gke"} + allowedRuntimeCloudProviders := []string{"aks", "gke", "iss"} if !slices.Contains(allowedRuntimeCloudProviders, strings.ToLower(runtimeCloudProvider)) { return cli.Exit( fmt.Sprintf( @@ -101,18 +101,6 @@ var Command *cli.Command = &cli.Command{ Aliases: []string{"n"}, Usage: "The repository name to use", }, - &cli.BoolFlag{ - Name: "skip-authentication", - Aliases: []string{"A"}, - Usage: "Skips authentication against the runtime cloud provider", - EnvVars: []string{"3LV_SKIP_AUTHENTICATION"}, - }, - &cli.BoolFlag{ - Name: "skip-getting-credentials", - Aliases: []string{"G"}, - Usage: "Skips getting credentials from the cloud provider for the Kubernetes cluster", - EnvVars: []string{"3LV_SKIP_GETTING_CREDENTIALS"}, - }, &cli.BoolFlag{ Name: "dry-run", Aliases: []string{"D"}, @@ -172,12 +160,6 @@ var Command *cli.Command = &cli.Command{ Hidden: true, EnvVars: []string{"3LV_GKE_CLUSTER_LOCATION"}, }, - &cli.BoolFlag{ - Name: "gke-use-internal-ip", - Usage: "Use the internal IP when connecting to the GKE cluster", - Hidden: true, - EnvVars: []string{"3LV_GKE_USE_INTERNAL_IP"}, - }, &cli.BoolFlag{ Name: "add-deployment-annotation", Usage: "Add a deployment annotation to Grafana. Requires --grafana-url and --grafana-api-key to be set.", @@ -238,8 +220,6 @@ func Deploy(c *cli.Context) error { environment := strings.ToLower(c.String("environment")) workloadType := strings.ToLower(c.String("workload-type")) runtimeCloudProvider := strings.ToLower(c.String("runtime-cloud-provider")) - skipAuthentication := c.Bool("skip-authentication") - skipGettingCredentials := c.Bool("skip-getting-credentials") dryRun := c.Bool("dry-run") runID := c.String("run-id") @@ -272,8 +252,6 @@ func Deploy(c *cli.Context) error { if err := setupAKS( azureTenantID, environment, - skipAuthentication, - skipGettingCredentials, setupOptions, ); err != nil { return cli.Exit(err, 1) @@ -284,16 +262,18 @@ func Deploy(c *cli.Context) error { ProjectID: c.String("gke-project-id"), ClusterName: c.String("gke-cluster-name"), ClusterLocation: c.String("gke-cluster-location"), - UseInternalIP: c.Bool("gke-use-internal-ip"), } if err := setupGKE( environment, - skipAuthentication, - skipGettingCredentials, authOptions, ); err != nil { return cli.Exit(err, 1) } + } else if runtimeCloudProvider == "iss" { + // do nothing + } else { + // This should never happen, as the runtimeCloudProvider flag is validated in the cli.Action function. + return cli.Exit(fmt.Errorf("Invalid runtime cloud provider: %s", runtimeCloudProvider), 1) } helmRepoAddOutput := helmRepoAddCommand(nil) @@ -306,6 +286,7 @@ func Deploy(c *cli.Context) error { return cli.Exit(fmt.Errorf("Failed to update Helm repository: %w", helmRepoUpdateOutput.Error), 1) } + useISSChart := runtimeCloudProvider == "iss" helmDeployOutput := helmDeployCommand( applicationName, systemName, @@ -316,6 +297,7 @@ func Deploy(c *cli.Context) error { repositoryName, commitHash, dryRun, + useISSChart, nil, ) if command.IsError(helmDeployOutput) && !dryRun { diff --git a/pkg/deploy/gke.go b/pkg/deploy/gke.go index b6b0e01..f29e4fb 100644 --- a/pkg/deploy/gke.go +++ b/pkg/deploy/gke.go @@ -13,36 +13,29 @@ type SetupGKEOptions struct { ProjectID string ClusterName string ClusterLocation string - UseInternalIP bool } func setupGKE( environment string, - skipAuthentication bool, - skipGettingCredentials bool, options *SetupGKEOptions, ) error { - if !skipAuthentication { - err := auth.AuthenticateGoogle() - if err != nil { - return err - } + err := auth.AuthenticateGoogle() + if err != nil { + return err } - if !skipGettingCredentials { - gcloudGetCredentialsOutput := gcloudGetCredentialsCommand( - environment, - &GcloudGetCredentialsCommandOptions{ - ProjectID: options.ProjectID, - ClusterName: options.ClusterName, - ClusterLocation: options.ClusterLocation, - RunOptions: nil, - }, - ) - - if command.IsError(gcloudGetCredentialsOutput) { - return fmt.Errorf("Failed to get GKE credentials: %w", gcloudGetCredentialsOutput.Error) - } + gcloudGetCredentialsOutput := gcloudGetCredentialsCommand( + environment, + &GcloudGetCredentialsCommandOptions{ + ProjectID: options.ProjectID, + ClusterName: options.ClusterName, + ClusterLocation: options.ClusterLocation, + RunOptions: nil, + }, + ) + + if command.IsError(gcloudGetCredentialsOutput) { + return fmt.Errorf("Failed to get GKE credentials: %w", gcloudGetCredentialsOutput.Error) } return nil @@ -52,7 +45,6 @@ type GcloudGetCredentialsCommandOptions struct { ProjectID string ClusterName string ClusterLocation string - UseInternalIP bool RunOptions *command.RunOptions } @@ -101,10 +93,6 @@ func gcloudGetCredentialsCommand( gkeProjectID, ) - if options.UseInternalIP { - cmd.Args = append(cmd.Args, "--internal-ip") - } - return command.Run( *cmd, options.RunOptions, diff --git a/pkg/deploy/gke_test.go b/pkg/deploy/gke_test.go index b9c8d1b..565d6b6 100644 --- a/pkg/deploy/gke_test.go +++ b/pkg/deploy/gke_test.go @@ -50,7 +50,6 @@ func TestGcloudGetCredentialsCommand2(t *testing.T) { const clusterLocation = "europe-west1" const projectID = "my-cool-project" const environment = "this-will-not-be-used" - const useInternalIP = true expectedCommandString := strings.Join( []string{ @@ -63,7 +62,6 @@ func TestGcloudGetCredentialsCommand2(t *testing.T) { clusterLocation, "--project", projectID, - "--internal-ip", }, " ", ) @@ -74,7 +72,6 @@ func TestGcloudGetCredentialsCommand2(t *testing.T) { ClusterName: clusterName, ClusterLocation: clusterLocation, ProjectID: projectID, - UseInternalIP: useInternalIP, RunOptions: &command.RunOptions{DryRun: true}, }, ) @@ -91,7 +88,6 @@ func TestGcloudGetCredentialsCommand3(t *testing.T) { const clusterLocation = "europe-west1" const projectID = "my-cool-project" const environment = "this-will-not-be-used" - const useInternalIP = false expectedCommandString := strings.Join( []string{ @@ -114,7 +110,6 @@ func TestGcloudGetCredentialsCommand3(t *testing.T) { ClusterName: clusterName, ClusterLocation: clusterLocation, ProjectID: projectID, - UseInternalIP: useInternalIP, RunOptions: &command.RunOptions{DryRun: true}, }, ) diff --git a/pkg/deploy/helm.go b/pkg/deploy/helm.go index 536bf4a..063167d 100644 --- a/pkg/deploy/helm.go +++ b/pkg/deploy/helm.go @@ -59,6 +59,7 @@ func helmDeployCommand( repositoryName string, commitHash string, dryRun bool, + useISSChart bool, runOptions *command.RunOptions, ) command.Output { if workloadType != "deployment" && workloadType != "statefulset" { @@ -67,6 +68,20 @@ func helmDeployCommand( ) } + chartName, err := func() (string, error) { + if useISSChart { + if workloadType == "deployment" { + return "iss-" + workloadType, nil + } else { + return "", fmt.Errorf("%s is not supported with ISS chart", workloadType) + } + } + return "elvia-" + workloadType, nil + }() + if err != nil { + return command.Error(err) + } + cmd := exec.Command( "helm", "upgrade", @@ -77,7 +92,7 @@ func helmDeployCommand( "-f", helmValuesFile, applicationName, - chartsNamespace+"/elvia-"+workloadType, + chartsNamespace+"/"+chartName, "--set-string", "environment="+environment, "--set-string", diff --git a/pkg/deploy/helm_test.go b/pkg/deploy/helm_test.go index 7621f17..a9c5a8d 100644 --- a/pkg/deploy/helm_test.go +++ b/pkg/deploy/helm_test.go @@ -102,6 +102,7 @@ func TestHelmDeployCommand1(t *testing.T) { repositoryName, commitHash, false, + false, &command.RunOptions{DryRun: true}, ) @@ -156,6 +157,7 @@ func TestHelmDeployCommand2(t *testing.T) { repositoryName, commitHash, false, + false, &command.RunOptions{DryRun: true}, ) @@ -186,6 +188,91 @@ func TestHelmDeployCommand3(t *testing.T) { repositoryName, commitHash, false, + false, + &command.RunOptions{DryRun: true}, + ) + + if !command.IsError(commandOutput) { + t.Errorf("Expected error, got %s", commandOutput) + } +} + +func TestHelmDeployCommand4(t *testing.T) { + const systemName = "core" + const helmValuesFile = ".github/deploy/values.yml" + const applicationName = "demo-api" + const environment = "prod" + const workloadType = "deployment" + const imageTag = "v420" + const repositoryName = "iss-demo-api" + const commitHash = "abcdef" + + expectedCommandString := strings.Join( + []string{ + "helm", + "upgrade", + "--debug", + "--install", + "-n", + systemName, + "-f", + helmValuesFile, + applicationName, + "elvia-charts/iss-" + workloadType, + "--set-string", + "environment=" + environment, + "--set-string", + "image.tag=" + imageTag, + "--set-string", + "labels.repositoryName=" + repositoryName, + "--set-string", + "labels.commitHash=\"" + commitHash + "\"", + }, + " ", + ) + + actualCommand := helmDeployCommand( + applicationName, + systemName, + helmValuesFile, + environment, + workloadType, + imageTag, + repositoryName, + commitHash, + false, + true, + &command.RunOptions{DryRun: true}, + ) + + command.ExpectedCommandStringEqualsActualCommand( + t, + expectedCommandString, + actualCommand, + ) +} + +func TestHelmDeployCommand5(t *testing.T) { + const systemName = "core" + const helmValuesFile = ".github/deploy/values.yml" + const applicationName = "demo-api" + const environment = "prod" + const workloadType = "statefulset" + const imageTag = "v420" + const repositoryName = "iss-demo-api" + const commitHash = "abcdef" + + commandOutput := helmDeployCommand( + applicationName, + systemName, + helmValuesFile, + environment, + workloadType, + imageTag, + repositoryName, + commitHash, + false, + true, &command.RunOptions{DryRun: true}, )