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

Port Ansible scaffolding to Kubebuilder plugin #3488

Merged
merged 2 commits into from
Jul 25, 2020

Conversation

asmacdo
Copy link
Member

@asmacdo asmacdo commented Jul 22, 2020

Boilerplate

  • Create init plugin
  • Create api plugin

Config

  • Scaffold kustomize default dir
  • Scaffold CRD bases and kustomization
  • Scaffold manager
  • Scaffold RBAC
  • Scaffold samples (CR)

Operator Image

  • Scaffold Dockerfile
  • Scaffold ansible Roles
  • scaffold requirements.yaml
  • scaffold watches.yaml

Misc

Tests

  • Port e2e tests
  • scaffold molecule

@asmacdo asmacdo added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 22, 2020
@openshift-ci-robot openshift-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 22, 2020
@joelanford joelanford mentioned this pull request Jul 22, 2020
92 tasks
@@ -101,10 +101,10 @@ const kustomizeTemplate = `resources:
- auth_proxy_role.yaml
- auth_proxy_role_binding.yaml
- auth_proxy_client_clusterrole.yaml
patchesJson6902:
Copy link
Contributor

Choose a reason for hiding this comment

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

what is patchesJson6902?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, very interesting. But, why do we need to do this change? What is the end goal?
What is the problem that you are trying to solve with?

Copy link
Member

Choose a reason for hiding this comment

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

It allows us to add RBAC for CRDs without modifying the central role.yaml that the user configures, and means we don't need an updater for the role.yaml

Copy link
Contributor

Choose a reason for hiding this comment

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

But then you are changing the common the purposed of these files. They should not be used by us. They are just helpers for the admins. I'd recommend to check the role implementation in helm. I think it would be exactly the same for ansible.

Copy link
Contributor

@camilamacedo86 camilamacedo86 left a comment

Choose a reason for hiding this comment

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

hi @asmacdo,

Could you please revert the changes in the structure of the files and not move them for other directories?

See that, when something change in Go/Kube we should be able to easily apply/patch the changes if we are able to diff both plugins dirs. The same across Helm/Ansible since they are very similar. Also, note that the changes made in the directories of the common files make harder not only to keep it maintained and synchronized across the projects with the other types as to review this pr as well. In this way;

  • As a maintainer, I'd like to diff ansible/helm plugins dirs and get just the diff between both. All common files would be ==
  • As a maintainer, I'd like to diff go(kb)/ansible plugins dirs and get just the diff between both. All common files would be ==

@fabianvf
Copy link
Member

@camilamacedo86 we intentionally changed the directory structure of the Ansible scaffolding to match the directory structure of the scaffolded code to make maintenance and contribution easier (especially from our less go-savvy Ansible contributors), these projects are likely going to be split into their own repos soon so I don't think there's much advantage to a 1-1 match up in directory structures.

spec:
description: Spec defines the desired state of {{ .Resource.Kind }}
type: object
x-kubernetes-preserve-unknown-fields: true
Copy link
Member

Choose a reason for hiding this comment

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

Is this being set to true because the type's spec/status will change when fields are added? If so, do you think it makes sense to remove these to enforce validation on all fields by default? If the operator author wants to skip validation, they can manually add these.

Copy link
Member

Choose a reason for hiding this comment

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

Adding validation is painful in Ansible as it has to be done entirely by hand, until we have some kind of tooling to support it I think it makes sense to be permissive by default. Anyone going through the trouble of writing the whole schema by hand can also remove this field in the process if they'd like to

Copy link
Member

Choose a reason for hiding this comment

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

That's fair, just gotta make sure this is documented since the CRD scaffold behavior differs from Go's.

mkdir -p bin ;\
curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/{{ .KustomizeVersion }}/kustomize_{{ .KustomizeVersion }}_$(OS)_$(ARCH).tar.gz | tar xzf - -C bin/ ;\
}
KUSTOMIZE=./bin/kustomize
Copy link
Member

Choose a reason for hiding this comment

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

From the Helm plugin:

Suggested change
KUSTOMIZE=./bin/kustomize
KUSTOMIZE=$(realpath ./bin/kustomize)

# mkdir -p bin ;\
# curl -LO https://github.com/operator-framework/operator-sdk/releases/download/{{ .AnsibleOperatorVersion}}/ansible-operator-{{ .AnsibleOperatorVersion}}-$(ARCHOPER)-$(OSOPER) ;\
# mv ansible-operator-{{ .AnsibleOperatorVersion}}-$(ARCHOPER)-$(OSOPER) ./bin/ansible-operator ;\
# chmod +x ./bin/helm-operator ;\
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# chmod +x ./bin/helm-operator ;\
# chmod +x ./bin/ansible-operator ;\

tmpl := template.Must(template.New("rules").Funcs(file.DefaultFuncMap()).Parse(watchFragment))
err := tmpl.Execute(buf, f)
if err != nil {
panic(err)
Copy link
Member

Choose a reason for hiding this comment

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

Do you plan on removing this panic? Ideally the watches fragment could be constructed without using a template as to not have to handle an error. If that is not possible/ergonomic, I'd rather see this template executed in the caller and passed as a field to WatchesUpdater. Perhaps in an exported function that generates a watches fragment?

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 had to use a template rather than Sprintf to enable {{.Resource.Kind | lower }} in the fragment. I borrowed the error handling from a similar situation in the helm plugin

I assume the reason for moving this into an exported function is that it would improve error handling?

Copy link
Member

Choose a reason for hiding this comment

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

Pretty much. I'd like to avoid panics if possible, and this function technically could panic because it takes user input (Resource), however unlikely due to upstream validation. I'm fine leaving this alone for now with a TODO and addressing in a follow-up.

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO the watches here would be == the helm one. However, instead of you have the Charts attribute you will have the ansible role and playbooks.

@camilamacedo86
Copy link
Contributor

camilamacedo86 commented Jul 23, 2020

Hi @fabianvf,

we intentionally changed the directory structure of the Ansible scaffolding to match the directory structure of the scaffolded code to make maintenance and contribution easier (especially from our less go-savvy Ansible contributors)

How move the path or rename the common(base core) files can be helpful for them? For example; why/how move the auth_proxy_patch.go (which is == for all types) from/scaffolds/templates/metricsauth/auth_proxy_patch.go to templates/config/kustomize/auth_proxy_patch.go make maintenance and contribution easier ?

these projects are likely going to be split into their own repos soon so I don't think there's much advantage to a 1-1 match up in directory structures.

Let's imagine the very common scenarios;

  • A new version of Go/kubebuilder was released and we need to patch the changes to ansible/helm
  • A new feature or fix for ansible that should be applied to Helm
  • A new feature or fix for helm that should be applied to ansible

Note that, we can just diff <repoA>/<pluginA>/<versionA> with <repoB>/<pluginB>/<versionB> via many tools to check what, where and how was changed which allows us easily decide what should be applied or not and do not matter if the dirs are or not in the same repo.

ps.: Indeed, just look for the same file and remember that we need to memorize that it is in A and B in one place when is another in C increase the complexity unnecessarily in mine POV.

  • I am as a maintainer, I'd like to diff go/ansible/helm plugins dirs and get just the diff between them. All common/core base-files would be equals.

So IMO it is very important we keep the same structure and do not change the default/common files across them. (At least in this first moment, note that we may realize that we ought to centralize it)

@jmrodri @joelanford @estroz wdyt?
c/c @asmacdo

// TODO(asmacdo) can this go?
// AnsibleDelims is a slice of two strings representing the left and right delimiters for ansible templates.
// Arrays can't be constants but this should be a constant.
var AnsibleDelims = [2]string{"[[", "]]"}
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO this file is not required see that each const is used just once in the boilerplate that will use that to scaffold the file,

@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 24, 2020
hack/tests/e2e-ansible.sh Outdated Show resolved Hide resolved
Comment on lines +107 to +152
if !p.doAPIScaffold {
fmt.Printf("Next: define a resource with:\n$ %s create api\n", p.commandName)
}

return nil
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if !p.doAPIScaffold {
fmt.Printf("Next: define a resource with:\n$ %s create api\n", p.commandName)
}
return nil
// runs the SDK customizations (wrappers)
if err := utilplugins.UpdateMakefile(p.config); err != nil {
return err
}
if p.doAPIScaffold {
return p.apiPlugin.PostScaffold()
}
fmt.Printf("Next: define a resource with:\n$ %s create api\n", p.commandName)
return nil

Copy link
Contributor

Choose a reason for hiding this comment

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

runs the customization for SDK

Copy link
Member

Choose a reason for hiding this comment

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

I'll handle this in a follow-up.


var (
supportedProjectVersions = []string{config.Version3Alpha}
pluginVersion = plugin.Version{Number: 1}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
pluginVersion = plugin.Version{Number: 1}
pluginVersion = plugin.Version{Number: 1}
pluginKey = plugin.KeyFor(Plugin{})

Copy link
Member

Choose a reason for hiding this comment

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

pluginKey wouldn't be used anywhere yet. I expect this to be added when help text is.

Copy link
Member

@jmrodri jmrodri 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 lgtm Indicates that a PR is ready to be merged. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed lgtm Indicates that a PR is ready to be merged. labels Jul 24, 2020
Copy link
Member

@joelanford joelanford 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 Jul 24, 2020
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 removed the lgtm Indicates that a PR is ready to be merged. label Jul 24, 2020
@openshift-ci-robot
Copy link

New changes are detected. LGTM label has been removed.

@openshift-ci-robot openshift-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 24, 2020
--generate-playbook
mkdir memcached-operator
pushd memcached-operator
operator-sdk init --plugins ansible.operator-sdk.io/v1 \
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
operator-sdk init --plugins ansible.operator-sdk.io/v1 \
operator-sdk init --plugins ansible.sdk.operatorframework.io/v1 \

pushd memcached-operator

operator-sdk init --plugins ansible.operator-sdk.io/v1 \
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
operator-sdk init --plugins ansible.operator-sdk.io/v1 \
operator-sdk init --plugins ansible.sdk.operatorframework.io/v1 \

Follow the new kubebuilderlayout, including the use of kustomize
@joelanford joelanford dismissed camilamacedo86’s stale review July 25, 2020 00:49

The remaining requested changes will be addressed in follow-ups

@asmacdo asmacdo merged commit b999502 into operator-framework:master Jul 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants