Skip to content

Conversation

ryansteakley
Copy link
Member

@ryansteakley ryansteakley commented Aug 5, 2021

Issue #, if available:
aws-controllers-k8s/community#770

Description of changes:

  • Adds namespacedInstallation flag for helm values.yaml to specify that Role and RoleBinding should be used instead of ClusterRole and ClusterRoleBinding
  • Specifies that watchNamespace in helmvalues.yaml must be set if using namespacedInstallation flag.
  • Contains a sed to replace the original output of the role-controller.yaml file with the template code that allows for the programmatic setting of namespacedInstallation in the helm values.yaml
  • Adds a overlays/namespaced directory for the raw yamls in config. This folder contains the json patch files, role.yaml and role-binding.yaml that will modify the ClusterRole and ClusterRoleBinding files to be Role and RoleBinding. This allows the user to apply these changes using raw yaml and not helm if these wish.
  • Chose to reuse the names of cluster-role-binding.yaml and cluster-role-controller.yaml so that every service repo doesn't need to rm these files since they already exist in their repo and any other naming of the yaml files will cause multiple roles/bindings to install causing installation failures.

Tested locally

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@ack-bot ack-bot requested review from jaypipes and vijtrip2 August 5, 2021 23:06
@ack-bot ack-bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Aug 5, 2021
@ack-bot
Copy link
Collaborator

ack-bot commented Aug 5, 2021

Hi @ryansteakley. Thanks for your PR.

I'm waiting for a aws-controllers-k8s member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link
Contributor

@RedbackThomson RedbackThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on using JSON patches with Kustomize
+1 on working around the limitation with the autogenerated role YAML file

I have some inline suggestions about file extensions and names.

[{"op": "replace",
"path": "/kind",
"value": "RoleBinding"},

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove excess whitespace

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still some excess whitespace here. Probably can go to 1 line per object:

[{"op": "replace", "path": "/kind", "value": "RoleBinding"},
{"op": "add", "path": "/metadata/namespace", "value":  "ack-system"},
{"op": "replace","path": "/roleRef/kind","value": "Role"}] 

group: rbac.authorization.k8s.io
version: v1
kind: ClusterRole
name: ack-sagemaker-controller
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does "sagemaker" need to be hardcoded here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought I removed this must have pushed it again by accident :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. These might need to be made into Go templates and inject {{ .ServiceIDClean }} just like the cluster-role-binding.yaml.tpl

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep had to make them into go templates and put them in release.go and controller.go respectively

@ryansteakley ryansteakley force-pushed the namespaced-installation branch from 8a9e3c0 to 46bace7 Compare August 6, 2021 18:35
Copy link
Collaborator

@jaypipes jaypipes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryansteakley you marked a number of conversations between you and @RedbackThomson as resolved, but I don't actually see changes made... did you forget to git push your changes?

Copy link
Contributor

@RedbackThomson RedbackThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just have one more concern about our helm patch file - see inline comments

[{"op": "replace",
"path": "/kind",
"value": "RoleBinding"},

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still some excess whitespace here. Probably can go to 1 line per object:

[{"op": "replace", "path": "/kind", "value": "RoleBinding"},
{"op": "add", "path": "/metadata/namespace", "value":  "ack-system"},
{"op": "replace","path": "/roleRef/kind","value": "Role"}] 

@ryansteakley
Copy link
Member Author

ryansteakley commented Aug 9, 2021

@ryansteakley you marked a number of conversations between you and @RedbackThomson as resolved, but I don't actually see changes made... did you forget to git push your changes?

Going to look into it, it is very possible some changes got git stash and never applied again

Some of the conversations related to file naming extensions ended up in keeping the .tpl extension as they were needed to get {{ .ServiceIDClean }} injected

Copy link
Contributor

@RedbackThomson RedbackThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. I think you've nailed it, now!

Copy link
Collaborator

@jaypipes jaypipes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs a bit more thought put into it. I need to do some more review here.


# If specified, the service controller will only be able to operate in a single namespace. Set by default to K8S_NAMESPACE
# If set to true, user must set watchNamespace as well.
namespacedInstallation: false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this additional option? If watchNamespace is required, then why can't we just switch on watchNamespace != ""?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A customer may want to set the watchNamespace but still have their resource be cluster-scoped. This allows for flexibility in changing the watchNamespace value later, and not having to redeploy anything except the deployment. It also means that a user could install the controller into the ack-system namespace and watch another namespace. Installing as namespacedInstallation = true requires the Helm chart be installed into the watchNamespace

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A customer may want to set the watchNamespace but still have their resource be cluster-scoped.

Why? Isn't the whole point of namespaced installation to limit the CRDs, the RBACs that can read those CRs and the namespace that those CRs can be created in to just a single namespace?

Copy link
Contributor

@RedbackThomson RedbackThomson Aug 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying to not conflate the two ideas:

  1. Watch a single namespace
  2. Be installed into the scope of the single namespace

Users may want 1 but not 2. But if they want 2, it is required that they also do 1.

If you want to bundle them up into the same thing and ship them together, then ok I'm on board. I wanted to offer the choice, at least.

Note: I guess I don't understand how customers are using namespace scoping well enough to draw a judgement on what they would want.

@@ -1,11 +1,22 @@
apiVersion: rbac.authorization.k8s.io/v1
{{ "{{ if not .Values.namespacedInstallation }}" }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below... this could simply be:

{{ "{{ if not .Values.watchNamespace }}" }}

@@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
{{ "{{ if not .Values.namespacedInstallation }}" }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below... I don't see why this can't just be:

{{ "{{ if not .Values.watchNamespace }}" }}

metadata:
creationTimestamp: null
name: ack-{{ .ServiceIDClean }}-controller
{{ "{{ else if and .Values.namespacedInstallation (required \"watchNamespace must be set for namespaced installation\" .Values.watchNamespace) }}" }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this would not be necessary... could just be {{ else }}

# `cluster-role-controller.yaml` to better reflect what is in that file. We additionally add the ability
# for the user to specify if they want the role to be ClusterRole or Role by specifying installation scope
# in the helm values.yaml
sed -e '1r '"$helm_output_dir/templates/_controller-role-kind-patch.yaml"'' -e '1, 7d' $helm_output_dir/templates/role.yaml > $helm_output_dir/templates/cluster-role-controller.yaml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh boy...

Way too much magic and sed-fu to be readable and understandable by mere mortals.

We need to find a clearer way of doing this.

Copy link
Member Author

@ryansteakley ryansteakley Aug 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue is that the role.yaml file is auto-generated by controller-gen. So there will have to be some overwriting of the auto-generated file with the lines of code we want to allow the user to switch programmatically between clusterrole and role.

@@ -0,0 +1,3 @@
[{"op": "replace", "path": "/kind", "value": "RoleBinding"},
{"op": "add", "path": "/metadata/namespace", "value": "ack-system"},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is replacing the namespace that should be supplied by the user in .Values.watchNamespace with the hard-coded string "ack-system", which is defeating the original purpose of a namespace-scoped installation, no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is for the Kustomize overlay - no Helm values to replace, here. All of these Kustomize files use ack-system as the default namespace. The user will need to override the values for all resources anyway, so may as well make this one match.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, yes, ok that makes sense.

@@ -0,0 +1,2 @@
[{"op": "replace", "path": "/kind", "value": "Role"},
{"op": "add", "path": "/metadata/namespace", "value": "ack-system"}] No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above about hard-coded "ack-system".

@jaypipes
Copy link
Collaborator

/hold

@ack-bot ack-bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 11, 2021
@RedbackThomson
Copy link
Contributor

As described on Slack with @jaypipes and @ryansteakley:
With the current implementation of .Values.watchNamespace, there are two places where the namespace will need to be specified when installing with namespace-scope. Those two places are the {{ .Release.Namespace }} (--namespace when calling helm install) as well as the --set watchNamespace value. When installing in namespace-scope, these values NEED to be identical, otherwise the Role will not have the privilege to access the resources.

I suggest that we remove the watchNamespace value altogether, and default the --watch-namespace argument to {{ .Release.Namespace}}. We should also have a value to track whether the controller should be installed into cluster or namespace scope - e.g. clusterScope: cluster|namespace. If the clusterScope == namespace, then we change all ClusterRole to Role, and set the --watch-namespace argument.

This would reduce the chance of a user accidentally applying the Helm chart into a namespace where the deployment does not have sufficient privileges. It also reduces the number of independent variables that need to align for a correct configuration.

Comment on lines +34 to +38
{{- define "watch-namespace" -}}
{{- if eq .Values.installScope "namespace" -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we confirmed that this defaults to an empty string when install scope is cluster?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Environment:
      K8S_NAMESPACE:                   ack-system (v1:metadata.namespace)
      AWS_ACCOUNT_ID:                  123456789012
      AWS_REGION:                      us-west-1
      AWS_ENDPOINT_URL:                
      ACK_WATCH_NAMESPACE:             
      ACK_ENABLE_DEVELOPMENT_LOGGING:  true
      ACK_LOG_LEVEL:                   debug
      ACK_RESOURCE_TAGS:               services.k8s.aws/managed=true,services.k8s.aws/created=%UTCNOW%,services.k8s.aws/namespace=%KUBERNETES_NAMESPACE%
      AWS_ROLE_ARN:                    arn:aws:iam::123456789012:role/ack-controller-role-namespaced
      AWS_WEB_IDENTITY_TOKEN_FILE:     /var/run/secrets/eks.amazonaws.com/serviceaccount/token

Defaults to an empty string when using cluster.
When using namespace, value is correctly passed.

  Environment:
      K8S_NAMESPACE:                   ack-system (v1:metadata.namespace)
      AWS_ACCOUNT_ID:                  123456789012
      AWS_REGION:                      us-west-1
      AWS_ENDPOINT_URL:                
      ACK_WATCH_NAMESPACE:             ack-system
      ACK_ENABLE_DEVELOPMENT_LOGGING:  true
      ACK_LOG_LEVEL:                   debug
      ACK_RESOURCE_TAGS:               services.k8s.aws/managed=true,services.k8s.aws/created=%UTCNOW%,services.k8s.aws/namespace=%KUBERNETES_NAMESPACE%
      AWS_ROLE_ARN:                    arn:aws:iam::123456789012:role/ack-controller-role-namespaced
      AWS_WEB_IDENTITY_TOKEN_FILE:     /var/run/secrets/eks.amazonaws.com/serviceaccount/token

Comment on lines 16 to 18
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ack-{{ .ServiceIDClean }}-controller
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Remove duplication by moving apiGroup and name to after {{ end }} (and removing from both conditional blocks)


# If specified, the service controller will watch for object creation only in the provided namespace
watchNamespace: ""
# Set to namespace to install the controller in a namespaced scope, will only watch for object creation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: For clarity,

Suggested change
# Set to namespace to install the controller in a namespaced scope, will only watch for object creation
# Set to "namespace" to install the controller in a namespaced scope, will only watch for object creation

Copy link
Collaborator

@jaypipes jaypipes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I like it.

@@ -0,0 +1,3 @@
[{"op": "replace", "path": "/kind", "value": "RoleBinding"},
{"op": "add", "path": "/metadata/namespace", "value": "ack-system"},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, yes, ok that makes sense.

@jaypipes
Copy link
Collaborator

@RedbackThomson feel free to lgtm if you're also good with this.

Copy link
Member

@a-hilaly a-hilaly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@RedbackThomson RedbackThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ship it!
/lgtm

@ack-bot ack-bot added the lgtm Indicates that a PR is ready to be merged. label Aug 16, 2021
@ack-bot
Copy link
Collaborator

ack-bot commented Aug 16, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: A-Hilaly, jaypipes, RedbackThomson, ryansteakley

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [A-Hilaly,RedbackThomson,jaypipes]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@RedbackThomson
Copy link
Contributor

/unhold

@ack-bot ack-bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 16, 2021
@ack-bot ack-bot merged commit ac31817 into aws-controllers-k8s:main Aug 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved lgtm Indicates that a PR is ready to be merged. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants