From 3ee26bf3cbecbfdecd033130d073b0bf8a2f963b Mon Sep 17 00:00:00 2001 From: Simon Emms Date: Tue, 17 Sep 2024 09:07:18 +0000 Subject: [PATCH] feat(azure): add azure beta command --- cmd/azure/command.go | 142 +++++++++++++++++++++++++++++++ cmd/azure/create.go | 145 ++++++++++++++++++++++++++++++++ cmd/beta.go | 2 + go.mod | 19 +++-- go.sum | 39 ++++----- internal/progress/message.go | 2 + internal/types/flags.go | 1 + internal/utilities/flags.go | 9 ++ internal/utilities/utilities.go | 11 +++ 9 files changed, 342 insertions(+), 28 deletions(-) create mode 100644 cmd/azure/command.go create mode 100644 cmd/azure/create.go diff --git a/cmd/azure/command.go b/cmd/azure/command.go new file mode 100644 index 00000000..fe1bc953 --- /dev/null +++ b/cmd/azure/command.go @@ -0,0 +1,142 @@ +/* +Copyright (C) 2021-2024, Kubefirst + +This program is licensed under MIT. +See the LICENSE file for more details. +*/ + +package azure + +import ( + "fmt" + + "github.com/konstructio/kubefirst-api/pkg/constants" + "github.com/konstructio/kubefirst/internal/common" + "github.com/konstructio/kubefirst/internal/progress" + "github.com/spf13/cobra" +) + +var ( + // Create + alertsEmailFlag string + ciFlag bool + cloudRegionFlag string + clusterNameFlag string + clusterTypeFlag string + dnsProviderFlag string + dnsAzureResourceGroup string + domainNameFlag string + subdomainNameFlag string + githubOrgFlag string + gitlabGroupFlag string + gitProviderFlag string + gitProtocolFlag string + gitopsTemplateURLFlag string + gitopsTemplateBranchFlag string + useTelemetryFlag bool + forceDestroyFlag bool + nodeTypeFlag string + nodeCountFlag string + installCatalogApps string + installKubefirstProFlag bool + + // RootCredentials + copyArgoCDPasswordToClipboardFlag bool + copyKbotPasswordToClipboardFlag bool + copyVaultPasswordToClipboardFlag bool + + // Supported providers + supportedDNSProviders = []string{"azure", "cloudflare"} + supportedGitProviders = []string{"github", "gitlab"} + + // Supported git providers + supportedGitProtocolOverride = []string{"https", "ssh"} +) + +func NewCommand() *cobra.Command { + azureCmd := &cobra.Command{ + Use: "azure", + Short: "kubefirst Azure installation", + Long: "kubefirst azure", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("To learn more about azure in kubefirst, run:") + fmt.Println(" kubefirst beta azure --help") + + if progress.Progress != nil { + progress.Progress.Quit() + } + }, + } + + // on error, doesnt show helper/usage + azureCmd.SilenceUsage = true + + // wire up new commands + azureCmd.AddCommand(Create(), Destroy(), RootCredentials()) + + return azureCmd +} + +func Create() *cobra.Command { + createCmd := &cobra.Command{ + Use: "create", + Short: "create the kubefirst platform running on Azure kubernetes", + TraverseChildren: true, + RunE: createAzure, + } + + azureDefaults := constants.GetCloudDefaults().Azure + + // todo review defaults and update descriptions + createCmd.Flags().StringVar(&alertsEmailFlag, "alerts-email", "", "email address for let's encrypt certificate notifications (required)") + createCmd.MarkFlagRequired("alerts-email") + createCmd.Flags().BoolVar(&ciFlag, "ci", false, "if running kubefirst in ci, set this flag to disable interactive features") + createCmd.Flags().StringVar(&cloudRegionFlag, "cloud-region", "eastus", "the GCP region to provision infrastructure in") + createCmd.Flags().StringVar(&clusterNameFlag, "cluster-name", "kubefirst", "the name of the cluster to create") + createCmd.Flags().StringVar(&clusterTypeFlag, "cluster-type", "mgmt", "the type of cluster to create (i.e. mgmt|workload)") + createCmd.Flags().StringVar(&nodeCountFlag, "node-count", azureDefaults.NodeCount, "the node count for the cluster") + createCmd.Flags().StringVar(&nodeTypeFlag, "node-type", azureDefaults.InstanceSize, "the instance size of the cluster to create") + createCmd.Flags().StringVar(&dnsProviderFlag, "dns-provider", "azure", fmt.Sprintf("the dns provider - one of: %s", supportedDNSProviders)) + createCmd.Flags().StringVar(&dnsAzureResourceGroup, "dns-azure-resource-group", "", "the resource group where the Azure DNS Zone is hosted") + createCmd.Flags().StringVar(&subdomainNameFlag, "subdomain", "", "the subdomain to use for DNS records (Cloudflare)") + createCmd.Flags().StringVar(&domainNameFlag, "domain-name", "", "the Azure/Cloudflare DNS hosted zone name to use for DNS records (i.e. your-domain.com|subdomain.your-domain.com) (required)") + createCmd.MarkFlagRequired("domain-name") + createCmd.Flags().StringVar(&gitProviderFlag, "git-provider", "github", fmt.Sprintf("the git provider - one of: %s", supportedGitProviders)) + createCmd.Flags().StringVar(&gitProtocolFlag, "git-protocol", "ssh", fmt.Sprintf("the git protocol - one of: %s", supportedGitProtocolOverride)) + createCmd.Flags().StringVar(&githubOrgFlag, "github-org", "", "the GitHub organization for the new gitops and metaphor repositories - required if using github") + createCmd.Flags().StringVar(&gitlabGroupFlag, "gitlab-group", "", "the GitLab group for the new gitops and metaphor projects - required if using gitlab") + createCmd.Flags().StringVar(&gitopsTemplateBranchFlag, "gitops-template-branch", "", "the branch to clone for the gitops-template repository") + createCmd.Flags().StringVar(&gitopsTemplateURLFlag, "gitops-template-url", "https://github.com/konstructio/gitops-template.git", "the fully qualified url to the gitops-template repository to clone") + createCmd.Flags().StringVar(&installCatalogApps, "install-catalog-apps", "", "comma separated values to install after provision") + createCmd.Flags().BoolVar(&useTelemetryFlag, "use-telemetry", true, "whether to emit telemetry") + createCmd.Flags().BoolVar(&forceDestroyFlag, "force-destroy", false, "allows force destruction on objects (helpful for test environments, defaults to false)") + createCmd.Flags().BoolVar(&installKubefirstProFlag, "install-kubefirst-pro", true, "whether or not to install kubefirst pro") + + return createCmd +} + +func Destroy() *cobra.Command { + destroyCmd := &cobra.Command{ + Use: "destroy", + Short: "destroy the kubefirst platform", + Long: "destroy the kubefirst platform running in Azure and remove all resources", + RunE: common.Destroy, + } + + return destroyCmd +} + +func RootCredentials() *cobra.Command { + authCmd := &cobra.Command{ + Use: "root-credentials", + Short: "retrieve root authentication information for platform components", + Long: "retrieve root authentication information for platform components", + RunE: common.GetRootCredentials, + } + + authCmd.Flags().BoolVar(©ArgoCDPasswordToClipboardFlag, "argocd", false, "copy the argocd password to the clipboard (optional)") + authCmd.Flags().BoolVar(©KbotPasswordToClipboardFlag, "kbot", false, "copy the kbot password to the clipboard (optional)") + authCmd.Flags().BoolVar(©VaultPasswordToClipboardFlag, "vault", false, "copy the vault password to the clipboard (optional)") + + return authCmd +} diff --git a/cmd/azure/create.go b/cmd/azure/create.go new file mode 100644 index 00000000..0928646b --- /dev/null +++ b/cmd/azure/create.go @@ -0,0 +1,145 @@ +/* +Copyright (C) 2021-2024, Kubefirst + +This program is licensed under MIT. +See the LICENSE file for more details. +*/ +package azure + +import ( + "fmt" + "os" + "strings" + + internalssh "github.com/konstructio/kubefirst-api/pkg/ssh" + utils "github.com/konstructio/kubefirst-api/pkg/utils" + "github.com/konstructio/kubefirst/internal/catalog" + "github.com/konstructio/kubefirst/internal/cluster" + "github.com/konstructio/kubefirst/internal/gitShim" + "github.com/konstructio/kubefirst/internal/launch" + "github.com/konstructio/kubefirst/internal/progress" + "github.com/konstructio/kubefirst/internal/provision" + "github.com/konstructio/kubefirst/internal/utilities" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +// Environment variables required for authentication. This should be a +// service principal - the Terraform provider docs detail how to create +// one +// @link https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret.html +var envvarSecrets = []string{ + "ARM_CLIENT_ID", + "ARM_CLIENT_SECRET", + "ARM_TENANT_ID", + "ARM_SUBSCRIPTION_ID", +} + +func createAzure(cmd *cobra.Command, args []string) error { + cliFlags, err := utilities.GetFlags(cmd, "azure") + if err != nil { + progress.Error(err.Error()) + return nil + } + + progress.DisplayLogHints(20) + + isValid, catalogApps, err := catalog.ValidateCatalogApps(cliFlags.InstallCatalogApps) + if !isValid { + return err + } + + err = ValidateProvidedFlags(cliFlags.GitProvider, cliFlags.DNSProvider, cliFlags.DNSAzureRG) + if err != nil { + progress.Error(err.Error()) + return nil + } + + // If cluster setup is complete, return + clusterSetupComplete := viper.GetBool("kubefirst-checks.cluster-install-complete") + if clusterSetupComplete { + err = fmt.Errorf("this cluster install process has already completed successfully") + progress.Error(err.Error()) + return nil + } + + utilities.CreateK1ClusterDirectory(clusterNameFlag) + + gitAuth, err := gitShim.ValidateGitCredentials(cliFlags.GitProvider, cliFlags.GithubOrg, cliFlags.GitlabGroup) + if err != nil { + progress.Error(err.Error()) + return nil + } + + executionControl := viper.GetBool(fmt.Sprintf("kubefirst-checks.%s-credentials", cliFlags.GitProvider)) + if !executionControl { + newRepositoryNames := []string{"gitops", "metaphor"} + newTeamNames := []string{"admins", "developers"} + + initGitParameters := gitShim.GitInitParameters{ + GitProvider: gitProviderFlag, + GitToken: gitAuth.Token, + GitOwner: gitAuth.Owner, + Repositories: newRepositoryNames, + Teams: newTeamNames, + } + err = gitShim.InitializeGitProvider(&initGitParameters) + if err != nil { + progress.Error(err.Error()) + return nil + } + } + + viper.Set(fmt.Sprintf("kubefirst-checks.%s-credentials", cliFlags.GitProvider), true) + viper.WriteConfig() + + k3dClusterCreationComplete := viper.GetBool("launch.deployed") + isK1Debug := strings.ToLower(os.Getenv("K1_LOCAL_DEBUG")) == "true" + + if !k3dClusterCreationComplete && !isK1Debug { + launch.Up(nil, true, cliFlags.UseTelemetry) + } + + err = utils.IsAppAvailable(fmt.Sprintf("%s/api/proxyHealth", cluster.GetConsoleIngressURL()), "kubefirst api") + if err != nil { + progress.Error("unable to start kubefirst api") + } + + provision.CreateMgmtCluster(gitAuth, cliFlags, catalogApps) + + return nil +} + +func ValidateProvidedFlags(gitProvider, dnsProvider, dnsAzureResourceGroup string) error { + progress.AddStep("Validate provided flags") + + for _, env := range envvarSecrets { + if os.Getenv(env) == "" { + return fmt.Errorf("your %s is not set - please set and re-run your last command", env) + } + } + + switch gitProvider { + case "github": + key, err := internalssh.GetHostKey("github.com") + if err != nil { + return fmt.Errorf("known_hosts file does not exist - please run `ssh-keyscan github.com >> ~/.ssh/known_hosts` to remedy") + } else { + log.Info().Msgf("%s %s\n", "github.com", key.Type()) + } + case "gitlab": + key, err := internalssh.GetHostKey("gitlab.com") + if err != nil { + return fmt.Errorf("known_hosts file does not exist - please run `ssh-keyscan gitlab.com >> ~/.ssh/known_hosts` to remedy") + } else { + log.Info().Msgf("%s %s\n", "gitlab.com", key.Type()) + } + } + + if dnsProvider == "azure" && dnsAzureResourceGroup == "" { + return fmt.Errorf("the resource group for the azure dns zone is required when using azure dns") + } + + return nil +} diff --git a/cmd/beta.go b/cmd/beta.go index 9afd9155..e5154206 100644 --- a/cmd/beta.go +++ b/cmd/beta.go @@ -10,6 +10,7 @@ import ( "fmt" "github.com/konstructio/kubefirst/cmd/akamai" + "github.com/konstructio/kubefirst/cmd/azure" "github.com/konstructio/kubefirst/cmd/google" "github.com/konstructio/kubefirst/cmd/k3s" "github.com/konstructio/kubefirst/cmd/vultr" @@ -36,6 +37,7 @@ func init() { cobra.OnInitialize() betaCmd.AddCommand( akamai.NewCommand(), + azure.NewCommand(), k3s.NewCommand(), google.NewCommand(), vultr.NewCommand(), diff --git a/go.mod b/go.mod index 9f304ede..3fc7570f 100644 --- a/go.mod +++ b/go.mod @@ -113,7 +113,7 @@ require ( github.com/google/go-github/v45 v45.2.0 // indirect github.com/google/s2a-go v0.1.4 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/gorilla/css v1.0.0 // indirect @@ -153,6 +153,7 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/xid v1.4.0 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/sahilm/fuzzy v0.1.0 // indirect @@ -171,10 +172,10 @@ require ( github.com/yuin/goldmark-emoji v1.0.1 // indirect go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.126.0 // indirect google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect @@ -266,11 +267,11 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/net v0.22.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.30.0 // indirect diff --git a/go.sum b/go.sum index 51fa6148..b67ecc1a 100644 --- a/go.sum +++ b/go.sum @@ -579,8 +579,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -1018,8 +1019,8 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -1252,8 +1253,8 @@ golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1309,8 +1310,8 @@ golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1379,8 +1380,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1410,8 +1411,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1518,8 +1519,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1530,8 +1531,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1549,8 +1550,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1635,8 +1636,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/progress/message.go b/internal/progress/message.go index 5971dfb2..c6313abb 100644 --- a/internal/progress/message.go +++ b/internal/progress/message.go @@ -88,6 +88,8 @@ func DisplaySuccessMessage(cluster types.Cluster) successMsg { switch cluster.CloudProvider { case "aws": cloudCliKubeconfig = fmt.Sprintf("aws eks update-kubeconfig --name %q --region %q", cluster.ClusterName, cluster.CloudRegion) + case "azure": + cloudCliKubeconfig = fmt.Sprintf("az aks get-credentials --resource-group %q --name %q", cluster.ClusterName, cluster.ClusterName) case "civo": cloudCliKubeconfig = fmt.Sprintf("civo kubernetes config %q --save", cluster.ClusterName) case "digitalocean": diff --git a/internal/types/flags.go b/internal/types/flags.go index 84c3777d..392d221a 100644 --- a/internal/types/flags.go +++ b/internal/types/flags.go @@ -14,6 +14,7 @@ type CliFlags struct { ClusterName string ClusterType string DNSProvider string + DNSAzureRG string DomainName string SubDomainName string GitProvider string diff --git a/internal/utilities/flags.go b/internal/utilities/flags.go index 12306966..c6ac1dd5 100644 --- a/internal/utilities/flags.go +++ b/internal/utilities/flags.go @@ -133,6 +133,15 @@ func GetFlags(cmd *cobra.Command, cloudProvider string) (types.CliFlags, error) cliFlags.ECR = ecrFlag } + if cloudProvider == "azure" { + dnsAzureResourceGroup, err := cmd.Flags().GetString("dns-azure-resource-group") + if err != nil { + progress.Error(err.Error()) + return cliFlags, fmt.Errorf("failed to get dns-azure-resource-group flag: %w", err) + } + cliFlags.DNSAzureRG = dnsAzureResourceGroup + } + if cloudProvider == "google" { googleProject, err := cmd.Flags().GetString("google-project") if err != nil { diff --git a/internal/utilities/utilities.go b/internal/utilities/utilities.go index 7a56a45b..ddf21297 100644 --- a/internal/utilities/utilities.go +++ b/internal/utilities/utilities.go @@ -107,6 +107,11 @@ func CreateClusterRecordFromRaw( cl.AWSAuth.AccessKeyID = viper.GetString("kubefirst.state-store-creds.access-key-id") cl.AWSAuth.SecretAccessKey = viper.GetString("kubefirst.state-store-creds.secret-access-key-id") cl.AWSAuth.SessionToken = viper.GetString("kubefirst.state-store-creds.token") + case "azure": + cl.AzureAuth.ClientID = os.Getenv("ARM_CLIENT_ID") + cl.AzureAuth.ClientSecret = os.Getenv("ARM_CLIENT_SECRET") + cl.AzureAuth.TenantID = os.Getenv("ARM_TENANT_ID") + cl.AzureAuth.SubscriptionID = os.Getenv("ARM_SUBSCRIPTION_ID") case "digitalocean": cl.DigitaloceanAuth.Token = os.Getenv("DO_TOKEN") cl.DigitaloceanAuth.SpacesKey = os.Getenv("DO_SPACES_KEY") @@ -173,6 +178,7 @@ func CreateClusterDefinitionRecordFromRaw(gitAuth apiTypes.GitAuth, cliFlags typ CloudflareAuth: apiTypes.CloudflareAuth{ APIToken: os.Getenv("CF_API_TOKEN"), }, + AzureDNSZoneResourceGroup: cliFlags.DNSAzureRG, } if cl.GitopsTemplateBranch == "" { @@ -191,6 +197,11 @@ func CreateClusterDefinitionRecordFromRaw(gitAuth apiTypes.GitAuth, cliFlags typ cl.AWSAuth.SecretAccessKey = viper.GetString("kubefirst.state-store-creds.secret-access-key-id") cl.AWSAuth.SessionToken = viper.GetString("kubefirst.state-store-creds.token") cl.ECR = cliFlags.ECR + case "azure": + cl.AzureAuth.ClientID = os.Getenv("ARM_CLIENT_ID") + cl.AzureAuth.ClientSecret = os.Getenv("ARM_CLIENT_SECRET") + cl.AzureAuth.TenantID = os.Getenv("ARM_TENANT_ID") + cl.AzureAuth.SubscriptionID = os.Getenv("ARM_SUBSCRIPTION_ID") case "civo": cl.CivoAuth.Token = os.Getenv("CIVO_TOKEN") case "digitalocean":