From 2bcabc63d9566d7e8974f7fd494e3be613d4581a Mon Sep 17 00:00:00 2001 From: Aleem Haji Date: Fri, 2 Oct 2020 21:05:58 -0400 Subject: [PATCH] Implement resource tagging to deploy groups of resources easily. (#30) * Pre-testing implementation of tagged resources. * Fix incorrect command attaching tags flags. * Clean up * Fix incorrectly named flag * Fix indenting * drop outdated comment --- cmd/hope/deploy.go | 35 ++++++++++++++++++++++++++++++++--- cmd/hope/root.go | 1 + cmd/hope/utils.go | 1 + hope.yaml | 12 ++++++++++-- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/cmd/hope/deploy.go b/cmd/hope/deploy.go index 4627924..91426af 100644 --- a/cmd/hope/deploy.go +++ b/cmd/hope/deploy.go @@ -19,15 +19,26 @@ import ( "github.com/Eagerod/hope/pkg/kubeutil" ) +var deployCmdTagSlice *[]string + +func initDeployCmdFlags() { + deployCmdTagSlice = deployCmd.Flags().StringArrayP("tag", "t", []string{}, "deploy resources with this tag") +} + var deployCmd = &cobra.Command{ Use: "deploy", - Short: "Deploy a Kubernetes yaml file", + Short: "Deploy Kubernetes resources defined in the hope file", RunE: func(cmd *cobra.Command, args []string) error { resources, err := getResources() if err != nil { return err } + // TODO: Re-evaluate; maybe just deploy everything in order defined. + if len(args) != 0 && len(*deployCmdTagSlice) != 0 { + return errors.New("Cannot deploy tags and named resources together.") + } + masters := viper.GetStringSlice("masters") kubectl, err := getKubectlFromAnyMaster(log.WithFields(log.Fields{}), masters) if err != nil { @@ -39,8 +50,26 @@ var deployCmd = &cobra.Command{ resourcesToDeploy := []Resource{} if len(args) == 0 { - log.Debug("Received no arguments for deployment. Deploying all resources.") - resourcesToDeploy = *resources + if len(*deployCmdTagSlice) != 0 { + tagMap := map[string]bool{} + for _, tag := range *deployCmdTagSlice { + tagMap[tag] = true + } + + for _, resource := range *resources { + for _, tag := range resource.Tags { + if _, ok := tagMap[tag]; ok { + resourcesToDeploy = append(resourcesToDeploy, resource) + continue + } + } + } + + log.Debug("Deploying these resources: \n\t", strings.Join(args, "\n\t"), "\nFrom provided tags.") + } else { + log.Debug("Received no arguments for deployment. Deploying all resources.") + resourcesToDeploy = *resources + } } else { log.Debug("Deploying these resources: \n\t", strings.Join(args, "\n\t"), "\nIn the order given.") diff --git a/cmd/hope/root.go b/cmd/hope/root.go index 1a44d4f..c86657c 100644 --- a/cmd/hope/root.go +++ b/cmd/hope/root.go @@ -50,6 +50,7 @@ func Execute() { rootCmd.AddCommand(sshCmd) rootCmd.AddCommand(tokenCmd) + initDeployCmdFlags() initHostnameCmdFlags() initKubeconfigCmdFlags() initResetCmd() diff --git a/cmd/hope/utils.go b/cmd/hope/utils.go index 65ea18f..3639169 100644 --- a/cmd/hope/utils.go +++ b/cmd/hope/utils.go @@ -44,6 +44,7 @@ type Resource struct { Build BuildSpec Job string Exec ExecSpec + Tags []string } // TODO: Allow jobs to define max retry parameters, or accept them on the diff --git a/hope.yaml b/hope.yaml index e744500..a9f96e5 100644 --- a/hope.yaml +++ b/hope.yaml @@ -13,10 +13,14 @@ resources: # It will always be preferred that urls appearing here are to stable yaml # files available on the Internet, rather than anything loaded from the # local machine. - # Local paths can be used for testing, but ultimately, whatever ends up being - # deployed should be done so using GitHub tags/releases. + # Local paths can be used for testing, but ultimately, whatever ends up + # being deployed should be done so using GitHub tags/releases. + # Every resource can provide a set of tags that will allow for the + # deployment of multiple resources without naming every resource + # explicitly. - name: calico file: https://docs.projectcalico.org/manifests/calico.yaml + tags: [network] # Inline definitions are also supported. # These values have to be provided as yaml strings under the `inline` key. # Values passed in through `inline` will be fed through `envsubst` before @@ -52,6 +56,7 @@ resources: namespace: metallb-system parameters: - METALLB_SYSTEM_MEMBERLIST_SECRET_KEY + tags: [network] # Build and push a docker image to the registry. # Doesn't include a kubectl command at all, so that can be done in a step # after a step like this appears. @@ -64,6 +69,7 @@ resources: build: path: some-dir-with-dockerfile tag: registry.internal.aleemhaji.com/example-repo:latest + tags: [app1] # When a spec comes with an initialization procedure, a job type can be used. # These will wait until the job with the specified name is completed. # If the job fails, the deployment stops so that other resources that may @@ -73,6 +79,7 @@ resources: # set to be deleted by any mechanism. - name: wait-for-some-kind-of-job job: init-the-database + tags: [database] # If something needs to be executed against pods of an existing set of pods, # the exec resource will run a script against a running instance. # A timeout can optionally be provided to wait for pods to start. @@ -84,6 +91,7 @@ resources: - mysql - -e - select 1; + tags: [database] # Jobs contains a collection of specifications of templated jobs that can be # run on demand in the cluster. # These jobs shouldn't be associated to the deployment of any particular