From 02ec979b6f70704bf010fad6aa5773869048ab9d Mon Sep 17 00:00:00 2001 From: ntishchauhan0022 Date: Mon, 12 Jun 2023 14:43:10 +0530 Subject: [PATCH 1/2] adding service account support Signed-off-by: ntishchauhan0022 --- cmd/deploy.go | 36 ++++++++++++--------- docs/reference/func_config_git_set.md | 2 +- docs/reference/func_deploy.md | 45 ++++++++++++++------------- pkg/functions/function.go | 3 ++ pkg/k8s/serviceaccount.go | 19 +++++++++++ pkg/knative/deployer.go | 19 ++++++++--- schema/func_yaml-schema.json | 4 +++ 7 files changed, 85 insertions(+), 43 deletions(-) create mode 100644 pkg/k8s/serviceaccount.go diff --git a/cmd/deploy.go b/cmd/deploy.go index d9e0e4a1d..201859dc0 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -32,8 +32,8 @@ SYNOPSIS {{rootCmdUse}} deploy [-R|--remote] [-r|--registry] [-i|--image] [-n|--namespace] [-e|--env] [-g|--git-url] [-t|--git-branch] [-d|--git-dir] [-b|--build] [--builder] [--builder-image] [-p|--push] - [--domain] [--platform] [--build-timestamp] - [-c|--confirm] [-v|--verbose] + [--domain] [--platform] [--build-timestamp] [--pvc-size] + [--service-account] [-c|--confirm] [-v|--verbose] DESCRIPTION @@ -125,7 +125,7 @@ EXAMPLES `, SuggestFor: []string{"delpoy", "deplyo"}, - PreRunE: bindEnv("build", "build-timestamp", "builder", "builder-image", "confirm", "domain", "env", "git-branch", "git-dir", "git-url", "image", "namespace", "path", "platform", "push", "pvc-size", "registry", "remote", "verbose"), + PreRunE: bindEnv("build", "build-timestamp", "builder", "builder-image", "confirm", "domain", "env", "git-branch", "git-dir", "git-url", "image", "namespace", "path", "platform", "push", "pvc-size","service-account", "registry", "remote", "verbose"), RunE: func(cmd *cobra.Command, args []string) error { return runDeploy(cmd, newClient) }, @@ -180,7 +180,8 @@ EXAMPLES "Trigger a remote deployment. Default is to deploy and build from the local system ($FUNC_REMOTE)") cmd.Flags().String("pvc-size", f.Build.PVCSize, "When triggering a remote deployment, set a custom volume size to allocate for the build operation ($FUNC_PVC_SIZE)") - + cmd.Flags().String("service-account", f.Deploy.ServiceAccount, + "Service account to be used in the deployed function ($FUNC_SERVICE_ACCOUNT)") // Static Flags: // Options which have static defaults only (not globally configurable nor // persisted with the function) @@ -431,6 +432,9 @@ type deployConfig struct { // (~/.kube/config) in the case of Kubernetes. Namespace string + //Service account to be used in deployed function + ServiceAccount string + // Remote indicates the deployment (and possibly build) process are to // be triggered in a remote environment rather than run locally. Remote bool @@ -447,17 +451,18 @@ type deployConfig struct { // environment variables; in that precedence. func newDeployConfig(cmd *cobra.Command) (c deployConfig) { c = deployConfig{ - buildConfig: newBuildConfig(), - Build: viper.GetString("build"), - Env: viper.GetStringSlice("env"), - Domain: viper.GetString("domain"), - GitBranch: viper.GetString("git-branch"), - GitDir: viper.GetString("git-dir"), - GitURL: viper.GetString("git-url"), - Namespace: viper.GetString("namespace"), - Remote: viper.GetBool("remote"), - PVCSize: viper.GetString("pvc-size"), - Timestamp: viper.GetBool("build-timestamp"), + buildConfig: newBuildConfig(), + Build: viper.GetString("build"), + Env: viper.GetStringSlice("env"), + Domain: viper.GetString("domain"), + GitBranch: viper.GetString("git-branch"), + GitDir: viper.GetString("git-dir"), + GitURL: viper.GetString("git-url"), + Namespace: viper.GetString("namespace"), + Remote: viper.GetBool("remote"), + PVCSize: viper.GetString("pvc-size"), + Timestamp: viper.GetBool("build-timestamp"), + ServiceAccount: viper.GetString("service-account"), } // NOTE: .Env should be viper.GetStringSlice, but this returns unparsed // results and appears to be an open issue since 2017: @@ -490,6 +495,7 @@ func (c deployConfig) Configure(f fn.Function) (fn.Function, error) { f.Build.Git.Revision = c.GitBranch // TODO: should match; perhaps "refSpec" f.Deploy.Namespace = c.Namespace f.Deploy.Remote = c.Remote + f.Deploy.ServiceAccount = c.ServiceAccount // PVCSize // If a specific value is requested, ensure it parses as a resource.Quantity diff --git a/docs/reference/func_config_git_set.md b/docs/reference/func_config_git_set.md index afaaca5e4..7e52b75c1 100644 --- a/docs/reference/func_config_git_set.md +++ b/docs/reference/func_config_git_set.md @@ -26,7 +26,7 @@ func config git set --gh-webhook-secret string GitHub Webhook Secret used for payload validation. If not specified, it will be generated automatically. -t, --git-branch string Git revision (branch) to be used when deploying via the Git repository ($FUNC_GIT_BRANCH) -d, --git-dir string Directory in the Git repository containing the function (default is the root) ($FUNC_GIT_DIR) - --git-provider string The type of the Git platform provider to setup webhook. This value is usually automatically generated from input URL, use this parameter to override this setting. Currently supported providers are "github". + --git-provider string The type of the Git platform provider to setup webhook. This value is usually automatically generated from input URL, use this parameter to override this setting. Currently supported providers are "github" and "gitlab". -g, --git-url string Repository url containing the function to build ($FUNC_GIT_URL) -h, --help help for set -i, --image string Full image name in the form [registry]/[namespace]/[name]:[tag]@[digest]. This option takes precedence over --registry. Specifying digest is optional, but if it is given, 'build' and 'push' phases are disabled. ($FUNC_IMAGE) diff --git a/docs/reference/func_deploy.md b/docs/reference/func_deploy.md index 895ab7386..61e985bae 100644 --- a/docs/reference/func_deploy.md +++ b/docs/reference/func_deploy.md @@ -12,8 +12,8 @@ SYNOPSIS func deploy [-R|--remote] [-r|--registry] [-i|--image] [-n|--namespace] [-e|--env] [-g|--git-url] [-t|--git-branch] [-d|--git-dir] [-b|--build] [--builder] [--builder-image] [-p|--push] - [--domain] [--platform] [--build-timestamp] - [-c|--confirm] [-v|--verbose] + [--domain] [--platform] [--build-timestamp] [--pvc-size] + [--service-account] [-c|--confirm] [-v|--verbose] DESCRIPTION @@ -112,26 +112,27 @@ func deploy ### Options ``` - --build string[="true"] Build the function. [auto|true|false]. ($FUNC_BUILD) (default "auto") - --build-timestamp Use the actual time as the created time for the docker image. This is only useful for buildpacks builder. - -b, --builder string Builder to use when creating the function's container. Currently supported builders are "pack" and "s2i". (default "pack") - --builder-image string Specify a custom builder image for use by the builder other than its default. ($FUNC_BUILDER_IMAGE) - -c, --confirm Prompt to confirm options interactively ($FUNC_CONFIRM) - --domain string Domain to use for the function's route. Cluster must be configured with domain matching for the given domain (ignored if unrecognized) ($FUNC_DOMAIN) - -e, --env stringArray Environment variable to set in the form NAME=VALUE. You may provide this flag multiple times for setting multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-). - -t, --git-branch string Git revision (branch) to be used when deploying via the Git repository ($FUNC_GIT_BRANCH) - -d, --git-dir string Directory in the Git repository containing the function (default is the root) ($FUNC_GIT_DIR) - -g, --git-url string Repository url containing the function to build ($FUNC_GIT_URL) - -h, --help help for deploy - -i, --image string Full image name in the form [registry]/[namespace]/[name]:[tag]@[digest]. This option takes precedence over --registry. Specifying digest is optional, but if it is given, 'build' and 'push' phases are disabled. ($FUNC_IMAGE) - -n, --namespace string Deploy into a specific namespace. Will use function's current namespace by default if already deployed, and the currently active namespace if it can be determined. ($FUNC_NAMESPACE) - -p, --path string Path to the function. Default is current directory ($FUNC_PATH) - --platform string Optionally specify a specific platform to build for (e.g. linux/amd64). ($FUNC_PLATFORM) - -u, --push Push the function image to registry before deploying. ($FUNC_PUSH) (default true) - --pvc-size string When triggering a remote deployment, set a custom volume size to allocate for the build operation ($FUNC_PVC_SIZE) - -r, --registry string Container registry + registry namespace. (ex 'ghcr.io/myuser'). The full image name is automatically determined using this along with function name. ($FUNC_REGISTRY) - -R, --remote Trigger a remote deployment. Default is to deploy and build from the local system ($FUNC_REMOTE) - -v, --verbose Print verbose logs ($FUNC_VERBOSE) + --build string[="true"] Build the function. [auto|true|false]. ($FUNC_BUILD) (default "auto") + --build-timestamp Use the actual time as the created time for the docker image. This is only useful for buildpacks builder. + -b, --builder string Builder to use when creating the function's container. Currently supported builders are "pack" and "s2i". (default "pack") + --builder-image string Specify a custom builder image for use by the builder other than its default. ($FUNC_BUILDER_IMAGE) + -c, --confirm Prompt to confirm options interactively ($FUNC_CONFIRM) + --domain string Domain to use for the function's route. Cluster must be configured with domain matching for the given domain (ignored if unrecognized) ($FUNC_DOMAIN) + -e, --env stringArray Environment variable to set in the form NAME=VALUE. You may provide this flag multiple times for setting multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-). + -t, --git-branch string Git revision (branch) to be used when deploying via the Git repository ($FUNC_GIT_BRANCH) + -d, --git-dir string Directory in the Git repository containing the function (default is the root) ($FUNC_GIT_DIR) + -g, --git-url string Repository url containing the function to build ($FUNC_GIT_URL) + -h, --help help for deploy + -i, --image string Full image name in the form [registry]/[namespace]/[name]:[tag]@[digest]. This option takes precedence over --registry. Specifying digest is optional, but if it is given, 'build' and 'push' phases are disabled. ($FUNC_IMAGE) + -n, --namespace string Deploy into a specific namespace. Will use function's current namespace by default if already deployed, and the currently active namespace if it can be determined. ($FUNC_NAMESPACE) + -p, --path string Path to the function. Default is current directory ($FUNC_PATH) + --platform string Optionally specify a specific platform to build for (e.g. linux/amd64). ($FUNC_PLATFORM) + -u, --push Push the function image to registry before deploying. ($FUNC_PUSH) (default true) + --pvc-size string When triggering a remote deployment, set a custom volume size to allocate for the build operation ($FUNC_PVC_SIZE) + -r, --registry string Container registry + registry namespace. (ex 'ghcr.io/myuser'). The full image name is automatically determined using this along with function name. ($FUNC_REGISTRY) + -R, --remote Trigger a remote deployment. Default is to deploy and build from the local system ($FUNC_REMOTE) + --service-account string Service account to be used in the deployed function ($FUNC_SERVICE_ACCOUNT) + -v, --verbose Print verbose logs ($FUNC_VERBOSE) ``` ### SEE ALSO diff --git a/pkg/functions/function.go b/pkg/functions/function.go index dfc8e3101..bf065e52c 100644 --- a/pkg/functions/function.go +++ b/pkg/functions/function.go @@ -130,6 +130,9 @@ type DeploySpec struct { // Namespace into which the function is deployed on supported platforms. Namespace string `yaml:"namespace,omitempty"` + //Service account to be used in the deployed function + ServiceAccount string `yaml:"serviceAccount,omitempty"` + // Remote indicates the deployment (and possibly build) process are to // be triggered in a remote environment rather than run locally. Remote bool `yaml:"remote,omitempty"` diff --git a/pkg/k8s/serviceaccount.go b/pkg/k8s/serviceaccount.go new file mode 100644 index 000000000..e1e344376 --- /dev/null +++ b/pkg/k8s/serviceaccount.go @@ -0,0 +1,19 @@ +package k8s + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func GetServiceAccount(ctx context.Context, referencedServiceAccount, namespace string) error { + k8sClient, err := NewKubernetesClientset() + if err != nil { + return err + } + _,err = k8sClient.CoreV1().ServiceAccounts(namespace).Get(ctx, referencedServiceAccount, metav1.GetOptions{}) + if err != nil { + return err + } + return nil +} diff --git a/pkg/knative/deployer.go b/pkg/knative/deployer.go index 9c1aafe18..f66fe074f 100644 --- a/pkg/knative/deployer.go +++ b/pkg/knative/deployer.go @@ -155,7 +155,7 @@ func (d *Deployer) Deploy(ctx context.Context, f fn.Function) (fn.DeploymentResu return fn.DeploymentResult{}, err } - err = checkResourcesArePresent(ctx, d.Namespace, &referencedSecrets, &referencedConfigMaps, &referencedPVCs) + err = checkResourcesArePresent(ctx, d.Namespace, &referencedSecrets, &referencedConfigMaps, &referencedPVCs, f.Deploy.ServiceAccount) if err != nil { err = fmt.Errorf("knative deployer failed to generate the Knative Service: %v", err) return fn.DeploymentResult{}, err @@ -252,7 +252,7 @@ func (d *Deployer) Deploy(ctx context.Context, f fn.Function) (fn.DeploymentResu return fn.DeploymentResult{}, err } - err = checkResourcesArePresent(ctx, d.Namespace, &referencedSecrets, &referencedConfigMaps, &referencedPVCs) + err = checkResourcesArePresent(ctx, d.Namespace, &referencedSecrets, &referencedConfigMaps, &referencedPVCs, f.Deploy.ServiceAccount) if err != nil { err = fmt.Errorf("knative deployer failed to update the Knative Service: %v", err) return fn.DeploymentResult{}, err @@ -370,7 +370,8 @@ func generateNewService(f fn.Function, decorator DeployDecorator) (*v1.Service, Containers: []corev1.Container{ container, }, - Volumes: newVolumes, + ServiceAccountName: f.Deploy.ServiceAccount, + Volumes: newVolumes, }, }, }, @@ -509,7 +510,7 @@ func updateService(f fn.Function, previousService *v1.Service, newEnv []corev1.E cp.EnvFrom = newEnvFrom cp.VolumeMounts = newVolumeMounts service.Spec.ConfigurationSpec.Template.Spec.Volumes = newVolumes - + service.Spec.ConfigurationSpec.Template.Spec.PodSpec.ServiceAccountName = f.Deploy.ServiceAccount return service, nil } } @@ -814,7 +815,7 @@ func processVolumes(volumes []fn.Volume, referencedSecrets, referencedConfigMaps // checkResourcesArePresent returns error if Secrets or ConfigMaps // referenced in input sets are not deployed on the cluster in the specified namespace -func checkResourcesArePresent(ctx context.Context, namespace string, referencedSecrets, referencedConfigMaps, referencedPVCs *sets.String) error { +func checkResourcesArePresent(ctx context.Context, namespace string, referencedSecrets, referencedConfigMaps, referencedPVCs *sets.String, referencedServiceAccount string) error { errMsg := "" for s := range *referencedSecrets { @@ -838,6 +839,14 @@ func checkResourcesArePresent(ctx context.Context, namespace string, referencedS } } + // check if referenced ServiceAccount is present in the namespace if it is not default + if referencedServiceAccount != "" && referencedServiceAccount != "default" { + err := k8s.GetServiceAccount(ctx, referencedServiceAccount, namespace) + if err != nil { + errMsg += fmt.Sprintf(" referenced ServiceAccount \"%s\" is not present in namespace \"%s\"\n", referencedServiceAccount, namespace) + } + } + if errMsg != "" { return fmt.Errorf("\n" + errMsg) } diff --git a/schema/func_yaml-schema.json b/schema/func_yaml-schema.json index 0a4713ac3..d81d98aa9 100644 --- a/schema/func_yaml-schema.json +++ b/schema/func_yaml-schema.json @@ -56,6 +56,10 @@ "type": "string", "description": "Namespace into which the function is deployed on supported platforms." }, + "serviceAccount": { + "type": "string", + "description": "Service account to be used in the deployed function" + }, "remote": { "type": "boolean", "description": "Remote indicates the deployment (and possibly build) process are to\nbe triggered in a remote environment rather than run locally." From 8046e073257e2b294783ca3f86c534416d79e007 Mon Sep 17 00:00:00 2001 From: ntishchauhan0022 Date: Thu, 15 Jun 2023 08:20:08 +0530 Subject: [PATCH 2/2] correcting formatting Signed-off-by: ntishchauhan0022 --- cmd/deploy.go | 2 +- pkg/k8s/serviceaccount.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/deploy.go b/cmd/deploy.go index 201859dc0..65d237197 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -125,7 +125,7 @@ EXAMPLES `, SuggestFor: []string{"delpoy", "deplyo"}, - PreRunE: bindEnv("build", "build-timestamp", "builder", "builder-image", "confirm", "domain", "env", "git-branch", "git-dir", "git-url", "image", "namespace", "path", "platform", "push", "pvc-size","service-account", "registry", "remote", "verbose"), + PreRunE: bindEnv("build", "build-timestamp", "builder", "builder-image", "confirm", "domain", "env", "git-branch", "git-dir", "git-url", "image", "namespace", "path", "platform", "push", "pvc-size", "service-account", "registry", "remote", "verbose"), RunE: func(cmd *cobra.Command, args []string) error { return runDeploy(cmd, newClient) }, diff --git a/pkg/k8s/serviceaccount.go b/pkg/k8s/serviceaccount.go index e1e344376..8180cae27 100644 --- a/pkg/k8s/serviceaccount.go +++ b/pkg/k8s/serviceaccount.go @@ -11,7 +11,7 @@ func GetServiceAccount(ctx context.Context, referencedServiceAccount, namespace if err != nil { return err } - _,err = k8sClient.CoreV1().ServiceAccounts(namespace).Get(ctx, referencedServiceAccount, metav1.GetOptions{}) + _, err = k8sClient.CoreV1().ServiceAccounts(namespace).Get(ctx, referencedServiceAccount, metav1.GetOptions{}) if err != nil { return err }