Skip to content

Commit

Permalink
ansible/helm - apply the service acount
Browse files Browse the repository at this point in the history
  • Loading branch information
Camila Macedo committed Mar 13, 2021
1 parent c6796de commit 4988f8b
Show file tree
Hide file tree
Showing 41 changed files with 433 additions and 446 deletions.
70 changes: 70 additions & 0 deletions changelog/fragments/service_account.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# entries is a list of entries to include in
# release notes and/or the migration guide
entries:
- description: >
(ansible/v1) (helm/v1) Create and bind to a non-default service account ([kubebuilder#2070](https://github.com/kubernetes-sigs/kubebuilder/pull/2070))
kind: addition
migration:
header: (go/v3) Add a `system:controller-manager` ServiceAccount to your project.
body: >
A non-default ServiceAccount `controller-manager` is scaffolded on `operator-sdk init`,
to improve security for operators installed in shared namespaces. To add this ServiceAccount
to your project, do the following:
```sh
# Create the ServiceAccount.
cat <<EOF > config/rbac/service_account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: controller-manager
namespace: system
EOF
# Add it to the list of RBAC resources.
echo "- service_account.yaml" >> config/rbac/kustomization.yaml
# Update all RoleBinding and ClusterRoleBinding subjects that reference the operator's ServiceAccount.
find config/rbac -name *_binding.yaml -exec sed -i -E 's/ name: default/ name: controller-manager/g' {} \;
# Add the ServiceAccount name to the manager Deployment's spec.template.spec.serviceAccountName.
sed -i -E 's/([ ]+)(terminationGracePeriodSeconds:)/\1serviceAccountName: controller-manager\n\1\2/g' config/manager/manager.yaml
```
The changes should look like:
```diff
# config/manager/manager.yaml
requests:
cpu: 100m
memory: 20Mi
+ serviceAccountName: controller-manager
terminationGracePeriodSeconds: 10
# config/rbac/auth_proxy_role_binding.yaml
name: proxy-role
subjects:
- kind: ServiceAccount
- name: default
+ name: controller-manager
namespace: system
# config/rbac/kustomization.yaml
resources:
+- service_account.yaml
- role.yaml
- role_binding.yaml
- leader_election_role.yaml
# config/rbac/leader_election_role_binding.yaml
name: leader-election-role
subjects:
- kind: ServiceAccount
- name: default
+ name: controller-manager
namespace: system
# config/rbac/role_binding.yaml
name: manager-role
subjects:
- kind: ServiceAccount
- name: default
+ name: controller-manager
namespace: system
# config/rbac/service_account.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: controller-manager
+ namespace: system
```
2 changes: 1 addition & 1 deletion internal/plugins/ansible/v1/scaffolds/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (s *initScaffolder) scaffold() error {
&rbac.LeaderElectionRoleBinding{},
&rbac.ManagerRole{},
&rbac.RoleBinding{},

&rbac.ServiceAccount{},
&prometheus.Kustomization{},
&prometheus.ServiceMonitor{},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,6 @@ spec:
port: 6789
initialDelaySeconds: 5
periodSeconds: 10
serviceAccountName: controller-manager
terminationGracePeriodSeconds: 10
`
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ roleRef:
name: proxy-role
subjects:
- kind: ServiceAccount
name: default
name: controller-manager
namespace: system
`
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ func (f *Kustomization) SetTemplateDefaults() error {
}

const kustomizeRBACTemplate = `resources:
# All RBAC will be applied under this service account in
# the deployment namespace. You may comment out this resource
# if your manager will use a service account that exists at
# runtime. Be sure to update RoleBinding and ClusterRoleBinding
# subjects if changing service account names.
- service_account.yam
- role.yaml
- role_binding.yaml
- leader_election_role.yaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ roleRef:
name: leader-election-role
subjects:
- kind: ServiceAccount
name: default
name: controller-manager
namespace: system
`
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ roleRef:
name: manager-role
subjects:
- kind: ServiceAccount
name: default
name: controller-manager
namespace: system
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Copyright 2019 The Kubernetes Authors.
Modifications copyright 2020 The Operator-SDK Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rbac

import (
"path/filepath"

"sigs.k8s.io/kubebuilder/v3/pkg/model/file"
)

var _ file.Template = &ServiceAccount{}

// ServiceAccount scaffolds a file that defines the service account the manager is deployed in.
type ServiceAccount struct {
file.TemplateMixin
}

// SetTemplateDefaults implements file.Template
func (f *ServiceAccount) SetTemplateDefaults() error {
if f.Path == "" {
f.Path = filepath.Join("config", "rbac", "service_account.yaml")
}

f.TemplateBody = serviceAccountTemplate

return nil
}

const serviceAccountTemplate = `apiVersion: v1
kind: ServiceAccount
metadata:
name: controller-manager
namespace: system
`
1 change: 1 addition & 0 deletions internal/plugins/helm/v1/scaffolds/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (s *initScaffolder) scaffold() error {
&rbac.LeaderElectionRoleBinding{},
&rbac.ManagerRole{},
&rbac.ManagerRoleBinding{},
&rbac.ServiceAccount{},
&manager.Kustomization{},
&manager.Manager{Image: imageName},
&prometheus.Kustomization{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ roleRef:
name: proxy-role
subjects:
- kind: ServiceAccount
name: default
name: controller-manager
namespace: system
`
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ roleRef:
name: leader-election-role
subjects:
- kind: ServiceAccount
name: default
name: controller-manager
namespace: system
`
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ roleRef:
name: manager-role
subjects:
- kind: ServiceAccount
name: default
name: controller-manager
namespace: system
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Copyright 2019 The Kubernetes Authors.
Modifications copyright 2020 The Operator-SDK Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rbac

import (
"path/filepath"

"sigs.k8s.io/kubebuilder/v3/pkg/model/file"
)

var _ file.Template = &ServiceAccount{}

// ServiceAccount scaffolds a file that defines the service account the manager is deployed in.
type ServiceAccount struct {
file.TemplateMixin
}

// SetTemplateDefaults implements file.Template
func (f *ServiceAccount) SetTemplateDefaults() error {
if f.Path == "" {
f.Path = filepath.Join("config", "rbac", "service_account.yaml")
}

f.TemplateBody = serviceAccountTemplate

return nil
}

const serviceAccountTemplate = `apiVersion: v1
kind: ServiceAccount
metadata:
name: controller-manager
namespace: system
`
2 changes: 1 addition & 1 deletion internal/scorecard/testdata/pod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ spec:
dnsPolicy: ClusterFirst
restartPolicy: Never
securityContext: {}
serviceAccount: default
serviceAccount: controller-manager
serviceAccountName: default
volumes:
- name: scorecard-bundle
Expand Down
25 changes: 13 additions & 12 deletions test/e2e/ansible/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,25 +252,26 @@ var _ = Describe("Running ansible projects", func() {
fmt.Sprintf("--serviceaccount=%s:default", tc.Kubectl.Namespace))
Expect(err).NotTo(HaveOccurred())

By("getting the token")
b64Token, err := tc.Kubectl.Get(
true,
"secrets",
"-o=jsonpath={.items[0].data.token}")
By("reading the metrics token")
// Filter token query by service account in case more than one exists in a namespace.
query := fmt.Sprintf(`{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="%s")].data.token}`,
tc.Kubectl.ServiceAccount,
)
b64Token, err := tc.Kubectl.Get(true, "secrets", "-o=jsonpath="+query)
Expect(err).NotTo(HaveOccurred())
token, err := base64.StdEncoding.DecodeString(strings.TrimSpace(b64Token))
Expect(err).NotTo(HaveOccurred())
Expect(token).NotTo(HaveLen(0))
Expect(len(token)).To(BeNumerically(">", 0))

By("creating a pod with curl image")
// todo: the flag --generator=run-pod/v1 is deprecated, however, shows that besides
By("creating a curl pod")
// TODO: the flag --generator=run-pod/v1 is deprecated, however, shows that besides
// it should not make any difference and work locally successfully when the flag is removed
// CI has been failing and the curl pod is not found when the flag is not used
// the test will fail and the curl pod is not found when the flag is not used
cmdOpts := []string{
"run", "--generator=run-pod/v1", "curl", "--image=curlimages/curl:7.68.0", "--restart=OnFailure", "--",
"run", "--generator=run-pod/v1", "curl", "--image=curlimages/curl:7.68.0", "--restart=OnFailure",
"--serviceaccount", tc.Kubectl.ServiceAccount, "--",
"curl", "-v", "-k", "-H", fmt.Sprintf(`Authorization: Bearer %s`, token),
fmt.Sprintf("https://%s-controller-manager-metrics-service.%s.svc:8443/metrics",
tc.ProjectName, tc.Kubectl.Namespace),
fmt.Sprintf("https://%s-controller-manager-metrics-service.%s.svc:8443/metrics", tc.ProjectName, tc.Kubectl.Namespace),
}
_, err = tc.Kubectl.CommandInNamespace(cmdOpts...)
Expect(err).NotTo(HaveOccurred())
Expand Down
22 changes: 12 additions & 10 deletions test/e2e/helm/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,22 +209,24 @@ var _ = Describe("Running Helm projects", func() {
fmt.Sprintf("--serviceaccount=%s:default", tc.Kubectl.Namespace))
Expect(err).NotTo(HaveOccurred())

By("getting the token")
b64Token, err := tc.Kubectl.Get(
true,
"secrets",
"-o=jsonpath={.items[0].data.token}")
By("reading the metrics token")
// Filter token query by service account in case more than one exists in a namespace.
query := fmt.Sprintf(`{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="%s")].data.token}`,
tc.Kubectl.ServiceAccount,
)
b64Token, err := tc.Kubectl.Get(true, "secrets", "-o=jsonpath="+query)
Expect(err).NotTo(HaveOccurred())
token, err := base64.StdEncoding.DecodeString(strings.TrimSpace(b64Token))
Expect(err).NotTo(HaveOccurred())
Expect(token).NotTo(HaveLen(0))
Expect(len(token)).To(BeNumerically(">", 0))

By("creating a pod with curl image")
// todo: the flag --generator=run-pod/v1 is deprecated, however, shows that besides
By("creating a curl pod")
// TODO: the flag --generator=run-pod/v1 is deprecated, however, shows that besides
// it should not make any difference and work locally successfully when the flag is removed
// CI has been failing and the curl pod is not found when the flag is not used
// the test will fail and the curl pod is not found when the flag is not used
cmdOpts := []string{
"run", "--generator=run-pod/v1", "curl", "--image=curlimages/curl:7.68.0", "--restart=OnFailure", "--",
"run", "--generator=run-pod/v1", "curl", "--image=curlimages/curl:7.68.0", "--restart=OnFailure",
"--serviceaccount", tc.Kubectl.ServiceAccount, "--",
"curl", "-v", "-k", "-H", fmt.Sprintf(`Authorization: Bearer %s`, token),
fmt.Sprintf("https://%s-controller-manager-metrics-service.%s.svc:8443/metrics", tc.ProjectName, tc.Kubectl.Namespace),
}
Expand Down

This file was deleted.

Loading

0 comments on commit 4988f8b

Please sign in to comment.