Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg/scaffold/role,pkg/operator-sdk/new.go: generate role rules from helm chart #1188

Merged
merged 9 commits into from
Apr 11, 2019

Conversation

joelanford
Copy link
Member

Description of the change:
When creating a helm-based project, parse the Helm chart templates to generate the role

Motivation for the change:
Instead of scaffolding a static role, which will likely have unnecessary rules and be missing necessary rules, we can generate the role rules dynamically from the chart templates.

This will enable operators to be generated with the correct RBAC rules for nearly all existing Helm charts.

/cc @dmesser @robszumski

@joelanford joelanford added the language/helm Issue is related to a Helm operator project label Mar 8, 2019
@openshift-ci-robot openshift-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 8, 2019
@joelanford
Copy link
Member Author

joelanford commented Mar 11, 2019

This PR currently has a couple of rough edges (and probably others I haven't thought about):

  1. Many Helm charts (at least 82 of 266 in the official stable repo) have templates for cluster-scoped resources (e.g. ClusterRole and ClusterRoleBinding), but this PR makes no attempt to discern between templates for namespace-scoped resources and cluster-scoped resources, and therefore groups all the rules together into either a Role or ClusterRole, depending on whether --cluster-scoped is set.

    The result is that rules that need to be in a ClusterRole incorrectly end up in a Role when --cluster-scoped is not set.

  2. To create a rule, we need the pluralized resource name, but all we have in the template is a GVK. This PR makes a best effort attempt to convert a kind to a resource, but some resources may have plural names that don't match our conversion.

EDIT: Both of these issues are now solved in the PR, which now uses the discovery API to lookup all the resources to get their scope and plural name.

Copy link
Member

@lilic lilic left a comment

Choose a reason for hiding this comment

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

Did a quick review and left some suggestions.

I am not sure if we can somehow make use of https://github.com/liggitt/audit2rbac to generate the RBAC? Or at least have a look what the project does, as it solves a similar problem, but guess that would be more for go operators.

pkg/scaffold/helm/chart.go Outdated Show resolved Hide resolved
func GenerateRoleRules(chart *chart.Chart) ([]rbacv1.PolicyRule, []error) {
helmOperatorRules := []rbacv1.PolicyRule{
// We need this rule so tiller can read namespaces to ensure they exist
{
Copy link
Member

Choose a reason for hiding this comment

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

Should we document the following "default" rules we have in place so the user understands and doesn't remove them?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a good idea. Unfortunately, the comments get stomped out by scaffold.UpdateRoleForResource because of the marshaling and unmarshaling that happens.

Kubernetes has an open issue addressing this problem: kubernetes/kubernetes#15157

pkg/scaffold/helm/chart.go Outdated Show resolved Hide resolved
pkg/scaffold/helm/chart.go Outdated Show resolved Hide resolved
}

// Skip templates that don't look like Kubernetes resources
if apiVersion == "" && kind == "" {
Copy link
Member

Choose a reason for hiding this comment

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

What if we just do:

if apiVersion == "" || kind == "" {
        errs = append(errs, fmt.Errorf("could not find resource kind or apiVersion %s[%d]", name, i))
	continue
}

Copy link
Member Author

Choose a reason for hiding this comment

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

This has also been slightly reworked. I left the separate checks for apiVersion and kind so that the logged warning would be more specific.

rules = append(rules, rbacv1.PolicyRule{
APIGroups: []string{group},
Resources: resources,
Verbs: []string{rbacv1.VerbAll},
Copy link
Member

Choose a reason for hiding this comment

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

So if I understand correctly we are just giving it *, I understand we can't fine tune this, but maybe we can document that the user double checks the generated rules?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think * is reasonable for these rules because the Helm operator needs to create, get, update, and delete all of the templated resources.

However, since the code now renders the default manifest and uses that to build rules, it is possible that some resources require custom values to be set so that they are present in the release manifest. I'll add a log at the end, that says something along the lines of:

Double check deploy/role.yaml to verify correct RBAC policy rules. The existing rules were created from the default chart manifest, so some rules may be overly broad or missing.

@openshift-ci-robot openshift-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 1, 2019
@joelanford joelanford force-pushed the helm-generate-role branch 2 times, most recently from f73232e to 1d1800e Compare April 2, 2019 00:32
When fetching chart dependencies, collect the Helm output in a
buffer. If an error occurs, output the buffer before returning
the error.
…ernal/pkg/scaffold/constants.go to avoid unnecessary dep imports in non-helm projects"

This reverts commit fc556e8.
Copy link
Member

@estroz estroz left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Apr 10, 2019
}
if err := man.Build(); err != nil {
fmt.Println(out.String())
return err
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit but can we wrap this and other errors like in Line 148. Either here or in the caller.

Otherwise we could end up with error messages that aren't too clear like in #1281
Right now I think this could end up showing something like:

failed to create helm chart: requirements.yaml cannot be opened: ....

https://github.com/helm/helm/blob/master/pkg/downloader/manager.go#L83

whereas I'd prefer to see:

failed to create helm chart: failed to fetch/build chart dependencies: requirements.yaml cannot be opened: ....

Copy link
Contributor

@hasbro17 hasbro17 left a comment

Choose a reason for hiding this comment

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

LGTM

Worth mentioning this in the CHANGELOG.
And do you think we should point out this behavior out in the helm user-guide?

Copy link
Member

@lilic lilic left a comment

Choose a reason for hiding this comment

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

lgtm 👍

@openshift-ci-robot openshift-ci-robot removed the lgtm Indicates that a PR is ready to be merged. label Apr 11, 2019
@openshift-ci-robot
Copy link

New changes are detected. LGTM label has been removed.

@joelanford joelanford merged commit 76d13fc into operator-framework:master Apr 11, 2019
@joelanford joelanford deleted the helm-generate-role branch April 12, 2019 01:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language/helm Issue is related to a Helm operator project size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants