├── .bingo ├── .gitignore ├── README.md ├── Variables.mk ├── bingo.mod ├── bingo.sum ├── go.mod ├── golangci-lint.mod ├── golangci-lint.sum ├── goreleaser.mod ├── goreleaser.sum ├── kind.mod ├── kind.sum ├── setup-envtest.mod ├── setup-envtest.sum └── variables.env ├── .github ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── doc-report.md │ ├── feature-request.md │ └── support-question.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── release.yml │ ├── test-ansible.yml │ ├── test-sanity.yml │ └── unit.yml ├── .gitignore ├── .goreleaser.yml ├── LICENSE ├── Makefile ├── OWNERS ├── OWNERS_ALIASES ├── README.md ├── cmd └── ansible-operator │ └── main.go ├── code-of-conduct.md ├── go.mod ├── go.sum ├── hack ├── check-error-log-msg-format.sh ├── check-license.sh ├── generate │ └── samples │ │ ├── ansible │ │ ├── advanced_molecule.go │ │ ├── constants.go │ │ ├── generate.go │ │ ├── memcached.go │ │ ├── memcached_molecule.go │ │ └── testdata │ │ │ ├── ansible.cfg │ │ │ ├── fixture_collection │ │ │ ├── galaxy.yml │ │ │ └── roles │ │ │ │ └── dummy │ │ │ │ └── tasks │ │ │ │ └── main.yml │ │ │ ├── inventory │ │ │ ├── group_vars │ │ │ │ └── test.yml │ │ │ └── hosts │ │ │ ├── playbooks │ │ │ └── finalizerconcurrencyfinalizer.yml │ │ │ ├── plugins │ │ │ └── filter │ │ │ │ └── test.py │ │ │ ├── secret.yml │ │ │ ├── tasks │ │ │ ├── argstest_test.yml │ │ │ ├── casetest_test.yml │ │ │ ├── clusterannotationtest_test.yml │ │ │ ├── collectiontest_test.yml │ │ │ ├── finalizerconcurrencytest_test.yml │ │ │ ├── inventorytest_test.yml │ │ │ ├── reconciliationtest_test.yml │ │ │ ├── secretstest_test.yml │ │ │ ├── selectortest_test.yml │ │ │ └── subresourcestest_test.yml │ │ │ └── watches.yaml │ │ ├── generate_testdata.go │ │ ├── internal │ │ └── pkg │ │ │ ├── context.go │ │ │ └── utils.go │ │ └── molecule │ │ └── generate.go ├── lib │ └── common.sh └── tests │ └── e2e-ansible-molecule.sh ├── images └── ansible-operator │ ├── Dockerfile │ ├── Pipfile │ ├── Pipfile.lock │ ├── README.md │ └── pipfile.Dockerfile ├── internal ├── annotations │ ├── metrics │ │ ├── metrics.go │ │ ├── metrics_suite_test.go │ │ └── metrics_test.go │ └── scorecard │ │ └── scorecard.go ├── ansible │ ├── apiserver │ │ └── apiserver.go │ ├── controller │ │ ├── controller.go │ │ ├── controller_test.go │ │ ├── reconcile.go │ │ ├── reconcile_test.go │ │ └── status │ │ │ ├── types.go │ │ │ ├── utils.go │ │ │ └── utils_test.go │ ├── events │ │ └── log_events.go │ ├── flags │ │ ├── flag.go │ │ ├── flag_test.go │ │ └── suite_test.go │ ├── handler │ │ ├── handler_suite_test.go │ │ ├── logging_enqueue_annotation.go │ │ ├── logging_enqueue_annotation_test.go │ │ ├── logging_enqueue_object.go │ │ ├── logging_enqueue_object_test.go │ │ ├── logging_enqueue_owner.go │ │ └── logging_enqueue_owner_test.go │ ├── metrics │ │ └── metrics.go │ ├── paramconv │ │ ├── paramconv.go │ │ └── paramconv_test.go │ ├── proxy │ │ ├── cache_response.go │ │ ├── controllermap │ │ │ └── controllermap.go │ │ ├── inject_owner.go │ │ ├── inject_owner_test.go │ │ ├── kubeconfig │ │ │ └── kubeconfig.go │ │ ├── kubectl.go │ │ ├── proxy.go │ │ ├── proxy_suite_test.go │ │ ├── proxy_test.go │ │ └── requestfactory │ │ │ └── requestinfo.go │ ├── runner │ │ ├── eventapi │ │ │ ├── eventapi.go │ │ │ └── types.go │ │ ├── fake │ │ │ └── runner.go │ │ ├── internal │ │ │ └── inputdir │ │ │ │ └── inputdir.go │ │ ├── runner.go │ │ ├── runner_test.go │ │ └── testdata │ │ │ ├── playbook.yml │ │ │ └── roles │ │ │ └── role │ │ │ └── tasks.yaml │ └── watches │ │ ├── testdata │ │ ├── ansible_collections │ │ │ └── nameSpace │ │ │ │ └── collection │ │ │ │ └── roles │ │ │ │ └── someRole │ │ │ │ └── empty_file │ │ ├── duplicate_gvk.yaml │ │ ├── env-vars.yaml │ │ ├── invalid.yaml │ │ ├── invalid_collection.yaml │ │ ├── invalid_duration.yaml │ │ ├── invalid_finalizer_no_vars.yaml │ │ ├── invalid_finalizer_playbook_path.yaml │ │ ├── invalid_finalizer_role_path.yaml │ │ ├── invalid_finalizer_whithout_name.yaml │ │ ├── invalid_playbook_path.yaml │ │ ├── invalid_role_path.yaml │ │ ├── invalid_status.yaml │ │ ├── invalid_yaml_file.yaml │ │ ├── playbook.yml │ │ ├── roles │ │ │ └── role │ │ │ │ └── tasks.yaml │ │ └── valid.yaml.tmpl │ │ ├── watches.go │ │ └── watches_test.go ├── cmd │ └── ansible-operator │ │ ├── run │ │ ├── cmd.go │ │ └── proxy_suite_test.go │ │ └── version │ │ ├── cmd.go │ │ ├── cmd_test.go │ │ └── version_suite_test.go ├── flags │ └── flags.go ├── testutils │ ├── olm.go │ ├── scorecard.go │ └── utils.go ├── util │ ├── bundleutil │ │ ├── bundleutil.go │ │ └── template.go │ ├── k8sutil │ │ ├── api.go │ │ ├── api_test.go │ │ ├── constants.go │ │ ├── k8sutil.go │ │ ├── k8sutil_test.go │ │ ├── object.go │ │ └── scan.go │ └── projutil │ │ ├── interactive_promt_util.go │ │ ├── interactive_promt_util_test.go │ │ ├── project_util.go │ │ └── projutil_test.go └── version │ └── version.go ├── pkg ├── plugins │ ├── ansible │ │ └── v1 │ │ │ ├── api.go │ │ │ ├── constants │ │ │ └── constants.go │ │ │ ├── init.go │ │ │ ├── plugin.go │ │ │ └── scaffolds │ │ │ ├── api.go │ │ │ ├── init.go │ │ │ └── internal │ │ │ └── templates │ │ │ ├── config │ │ │ ├── crd │ │ │ │ ├── crd.go │ │ │ │ └── kustomization.go │ │ │ ├── rbac │ │ │ │ └── role.go │ │ │ └── testing │ │ │ │ ├── debug_logs_patch.go │ │ │ │ ├── kustomization.go │ │ │ │ ├── manager_image.go │ │ │ │ └── pullpolicy │ │ │ │ ├── always_pull_patch.go │ │ │ │ ├── ifnotpresent_pull_patch.go │ │ │ │ └── never_pull_patch.go │ │ │ ├── dockerfile.go │ │ │ ├── gitignore.go │ │ │ ├── makefile.go │ │ │ ├── molecule │ │ │ ├── mdefault │ │ │ │ ├── converge.go │ │ │ │ ├── create.go │ │ │ │ ├── destroy.go │ │ │ │ ├── kustomize.go │ │ │ │ ├── molecule.go │ │ │ │ ├── prepare.go │ │ │ │ ├── tasks_test_resource.go │ │ │ │ └── verify.go │ │ │ └── mkind │ │ │ │ ├── converge.go │ │ │ │ ├── create.go │ │ │ │ ├── destroy.go │ │ │ │ └── molecule.go │ │ │ ├── playbooks │ │ │ ├── placeholder.go │ │ │ └── playbook.go │ │ │ ├── requirements.go │ │ │ ├── roles │ │ │ ├── defaults_main.go │ │ │ ├── files_dir.go │ │ │ ├── handlers_main.go │ │ │ ├── meta_main.go │ │ │ ├── placeholder.go │ │ │ ├── readme.go │ │ │ ├── tasks_main.go │ │ │ ├── templates_dir.go │ │ │ └── vars_main.go │ │ │ └── watches.go │ ├── plugins.go │ └── util │ │ ├── cleanup.go │ │ └── message.go └── testutils │ ├── command │ └── command.go │ ├── e2e │ ├── certmanager │ │ └── helpers.go │ ├── helpers.go │ ├── kind │ │ └── helpers.go │ ├── metrics │ │ └── helpers.go │ ├── operator │ │ └── helpers.go │ └── prometheus │ │ └── helpers.go │ ├── kubernetes │ ├── kubectl.go │ └── version.go │ └── sample │ ├── cli │ └── cli.go │ ├── generator.go │ └── sample.go ├── test ├── common │ └── sa_secret.go └── e2e │ └── ansible │ ├── cluster_test.go │ ├── local_test.go │ └── suite_test.go ├── testdata └── memcached-molecule-operator │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── PROJECT │ ├── config │ ├── crd │ │ ├── bases │ │ │ ├── cache.example.com_foos.yaml │ │ │ ├── cache.example.com_memcacheds.yaml │ │ │ ├── cache.example.com_memfins.yaml │ │ │ └── ignore.example.com_secrets.yaml │ │ └── kustomization.yaml │ ├── default │ │ ├── kustomization.yaml │ │ ├── manager_metrics_patch.yaml │ │ └── metrics_service.yaml │ ├── manager │ │ ├── kustomization.yaml │ │ └── manager.yaml │ ├── network-policy │ │ ├── allow-metrics-traffic.yaml │ │ └── kustomization.yaml │ ├── prometheus │ │ ├── kustomization.yaml │ │ └── monitor.yaml │ ├── rbac │ │ ├── foo_admin_role.yaml │ │ ├── foo_editor_role.yaml │ │ ├── foo_viewer_role.yaml │ │ ├── ignore_secret_admin_role.yaml │ │ ├── ignore_secret_editor_role.yaml │ │ ├── ignore_secret_viewer_role.yaml │ │ ├── kustomization.yaml │ │ ├── leader_election_role.yaml │ │ ├── leader_election_role_binding.yaml │ │ ├── memcached_admin_role.yaml │ │ ├── memcached_editor_role.yaml │ │ ├── memcached_viewer_role.yaml │ │ ├── memfin_admin_role.yaml │ │ ├── memfin_editor_role.yaml │ │ ├── memfin_viewer_role.yaml │ │ ├── metrics_auth_role.yaml │ │ ├── metrics_auth_role_binding.yaml │ │ ├── metrics_reader_role.yaml │ │ ├── role.yaml │ │ ├── role_binding.yaml │ │ └── service_account.yaml │ ├── samples │ │ ├── cache_v1alpha1_foo.yaml │ │ ├── cache_v1alpha1_memcached.yaml │ │ ├── cache_v1alpha1_memfin.yaml │ │ ├── ignore_v1_secret.yaml │ │ └── kustomization.yaml │ └── testing │ │ ├── debug_logs_patch.yaml │ │ ├── kustomization.yaml │ │ ├── manager_image.yaml │ │ ├── pull_policy │ │ ├── Always.yaml │ │ ├── IfNotPresent.yaml │ │ └── Never.yaml │ │ └── watch_namespace_patch.yaml │ ├── molecule │ ├── default │ │ ├── converge.yml │ │ ├── create.yml │ │ ├── destroy.yml │ │ ├── kustomize.yml │ │ ├── molecule.yml │ │ ├── prepare.yml │ │ ├── tasks │ │ │ ├── foo_test.yml │ │ │ ├── memcached_test.yml │ │ │ └── memfin_test.yml │ │ └── verify.yml │ └── kind │ │ ├── converge.yml │ │ ├── create.yml │ │ ├── destroy.yml │ │ └── molecule.yml │ ├── playbooks │ ├── .placeholder │ ├── foo.yml │ ├── memcached.yml │ └── memfin.yml │ ├── requirements.yml │ ├── roles │ ├── .placeholder │ ├── foo │ │ ├── README.md │ │ ├── defaults │ │ │ └── main.yml │ │ ├── files │ │ │ └── .placeholder │ │ ├── handlers │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ ├── templates │ │ │ └── .placeholder │ │ └── vars │ │ │ └── main.yml │ ├── memcached │ │ ├── README.md │ │ ├── defaults │ │ │ └── main.yml │ │ ├── files │ │ │ └── .placeholder │ │ ├── handlers │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ ├── templates │ │ │ └── .placeholder │ │ └── vars │ │ │ └── main.yml │ ├── memfin │ │ ├── README.md │ │ ├── defaults │ │ │ └── main.yml │ │ ├── files │ │ │ └── .placeholder │ │ ├── handlers │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ ├── templates │ │ │ └── .placeholder │ │ └── vars │ │ │ └── main.yml │ └── secret │ │ ├── README.md │ │ ├── defaults │ │ └── main.yml │ │ ├── files │ │ └── .placeholder │ │ ├── handlers │ │ └── main.yml │ │ ├── meta │ │ └── main.yml │ │ ├── tasks │ │ └── main.yml │ │ ├── templates │ │ └── .placeholder │ │ └── vars │ │ └── main.yml │ └── watches.yaml └── tools ├── scripts └── fetch └── tools.go /.bingo/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Ignore everything 3 | * 4 | 5 | # But not these files: 6 | !.gitignore 7 | !*.mod 8 | !*.sum 9 | !README.md 10 | !Variables.mk 11 | !variables.env 12 | 13 | *tmp.mod 14 | -------------------------------------------------------------------------------- /.bingo/README.md: -------------------------------------------------------------------------------- 1 | # Project Development Dependencies. 2 | 3 | This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo. 4 | 5 | * Run `bingo get` to install all tools having each own module file in this directory. 6 | * Run `bingo get ` to install that have own module file in this directory. 7 | * For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $() variable where is the .bingo/.mod. 8 | * For shell: Run `source .bingo/variables.env` to source all environment variable for each tool. 9 | * For go: Import `.bingo/variables.go` to for variable names. 10 | * See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies. 11 | 12 | ## Requirements 13 | 14 | * Go 1.14+ 15 | -------------------------------------------------------------------------------- /.bingo/bingo.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.21.3 4 | 5 | require github.com/bwplotka/bingo v0.9.0 6 | -------------------------------------------------------------------------------- /.bingo/go.mod: -------------------------------------------------------------------------------- 1 | module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files. -------------------------------------------------------------------------------- /.bingo/golangci-lint.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.22.1 4 | 5 | toolchain go1.22.5 6 | 7 | require github.com/golangci/golangci-lint v1.62.2 // cmd/golangci-lint 8 | -------------------------------------------------------------------------------- /.bingo/goreleaser.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.21.3 4 | 5 | require github.com/goreleaser/goreleaser v1.16.2 6 | -------------------------------------------------------------------------------- /.bingo/kind.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.21.3 4 | 5 | require sigs.k8s.io/kind v0.24.0 6 | -------------------------------------------------------------------------------- /.bingo/setup-envtest.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.8 6 | 7 | require sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20241019152504-013f46fbca88 8 | -------------------------------------------------------------------------------- /.bingo/variables.env: -------------------------------------------------------------------------------- 1 | # Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT. 2 | # All tools are designed to be build inside $GOBIN. 3 | # Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk. 4 | GOBIN=${GOBIN:=$(go env GOBIN)} 5 | 6 | if [ -z "$GOBIN" ]; then 7 | GOBIN="$(go env GOPATH)/bin" 8 | fi 9 | 10 | 11 | BINGO="${GOBIN}/bingo-v0.9.0" 12 | 13 | GOLANGCI_LINT="${GOBIN}/golangci-lint-v1.62.2" 14 | 15 | GORELEASER="${GOBIN}/goreleaser-v1.16.2" 16 | 17 | KIND="${GOBIN}/kind-v0.24.0" 18 | 19 | SETUP_ENVTEST="${GOBIN}/setup-envtest-v0.0.0-20241019152504-013f46fbca88" 20 | 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: If things aren't working as expected. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Bug Report 11 | 12 | 18 | 19 | #### What did you do? 20 | 21 | 22 | 23 | #### What did you expect to see? 24 | 25 | 26 | 27 | #### What did you see instead? Under which circumstances? 28 | 29 | 30 | 31 | #### Environment 32 | 33 | **Kubernetes cluster type:** 34 | 35 | 36 | 37 | `$ operator-sdk version` 38 | 39 | 40 | 41 | `$ go version` (if language is Go) 42 | 43 | 44 | 45 | `$ kubectl version` 46 | 47 | 48 | 49 | #### Possible Solution 50 | 51 | 52 | 53 | #### Additional context 54 | 55 | 56 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/doc-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Doc Report 3 | about: Raise an issue with the documentation. 4 | title: '' 5 | labels: kind/documentation 6 | assignees: '' 7 | 8 | --- 9 | 10 | 13 | 14 | ### What is the URL of the document? 15 | 16 | 17 | 18 | ### Which section(s) is the issue in? 19 | 20 | 21 | 22 | ### What needs fixing? 23 | 24 | 25 | 26 | #### Additional context 27 | 28 | 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest a feature 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Feature Request 11 | 12 | #### Describe the problem you need a feature to resolve. 13 | 14 | 19 | 20 | #### Describe the solution you'd like. 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support Question 3 | about: Any support questions you might have. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 17 | 18 | ## Type of question 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ## Question 28 | 29 | #### What did you do? 30 | 31 | 32 | 33 | #### What did you expect to see? 34 | 35 | 36 | 37 | #### What did you see instead? Under which circumstances? 38 | 39 | 40 | 41 | #### Environment 42 | 43 | **Kubernetes cluster type:** 44 | 45 | 46 | 47 | `$ operator-sdk version` 48 | 49 | 50 | 51 | `$ go version` (if language is Go) 52 | 53 | 54 | 55 | `$ kubectl version` 56 | 57 | 58 | 59 | #### Additional context 60 | 61 | 62 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 14 | 15 | **Description of the change:** 16 | 17 | 18 | **Motivation for the change:** 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/test-ansible.yml: -------------------------------------------------------------------------------- 1 | name: ansible 2 | on: 3 | pull_request: {} 4 | 5 | jobs: 6 | e2e: 7 | name: e2e 8 | runs-on: ubuntu-22.04 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | fetch-depth: 0 13 | - uses: actions/setup-go@v5 14 | with: 15 | go-version-file: "go.mod" 16 | - run: sudo rm -rf /usr/local/bin/kustomize 17 | - run: make test-e2e-ansible 18 | 19 | e2e-molecule: 20 | name: e2e-molecule 21 | runs-on: ubuntu-22.04 22 | steps: 23 | - uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 0 26 | - uses: actions/setup-go@v5 27 | with: 28 | go-version-file: "go.mod" 29 | - run: sudo rm -rf /usr/local/bin/kustomize 30 | - uses: actions/setup-python@v5 31 | with: 32 | python-version: '3.12' 33 | - name: Run test e2e ansible molecule 34 | run: | 35 | env 36 | pip3 install --user --upgrade setuptools pip 37 | pip3 install --user ansible-core~=2.17.4 38 | make test-e2e-ansible-molecule 39 | -------------------------------------------------------------------------------- /.github/workflows/test-sanity.yml: -------------------------------------------------------------------------------- 1 | name: sanity 2 | on: 3 | pull_request: {} 4 | 5 | jobs: 6 | sanity: 7 | name: sanity 8 | runs-on: ubuntu-22.04 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | fetch-depth: 0 13 | - uses: actions/setup-go@v5 14 | with: 15 | go-version-file: "go.mod" 16 | id: go 17 | - run: sudo rm -rf /usr/local/bin/kustomize 18 | - run: make test-sanity 19 | -------------------------------------------------------------------------------- /.github/workflows/unit.yml: -------------------------------------------------------------------------------- 1 | name: unit 2 | on: 3 | pull_request: {} 4 | 5 | jobs: 6 | unit: 7 | name: unit 8 | runs-on: ubuntu-22.04 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | fetch-depth: 0 13 | - uses: actions/setup-go@v5 14 | with: 15 | go-version-file: "go.mod" 16 | - run: make test-unit 17 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - sdk-admins 3 | - sdk-approvers 4 | reviewers: 5 | - sdk-admins 6 | - sdk-approvers 7 | - sdk-reviewers 8 | -------------------------------------------------------------------------------- /OWNERS_ALIASES: -------------------------------------------------------------------------------- 1 | 2 | # See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md 3 | 4 | aliases: 5 | # Contributors who can be contacted to perform admin-related tasks on the repo. 6 | # This role is a subset of the approver role. 7 | sdk-admins: 8 | - joelanford 9 | - everettraven 10 | - oceanc80 11 | 12 | # Contributors who can approve any PRs in the repo. 13 | sdk-approvers: 14 | - fabianvf 15 | - jberkhahn 16 | - rashmigottipati 17 | - theishshah 18 | - varshaprasad96 19 | - grokspawn 20 | - anik120 21 | 22 | # Contributors who can review and LGTM any PRs in the repo. 23 | sdk-reviewers: 24 | 25 | # Contributors who were approvers that are no longer directly involved with the project. 26 | # This role is symbolic. 27 | sdk-emeritus-approvers: 28 | - bharathi-tenneti 29 | - hasbro17 30 | - shawn-hurley 31 | - estroz 32 | - camilamacedo86 33 | - marc-obrien 34 | - asmacdo 35 | - jmrodri 36 | -------------------------------------------------------------------------------- /cmd/ansible-operator/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "log" 19 | 20 | "github.com/spf13/cobra" 21 | _ "k8s.io/client-go/plugin/pkg/client/auth" 22 | 23 | "github.com/operator-framework/ansible-operator-plugins/internal/cmd/ansible-operator/run" 24 | "github.com/operator-framework/ansible-operator-plugins/internal/cmd/ansible-operator/version" 25 | ) 26 | 27 | func main() { 28 | root := cobra.Command{ 29 | Short: "Reconcile an Ansible operator project using ansible-runner", 30 | Long: `This binary runs an Ansible operator that reconciles Kubernetes resources 31 | managed by the ansible-runner program. It can be run either directly or from an Ansible 32 | operator project's image entrypoint 33 | `, 34 | Use: "ansible-operator", 35 | } 36 | 37 | root.AddCommand(run.NewCmd()) 38 | root.AddCommand(version.NewCmd()) 39 | 40 | if err := root.Execute(); err != nil { 41 | log.Fatal(err) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /hack/check-error-log-msg-format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o nounset 4 | set -o pipefail 5 | 6 | source "hack/lib/common.sh" 7 | 8 | echo "Checking format of error and log messages..." 9 | allfiles=$(listFiles|grep -v ./internal/bindata/...) 10 | log_case_output=$(grep -PRn '(Error\((.*[Ee]rr|nil), |^(?!.*(fmt|errors)).+\.Error(f)?\(|Fatal(f)?\(|Info(f)?\(|Warn(f)?\()"[[:lower:]]' $allfiles | sort -u) 11 | if [ -n "${log_case_output}" ]; then 12 | echo -e "Log messages do not begin with upper case:\n${log_case_output}" 13 | fi 14 | err_case_output=$(grep -ERn '(errors\.New|fmt\.Errorf)\("[[:upper:]]' $allfiles | sort -u) 15 | if [ -n "${err_case_output}" ]; then 16 | echo -e "Error messages do not begin with lower case:\n${err_case_output}" 17 | fi 18 | err_punct_output=$(grep -ERn '(errors\.New|fmt\.Errorf)\(".*\."' $allfiles | sort -u) 19 | if [ -n "${err_punct_output}" ]; then 20 | echo -e "Error messages should not have ending punctuation:\n${err_punct_output}" 21 | fi 22 | 23 | if [[ -n "$log_case_output" || -n "$err_case_output" || -n "$err_punct_output" ]]; then 24 | exit 255 25 | fi 26 | -------------------------------------------------------------------------------- /hack/check-license.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | set -o pipefail 6 | 7 | source "hack/lib/common.sh" 8 | 9 | echo "Checking for license header..." 10 | allfiles=$(listFiles|grep -v ./internal/bindata/...) 11 | licRes="" 12 | for file in $allfiles; do 13 | if ! head -n3 "${file}" | grep -Eq "(Copyright|generated|GENERATED|Licensed)" ; then 14 | licRes="${licRes}\n"$(echo -e " ${file}") 15 | fi 16 | done 17 | if [ -n "${licRes}" ]; then 18 | echo -e "license header checking failed:\n${licRes}" 19 | exit 255 20 | fi 21 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | inventory_plugins = /opt/ansible/plugins/inventory 3 | stdout_callback = yaml 4 | callback_whitelist = profile_tasks,timer 5 | module_utils = /opt/ansible/module_utils 6 | roles_path = /opt/ansible/roles 7 | library = /opt/ansible/library 8 | inventory = /opt/ansible/inventory 9 | filter_plugins = /opt/ansible/plugins/filter 10 | remote_tmp = /tmp/ansible 11 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/fixture_collection/galaxy.yml: -------------------------------------------------------------------------------- 1 | namespace: operator_sdk 2 | name: test_fixtures 3 | version: 0.0.0 4 | readme: README.md 5 | authors: 6 | - your name 7 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/fixture_collection/roles/dummy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create ConfigMap 3 | kubernetes.core.k8s: 4 | definition: 5 | kind: ConfigMap 6 | apiVersion: v1 7 | metadata: 8 | name: test-this-collection 9 | namespace: "{{ meta.namespace }}" 10 | data: 11 | did_it_work: "indeed" 12 | state: present 13 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/inventory/group_vars/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | sentinel: test 4 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/inventory/hosts: -------------------------------------------------------------------------------- 1 | [test] 2 | 127.0.0.1 ansible_connection=local 3 | 4 | [all:vars] 5 | ansible_python_interpreter=/usr/local/bin/python3 -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/playbooks/finalizerconcurrencyfinalizer.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | collections: 5 | - kubernetes.core 6 | - operator_sdk.util 7 | 8 | tasks: 9 | - debug: 10 | msg: "Pausing until configmap exists" 11 | 12 | - name: Wait for configmap 13 | k8s_info: 14 | api_version: v1 15 | kind: ConfigMap 16 | name: finalizer-concurrency-results 17 | namespace: osdk-test 18 | wait: yes 19 | wait_sleep: 10 20 | wait_timeout: 30 21 | 22 | - name: Update configmap 23 | k8s: 24 | state: present 25 | force: yes 26 | definition: 27 | apiVersion: v1 28 | kind: ConfigMap 29 | metadata: 30 | name: finalizer-concurrency-results 31 | namespace: osdk-test 32 | data: 33 | finalizer: "success" 34 | wait: yes 35 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/plugins/filter/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from __future__ import (absolute_import, division, print_function) 4 | __metaclass__ = type 5 | 6 | 7 | def test(sentinel): 8 | return sentinel == 'test' 9 | 10 | 11 | class FilterModule(object): 12 | ''' Fake test plugin for ansible-operator ''' 13 | 14 | def filters(self): 15 | return { 16 | 'test': test 17 | } 18 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/secret.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | collections: 5 | - kubernetes.core 6 | 7 | tasks: 8 | - meta: end_play 9 | when: not (__secret.metadata.get('labels', {}).reconcile|default(false)|bool) 10 | 11 | # This is for testing, but never do this with real secrets 12 | - name: Populate configmap with contents of secret 13 | k8s: 14 | definition: | 15 | apiVersion: v1 16 | kind: ConfigMap 17 | metadata: 18 | name: '{{ meta.name }}' 19 | namespace: '{{ meta.namespace }}' 20 | data: 21 | '{{ item.key }}': '{{ item.value | b64decode }}' 22 | with_dict: '{{ __secret.data }}' 23 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/argstest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.ArgsTest 3 | k8s: 4 | state: present 5 | definition: 6 | apiVersion: test.example.com/v1alpha1 7 | kind: ArgsTest 8 | metadata: 9 | name: args-test 10 | namespace: '{{ namespace }}' 11 | spec: 12 | field: value 13 | wait: yes 14 | wait_timeout: 300 15 | wait_condition: 16 | type: Successful 17 | status: "True" 18 | register: args_test 19 | 20 | - name: Assert sentinel ConfigMap has been created for Molecule Test 21 | assert: 22 | that: cm.data.msg == "The decrypted value is thisisatest" 23 | vars: 24 | cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace, 25 | resource_name='args-test').0 }}" 26 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/casetest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.CaseTest 3 | k8s: 4 | state: present 5 | definition: 6 | apiVersion: test.example.com/v1alpha1 7 | kind: CaseTest 8 | metadata: 9 | name: case-test 10 | namespace: '{{ namespace }}' 11 | spec: 12 | camelCaseVar: "true" 13 | wait: yes 14 | wait_timeout: 300 15 | wait_condition: 16 | type: Successful 17 | status: "True" 18 | register: case_test 19 | 20 | - name: Assert sentinel ConfigMap has been created for Molecule Test 21 | assert: 22 | that: cm.data.shouldBeCamel == 'true' 23 | vars: 24 | cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace, resource_name='case-test').0 }}" 25 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/clusterannotationtest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.ClusterAnnotationTest 3 | k8s: 4 | state: present 5 | namespace: '{{ namespace }}' 6 | definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}" 7 | wait: yes 8 | wait_timeout: 300 9 | wait_condition: 10 | type: Successful 11 | status: "True" 12 | vars: 13 | cr_file: 'test_v1alpha1_clusterannotationtest.yaml' 14 | 15 | - name: retrieve configmap 16 | k8s_info: 17 | api_version: v1 18 | kind: ConfigMap 19 | namespace: "externalnamespace" 20 | name: "clusterannotationtest-sample" 21 | register: configmap 22 | until: (configmap.resources | length) == 1 23 | 24 | - assert: 25 | that: 26 | - configmap.resources[0].metadata.annotations["operator-sdk/primary-resource"] == primary 27 | - configmap.resources[0].metadata.annotations["operator-sdk/primary-resource-type"] == primary_type 28 | vars: 29 | primary: "osdk-test/clusterannotationtest-sample" 30 | primary_type: "ClusterAnnotationTest.test.example.com" 31 | 32 | - name: change the namespace labels 33 | k8s: 34 | name: "externalnamespace" 35 | api_version: v1 36 | kind: "Namespace" 37 | wait: yes 38 | definition: 39 | metadata: 40 | labels: 41 | foo: baz 42 | 43 | - name: Make sure the label is changed back 44 | k8s_info: 45 | api_version: v1 46 | kind: Namespace 47 | name: "externalnamespace" 48 | register: external_namespace 49 | until: external_namespace.resources[0].metadata.labels["foo"] == "bar" 50 | retries: 6 51 | 52 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/collectiontest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.CollectionTest 3 | k8s: 4 | state: present 5 | namespace: '{{ namespace }}' 6 | definition: 7 | apiVersion: test.example.com/v1alpha1 8 | kind: CollectionTest 9 | metadata: 10 | name: collection-test 11 | wait: yes 12 | wait_timeout: 300 13 | wait_condition: 14 | type: Successful 15 | status: "True" 16 | 17 | - name: Assert ConfigMap has been created by collection Role 18 | assert: 19 | that: cm.data.did_it_work == 'indeed' 20 | vars: 21 | cm: "{{ q('k8s', 22 | api_version='v1', 23 | kind='ConfigMap', 24 | namespace=namespace, 25 | resource_name='test-this-collection' 26 | ).0 }}" 27 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/finalizerconcurrencytest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # TODO(asmacdo) this should be the only task. the other is getting magiced in 3 | - name: Create the test.example.com/v1alpha1.FinalizerConcurrencyTest 4 | k8s: 5 | state: present 6 | definition: 7 | apiVersion: test.example.com/v1alpha1 8 | kind: FinalizerConcurrencyTest 9 | metadata: 10 | name: finalizer-concurrency-test 11 | namespace: '{{ namespace }}' 12 | wait: no 13 | 14 | - name: While reconcile is paused, delete the CR 15 | k8s: 16 | state: absent 17 | definition: 18 | apiVersion: test.example.com/v1alpha1 19 | kind: FinalizerConcurrencyTest 20 | metadata: 21 | name: finalizer-concurrency-test 22 | namespace: '{{ namespace }}' 23 | wait: no 24 | 25 | - name: Create a configmap to allow reconciliation to unpause 26 | k8s: 27 | state: present 28 | definition: 29 | apiVersion: v1 30 | kind: ConfigMap 31 | metadata: 32 | name: finalizer-concurrency-results 33 | namespace: osdk-test 34 | wait: no 35 | 36 | - name: Wait for the custom resource to be deleted 37 | k8s_info: 38 | api_version: test.example.com/v1alpha1 39 | kind: FinalizerConcurrencyTest 40 | namespace: osdk-test # TODO(asmacdo) Fixme 41 | name: finalizer-concurrency-test 42 | register: cr 43 | retries: 10 44 | delay: 6 45 | until: not cr.resources 46 | failed_when: cr.resources 47 | 48 | - name: Retrive the cm 49 | k8s_info: 50 | api_version: v1 51 | kind: ConfigMap 52 | name: finalizer-concurrency-results 53 | namespace: osdk-test 54 | register: finalizer_test 55 | 56 | - name: Assert that finalizer ran 57 | assert: 58 | that: finalizer_test.resources.0.data.finalizer== 'success' 59 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/inventorytest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.InventoryTest 3 | k8s: 4 | state: present 5 | namespace: '{{ namespace }}' 6 | definition: '{{ custom_resource }}' 7 | wait: yes 8 | wait_timeout: 300 9 | wait_condition: 10 | type: Successful 11 | status: "True" 12 | vars: 13 | custom_resource: "{{ lookup('template', '/'.join([ 14 | config_dir, 15 | 'samples/test_v1alpha1_inventorytest.yaml' 16 | ])) | from_yaml }}" 17 | 18 | - name: Assert sentinel ConfigMap has been created for Molecule Test 19 | assert: 20 | that: cm.data.sentinel == 'test' 21 | vars: 22 | cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace, resource_name='inventory-cm').0 }}" 23 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/reconciliationtest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.ReconciliationTest 3 | k8s: 4 | state: present 5 | definition: 6 | apiVersion: test.example.com/v1alpha1 7 | kind: ReconciliationTest 8 | metadata: 9 | name: reconciliation-test 10 | namespace: '{{ namespace }}' 11 | spec: 12 | field: value 13 | wait: yes 14 | wait_timeout: 300 15 | wait_condition: 16 | type: Successful 17 | status: "True" 18 | register: reconciliation_test 19 | - name: Retreive the number of iterations on the ConfigMap 20 | debug: var=cm.data.iterations 21 | retries: 20 22 | delay: 2 23 | until: "cm.data.iterations|int == 5" 24 | vars: 25 | cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace, 26 | resource_name='reconciliation-test').0 }}" 27 | - name: Assert sentinel ConfigMap has been created for Molecule Test 28 | assert: 29 | that: "cm.data.iterations|int == 5" 30 | vars: 31 | cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace, 32 | resource_name='reconciliation-test').0 }}" 33 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/secretstest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the v1.Secret 3 | k8s: 4 | state: present 5 | definition: 6 | apiVersion: v1 7 | kind: Secret 8 | metadata: 9 | name: test-secret 10 | namespace: '{{ namespace }}' 11 | labels: 12 | reconcile: "yes" 13 | data: 14 | test: '{{ "test" | b64encode }}' 15 | 16 | - name: Wait for the corresponding configmap to be created 17 | k8s_info: 18 | api_version: v1 19 | kind: ConfigMap 20 | name: test-secret 21 | namespace: '{{ namespace }}' 22 | register: result 23 | until: result.resources 24 | retries: 20 25 | 26 | - name: Assert that the configmap has the proper content 27 | assert: 28 | that: result.resources.0.data.test == "test" 29 | 30 | - name: Update the v1.Secret 31 | k8s: 32 | state: present 33 | definition: 34 | apiVersion: v1 35 | kind: Secret 36 | metadata: 37 | name: test-secret 38 | namespace: '{{ namespace }}' 39 | labels: 40 | reconcile: "yes" 41 | data: 42 | new: '{{ "content" | b64encode }}' 43 | 44 | - name: Wait for the corresponding key to be created 45 | k8s_info: 46 | api_version: v1 47 | kind: ConfigMap 48 | name: test-secret 49 | namespace: '{{ namespace }}' 50 | register: result 51 | until: result.resources.0.data.new is defined 52 | retries: 20 53 | 54 | - name: Assert that the configmap has the proper content 55 | assert: 56 | that: result.resources.0.data.new == 'content' 57 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/selectortest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.SelectorTest 3 | k8s: 4 | state: present 5 | definition: 6 | apiVersion: test.example.com/v1alpha1 7 | kind: SelectorTest 8 | metadata: 9 | name: selector-test 10 | namespace: '{{ namespace }}' 11 | labels: 12 | testLabel: testValue 13 | spec: 14 | field: value 15 | wait: yes 16 | wait_timeout: 300 17 | wait_condition: 18 | type: Successful 19 | status: "True" 20 | register: selector_test 21 | 22 | - name: Assert sentinel ConfigMap has been created for Molecule Test 23 | assert: 24 | that: cm.data.hello == 'world' 25 | vars: 26 | cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace, 27 | resource_name='selector-test').0 }}" 28 | 29 | - name: Create the test.example.com/v1alpha1.SelectorTest 30 | k8s: 31 | state: present 32 | definition: 33 | apiVersion: test.example.com/v1alpha1 34 | kind: SelectorTest 35 | metadata: 36 | name: selector-test-fail 37 | namespace: '{{ namespace }}' 38 | spec: 39 | field: value 40 | register: selector_test 41 | 42 | - name: Wait for 30 seconds 43 | wait_for: 44 | timeout: 30 45 | 46 | - name: Assert sentinel ConfigMap has not been created for Molecule Test 47 | assert: 48 | that: not cm 49 | vars: 50 | cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace, 51 | resource_name='selector-test-fail')}}" 52 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/tasks/subresourcestest_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the test.example.com/v1alpha1.SubresourcesTest 3 | k8s: 4 | state: present 5 | definition: 6 | apiVersion: test.example.com/v1alpha1 7 | kind: SubresourcesTest 8 | metadata: 9 | name: subresources-test 10 | namespace: '{{ namespace }}' 11 | spec: 12 | execCommand: "echo 'hello world'" 13 | logMessage: "Running..." 14 | wait: yes 15 | wait_timeout: 300 16 | wait_condition: 17 | type: Successful 18 | status: "True" 19 | register: subresources_test 20 | 21 | - name: Assert stdout and stderr are properly set in status 22 | assert: 23 | that: 24 | - subresources_test.result.status.execCommandStderr == "" 25 | - subresources_test.result.status.execCommandStdout == "hello world" 26 | - "'Running' in subresources_test.result.status.logs" 27 | -------------------------------------------------------------------------------- /hack/generate/samples/ansible/testdata/watches.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Use the 'create api' subcommand to add watches to this file. 3 | - version: v1alpha1 4 | group: test.example.com 5 | kind: InventoryTest 6 | playbook: playbooks/inventorytest.yml 7 | vars: 8 | meta: '{{ ansible_operator_meta }}' 9 | 10 | - version: v1alpha1 11 | group: test.example.com 12 | kind: CollectionTest 13 | role: operator_sdk.test_fixtures.dummy 14 | vars: 15 | meta: '{{ ansible_operator_meta }}' 16 | 17 | - version: v1alpha1 18 | group: test.example.com 19 | kind: SubresourcesTest 20 | playbook: playbooks/subresourcestest.yml 21 | vars: 22 | meta: '{{ ansible_operator_meta }}' 23 | 24 | - version: v1 25 | group: "" 26 | kind: Secret 27 | playbook: playbooks/secret.yml 28 | manageStatus: false 29 | selector: 30 | matchExpressions: 31 | - {key: reconcile, operator: Exists, values: []} 32 | vars: 33 | meta: '{{ ansible_operator_meta }}' 34 | 35 | - version: v1alpha1 36 | group: test.example.com 37 | kind: SelectorTest 38 | playbook: playbooks/selectortest.yml 39 | selector: 40 | matchExpressions: 41 | - {key: testLabel, operator: Exists, values: []} 42 | vars: 43 | meta: '{{ ansible_operator_meta }}' 44 | 45 | - version: v1alpha1 46 | group: test.example.com 47 | kind: CaseTest 48 | playbook: playbooks/casetest.yml 49 | snakeCaseParameters: false 50 | vars: 51 | meta: '{{ ansible_operator_meta }}' 52 | 53 | - version: v1alpha1 54 | group: test.example.com 55 | kind: ArgsTest 56 | playbook: playbooks/argstest.yml 57 | vars: 58 | meta: '{{ ansible_operator_meta }}' 59 | 60 | - version: v1alpha1 61 | group: test.example.com 62 | kind: ReconciliationTest 63 | playbook: playbooks/reconciliationtest.yml 64 | vars: 65 | meta: '{{ ansible_operator_meta }}' 66 | 67 | - version: v1alpha1 68 | group: test.example.com 69 | kind: ClusterAnnotationTest 70 | playbook: playbooks/clusterannotationtest.yml 71 | watchClusterScopedResources: true 72 | vars: 73 | meta: '{{ ansible_operator_meta }}' 74 | 75 | - version: v1alpha1 76 | group: test.example.com 77 | kind: FinalizerConcurrencyTest 78 | playbook: playbooks/finalizerconcurrencytest.yml 79 | finalizer: 80 | name: test.example.com/finalizer 81 | playbook: playbooks/finalizerconcurrencyfinalizer.yml 82 | vars: 83 | meta: '{{ ansible_operator_meta }}' 84 | #+kubebuilder:scaffold:watch 85 | -------------------------------------------------------------------------------- /hack/generate/samples/generate_testdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "flag" 19 | "os" 20 | "path/filepath" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/hack/generate/samples/ansible" 23 | 24 | log "github.com/sirupsen/logrus" 25 | 26 | "github.com/operator-framework/ansible-operator-plugins/internal/testutils" 27 | ) 28 | 29 | func main() { 30 | // binaryPath allow inform the binary that should be used. 31 | // By default it is operator-sdk 32 | var binaryPath string 33 | 34 | flag.StringVar(&binaryPath, "bin", testutils.BinaryName, "Binary path that should be used") 35 | flag.Parse() 36 | 37 | // Make the binary path absolute if pathed, for reproducibility and debugging purposes. 38 | if dir, _ := filepath.Split(binaryPath); dir != "" { 39 | tmp, err := filepath.Abs(binaryPath) 40 | if err != nil { 41 | log.Fatalf("Failed to make binary path %q absolute: %v", binaryPath, err) 42 | } 43 | binaryPath = tmp 44 | } 45 | 46 | wd, err := os.Getwd() 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | 51 | // samplesPath is the path where all samples should be generated 52 | samplesPath := filepath.Join(wd, "testdata") 53 | log.Infof("writing sample directories under %s", samplesPath) 54 | 55 | log.Infof("creating Ansible Memcached Sample") 56 | ansible.GenerateMoleculeSample(samplesPath) 57 | } 58 | -------------------------------------------------------------------------------- /hack/generate/samples/internal/pkg/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pkg 16 | 17 | import ( 18 | "github.com/operator-framework/ansible-operator-plugins/internal/testutils" 19 | ) 20 | 21 | // SampleContext represents the Context used to generate the samples 22 | type SampleContext struct { 23 | testutils.TestContext 24 | } 25 | 26 | // NewSampleContext returns a SampleContext containing a new kubebuilder TestContext. 27 | func NewSampleContext(binary string, path string, env ...string) (s SampleContext, err error) { 28 | s.TestContext, err = testutils.NewPartialTestContext(binary, path, env...) 29 | return s, err 30 | } 31 | -------------------------------------------------------------------------------- /hack/lib/common.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Turn colors in this script off by setting the NO_COLOR variable in your 4 | # environment to any value: 5 | NO_COLOR=${NO_COLOR:-""} 6 | if [ -z "$NO_COLOR" ]; then 7 | header_color=$'\e[1;33m' 8 | error_color=$'\e[0;31m' 9 | reset_color=$'\e[0m' 10 | else 11 | header_color='' 12 | error_color='' 13 | reset_color='' 14 | fi 15 | 16 | function log() { printf '%s\n' "$*"; } 17 | function error() { error_text "ERROR:" $* >&2; } 18 | function fatal() { error "$@"; exit 1; } 19 | 20 | function header_text { 21 | echo "$header_color$*$reset_color" 22 | } 23 | 24 | function error_text { 25 | echo "$error_color$*$reset_color" 26 | } 27 | 28 | #=================================================================== 29 | # FUNCTION trap_add () 30 | # 31 | # Purpose: prepends a command to a trap 32 | # 33 | # - 1st arg: code to add 34 | # - remaining args: names of traps to modify 35 | # 36 | # Example: trap_add 'echo "in trap DEBUG"' DEBUG 37 | # 38 | # See: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal 39 | #=================================================================== 40 | function trap_add() { 41 | trap_add_cmd=$1; shift || fatal "${FUNCNAME} usage error" 42 | new_cmd= 43 | for trap_add_name in "$@"; do 44 | # Grab the currently defined trap commands for this trap 45 | existing_cmd=`trap -p "${trap_add_name}" | awk -F"'" '{print $2}'` 46 | 47 | # Define default command 48 | [ -z "${existing_cmd}" ] && existing_cmd="echo exiting @ `date`" 49 | 50 | # Generate the new command 51 | new_cmd="${trap_add_cmd};${existing_cmd}" 52 | 53 | # Assign the test 54 | trap "${new_cmd}" "${trap_add_name}" || \ 55 | fatal "unable to add to trap ${trap_add_name}" 56 | done 57 | } 58 | 59 | function listPkgDirs() { 60 | go list -f '{{.Dir}}' ./cmd/... ./test/... ./internal/... | grep -v generated 61 | } 62 | 63 | function listFiles() { 64 | # pipeline is much faster than for loop 65 | listPkgDirs | xargs -I {} find {} -name '*.go' | grep -v generated 66 | } 67 | -------------------------------------------------------------------------------- /images/ansible-operator/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | ansible-runner = "~=2.4.0" 8 | ansible-runner-http = "~=1.0.0" 9 | ansible-core = "~=2.18.3" 10 | urllib3 = "~=1.26.2" 11 | kubernetes = "==32.0.0" 12 | requests = "~=2.31.0" 13 | 14 | [dev-packages] 15 | 16 | [requires] 17 | python_version = "3.12" 18 | -------------------------------------------------------------------------------- /images/ansible-operator/README.md: -------------------------------------------------------------------------------- 1 | We build the base image using the Dockerfile, which validates the python requirements scaffolding that it copies from this directory. 2 | 3 | To update the requirements (`Pipfile` and `Pipfile.lock`) build and execute the image generated by `pipfile.Dockerfile` like so: 4 | 5 | 1. docker build -f ./pipfile.Dockerfile -t pipfile-generator . 6 | 2. docker run --rm -it -v .:/tmp/pip-airlock:Z pipfile-generator 7 | 3. Commit the newly-generated `Pipfile.lock` file (NB: this directory is in root .gitignore file, so you must `git add -f`) 8 | 9 | -------------------------------------------------------------------------------- /images/ansible-operator/pipfile.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/ubi9/ubi:9.5 AS basebuilder 2 | 3 | # Install Rust so that we can ensure backwards compatibility with installing/building the cryptography wheel across all platforms 4 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 5 | ENV PATH="/root/.cargo/bin:${PATH}" 6 | RUN rustc --version 7 | 8 | # Copy python dependencies (including ansible) to be installed using Pipenv 9 | COPY ./Pipfile ./ 10 | # Instruct pip(env) not to keep a cache of installed packages, 11 | # to install into the global site-packages and 12 | # to clear the pipenv cache as well 13 | ENV PIP_NO_CACHE_DIR=1 \ 14 | PIPENV_SYSTEM=1 \ 15 | PIPENV_CLEAR=1 16 | # Ensure fresh metadata rather than cached metadata, install system and pip python deps, 17 | # and remove those not needed at runtime. 18 | RUN set -e && dnf clean all && rm -rf /var/cache/dnf/* \ 19 | && dnf update -y \ 20 | && dnf install -y gcc libffi-devel openssl-devel python3.12-devel \ 21 | && pushd /usr/local/bin && ln -sf ../../bin/python3.12 python3 && popd \ 22 | && python3 -m ensurepip --upgrade \ 23 | && pip3 install --upgrade pip~=23.3.2 \ 24 | && pip3 install pipenv==2023.11.15 \ 25 | && pipenv lock \ 26 | # NOTE: This ignored vulnerability (71064) was detected in requests, \ 27 | # but the upgraded version doesn't support the use case (protocol we are using).\ 28 | # Ref: https://github.com/operator-framework/ansible-operator-plugins/pull/67#issuecomment-2189164688 29 | && pipenv check --ignore 71064 \ 30 | && dnf remove -y gcc libffi-devel openssl-devel python3.12-devel \ 31 | && dnf clean all \ 32 | && rm -rf /var/cache/dnf 33 | 34 | VOLUME /tmp/pip-airlock 35 | ENTRYPOINT ["cp", "./Pipfile.lock", "/tmp/pip-airlock/"] 36 | # to pull the generated lockfile, run this like 37 | # docker run --rm -it -v .:/tmp/pip-airlock:Z 38 | -------------------------------------------------------------------------------- /internal/annotations/metrics/metrics_suite_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package metrics 16 | 17 | import ( 18 | "testing" 19 | 20 | . "github.com/onsi/ginkgo/v2" 21 | . "github.com/onsi/gomega" 22 | ) 23 | 24 | func TestMetrics(t *testing.T) { 25 | RegisterFailHandler(Fail) 26 | RunSpecs(t, "Metrics Suite") 27 | } 28 | -------------------------------------------------------------------------------- /internal/annotations/metrics/metrics_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package metrics 16 | 17 | import ( 18 | . "github.com/onsi/ginkgo/v2" 19 | . "github.com/onsi/gomega" 20 | ) 21 | 22 | var _ = Describe("SDK Label helper functions", func() { 23 | Describe("parseVersion", func() { 24 | It("should extract sdk version", func() { 25 | version := "v0.17.0-159-ge87627f4-dirty" 26 | output := parseVersion(version) 27 | Expect(output).To(Equal("v0.17.0+git")) 28 | }) 29 | It("should extract sdk version", func() { 30 | version := "v0.18.0" 31 | output := parseVersion(version) 32 | Expect(output).To(Equal("v0.18.0")) 33 | }) 34 | It("should extract sdk version", func() { 35 | version := "v0.18.0-ge87627f4" 36 | output := parseVersion(version) 37 | Expect(output).To(Equal("v0.18.0+git")) 38 | }) 39 | It("should return unknown", func() { 40 | version := "noneSemanticVersion" 41 | output := parseVersion(version) 42 | Expect(output).To(Equal("unknown")) 43 | }) 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /internal/annotations/scorecard/scorecard.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scorecard 16 | 17 | import ( 18 | "path/filepath" 19 | ) 20 | 21 | // Static bundle annotation values. 22 | const ( 23 | mediaTypeV1 = "scorecard+v1" 24 | ) 25 | 26 | // Bundle annotation keys. 27 | // NB(estroz): version these keys based on their "vX" version (either with the version in their names, 28 | // or in subpackages). This may be a requirement if we create "v2" keys. 29 | const ( 30 | mediaTypeBundleKey = "operators.operatorframework.io.test.mediatype.v1" 31 | configBundleKey = "operators.operatorframework.io.test.config.v1" 32 | ) 33 | 34 | func MakeBundleMetadataLabels(configDir string) map[string]string { 35 | return map[string]string{ 36 | mediaTypeBundleKey: mediaTypeV1, 37 | configBundleKey: configDir, 38 | } 39 | } 40 | 41 | func GetConfigDir(labels map[string]string) (value string, hasKey bool) { 42 | if configKey, hasMTKey := configKeyForMediaType(labels); hasMTKey { 43 | value, hasKey = labels[configKey] 44 | } 45 | return filepath.Clean(filepath.FromSlash(value)), hasKey 46 | } 47 | 48 | func configKeyForMediaType(labels map[string]string) (string, bool) { 49 | switch labels[mediaTypeBundleKey] { 50 | case mediaTypeV1: 51 | return configBundleKey, true 52 | } 53 | return "", false 54 | } 55 | -------------------------------------------------------------------------------- /internal/ansible/apiserver/apiserver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package apiserver 16 | 17 | import ( 18 | "encoding/json" 19 | "fmt" 20 | "io" 21 | "net/http" 22 | "time" 23 | 24 | logf "sigs.k8s.io/controller-runtime/pkg/log" 25 | crmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" 26 | 27 | "github.com/operator-framework/ansible-operator-plugins/internal/ansible/metrics" 28 | ) 29 | 30 | var log = logf.Log.WithName("apiserver") 31 | 32 | type Options struct { 33 | Address string 34 | Port int 35 | } 36 | 37 | func Run(options Options) error { 38 | mux := http.NewServeMux() 39 | mux.HandleFunc("/metrics", metricsHandler) 40 | 41 | server := http.Server{ 42 | Addr: fmt.Sprintf("%s:%d", options.Address, options.Port), 43 | Handler: mux, 44 | ReadHeaderTimeout: 5 * time.Second, 45 | } 46 | log.Info("Starting to serve metrics listener", "Address", server.Addr) 47 | return server.ListenAndServe() 48 | } 49 | 50 | func metricsHandler(w http.ResponseWriter, r *http.Request) { 51 | defer func() { 52 | _, _ = io.Copy(io.Discard, r.Body) 53 | r.Body.Close() 54 | }() 55 | log.V(3).Info(fmt.Sprintf("%s %s", r.Method, r.URL)) 56 | 57 | var userMetric metrics.UserMetric 58 | 59 | switch r.Method { 60 | case http.MethodPost: 61 | log.V(3).Info("The apiserver has received a POST") 62 | err := json.NewDecoder(r.Body).Decode(&userMetric) 63 | if err != nil { 64 | log.Info(err.Error()) 65 | http.Error(w, err.Error(), http.StatusBadRequest) 66 | return 67 | } 68 | err = metrics.HandleUserMetric(crmetrics.Registry, userMetric) 69 | if err != nil { 70 | log.Info(err.Error()) 71 | http.Error(w, err.Error(), http.StatusBadRequest) 72 | } 73 | default: 74 | http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /internal/ansible/controller/controller_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package controller 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | ) 23 | 24 | func TestFilterPredicate(t *testing.T) { 25 | matchLabelPass := make(map[string]string) 26 | matchLabelPass["testKey"] = "testValue" 27 | selectorPass := metav1.LabelSelector{ 28 | MatchLabels: matchLabelPass, 29 | } 30 | noSelector := metav1.LabelSelector{} 31 | 32 | passPredicate, err := parsePredicateSelector(selectorPass) 33 | assert.Equal(t, nil, err, "Verify that no error is thrown on a valid populated selector") 34 | assert.NotEqual(t, nil, passPredicate, "Verify that a predicate is constructed using a valid selector") 35 | 36 | nilPredicate, err := parsePredicateSelector(noSelector) 37 | assert.Equal(t, nil, err, "Verify that no error is thrown on a valid unpopulated selector") 38 | assert.Equal(t, nil, nilPredicate, "Verify correct parsing of an unpopulated selector") 39 | } 40 | -------------------------------------------------------------------------------- /internal/ansible/flags/suite_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package flags_test 16 | 17 | import ( 18 | "testing" 19 | 20 | . "github.com/onsi/ginkgo/v2" 21 | . "github.com/onsi/gomega" 22 | ) 23 | 24 | func TestFlags(t *testing.T) { 25 | RegisterFailHandler(Fail) 26 | RunSpecs(t, "Flags Suite") 27 | } 28 | -------------------------------------------------------------------------------- /internal/ansible/handler/handler_suite_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package handler 16 | 17 | import ( 18 | "bytes" 19 | "testing" 20 | 21 | . "github.com/onsi/ginkgo/v2" 22 | . "github.com/onsi/gomega" 23 | "k8s.io/client-go/rest" 24 | "sigs.k8s.io/controller-runtime/pkg/envtest" 25 | logf "sigs.k8s.io/controller-runtime/pkg/log" 26 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 27 | ) 28 | 29 | var testenv *envtest.Environment 30 | var cfg *rest.Config 31 | var logBuffer bytes.Buffer 32 | 33 | func TestEventhandler(t *testing.T) { 34 | RegisterFailHandler(Fail) 35 | RunSpecs(t, "Handler Suite") 36 | } 37 | 38 | var _ = BeforeSuite(func() { 39 | logf.SetLogger(zap.New(zap.WriteTo(&logBuffer), zap.UseDevMode(true))) 40 | testenv = &envtest.Environment{} 41 | var err error 42 | cfg, err = testenv.Start() 43 | Expect(err).NotTo(HaveOccurred()) 44 | }) 45 | 46 | var _ = AfterSuite(func() { 47 | Expect(testenv.Stop()).To(Succeed()) 48 | }) 49 | -------------------------------------------------------------------------------- /internal/ansible/runner/testdata/playbook.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/internal/ansible/runner/testdata/playbook.yml -------------------------------------------------------------------------------- /internal/ansible/runner/testdata/roles/role/tasks.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/internal/ansible/runner/testdata/roles/role/tasks.yaml -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/ansible_collections/nameSpace/collection/roles/someRole/empty_file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/internal/ansible/watches/testdata/ansible_collections/nameSpace/collection/roles/someRole/empty_file -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/duplicate_gvk.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | finalizer: 7 | name: app.example.com/finalizer 8 | vars: 9 | sentinel: finalizer_running 10 | - version: v1alpha1 11 | group: app.example.com 12 | kind: Database 13 | playbook: playbook.yaml 14 | finalizer: 15 | name: app.example.com/finalizer 16 | vars: 17 | sentinel: finalizer_running 18 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/env-vars.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: "${WATCH_VERSION}" 3 | group: "app.example.com" 4 | kind: "AnsibleSelectorTest" 5 | playbook: ${WATCH_PLAYBOOK} 6 | selector: 7 | matchLabels: 8 | ${WATCH_MATCH_LABEL_VAR_NAME}: "${WATCH_MATCH_LABEL_VAR_VALUE}" 9 | undefined: "${WATCH_UNDEFINED_ENV_VAR}" 10 | matchExpressions: 11 | - {key: ${WATCH_MATCH_EXPRESSIONS_KEY}, operator: In, values: [a, b]} -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | finalizer: 7 | name: app.example.com/finalizer 8 | vars: 9 | sentinel: finalizer_running 10 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_collection.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: SanityUnconfirmed 5 | role: nameSpace.collection.someRole 6 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_duration.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | reconcilePeriod: invalid 7 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_finalizer_no_vars.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | finalizer: 7 | name: foo.app.example.com/finalizer 8 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_finalizer_playbook_path.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | finalizer: 7 | name: app.example.com/finalizer 8 | playbook: playbook.yaml 9 | vars: 10 | sentinel: finalizer_running 11 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_finalizer_role_path.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | finalizer: 7 | name: app.example.com/finalizer 8 | role: ansible/role 9 | vars: 10 | sentinel: finalizer_running 11 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_finalizer_whithout_name.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | finalizer: 7 | name: 8 | 9 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_playbook_path.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: invalid/playbook.yaml 6 | finalizer: 7 | name: app.example.com/finalizer 8 | vars: 9 | sentinel: finalizer_running 10 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_role_path.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | role: opt/ansible/playbook.yaml 6 | finalizer: 7 | name: app.example.com/finalizer 8 | vars: 9 | sentinel: finalizer_running 10 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_status.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - version: v1alpha1 3 | group: app.example.com 4 | kind: Database 5 | playbook: playbook.yaml 6 | watches: invalid 7 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/invalid_yaml_file.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | invalid file layout 3 | 4 | -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/playbook.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/internal/ansible/watches/testdata/playbook.yml -------------------------------------------------------------------------------- /internal/ansible/watches/testdata/roles/role/tasks.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/internal/ansible/watches/testdata/roles/role/tasks.yaml -------------------------------------------------------------------------------- /internal/cmd/ansible-operator/run/proxy_suite_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package run 16 | 17 | import ( 18 | "testing" 19 | 20 | . "github.com/onsi/ginkgo/v2" 21 | . "github.com/onsi/gomega" 22 | ) 23 | 24 | func TestVersion(t *testing.T) { 25 | RegisterFailHandler(Fail) 26 | RunSpecs(t, "cmd suite") 27 | } 28 | -------------------------------------------------------------------------------- /internal/cmd/ansible-operator/version/cmd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package version 16 | 17 | import ( 18 | "fmt" 19 | "runtime" 20 | 21 | "github.com/spf13/cobra" 22 | 23 | ver "github.com/operator-framework/ansible-operator-plugins/internal/version" 24 | ) 25 | 26 | func NewCmd() *cobra.Command { 27 | versionCmd := &cobra.Command{ 28 | Use: "version", 29 | Short: "Prints the version of operator-sdk", 30 | Run: func(cmd *cobra.Command, args []string) { 31 | run() 32 | }, 33 | } 34 | return versionCmd 35 | } 36 | 37 | func run() { 38 | version := ver.GitVersion 39 | if version == "unknown" { 40 | version = ver.Version 41 | } 42 | fmt.Printf("ansible-operator version: %q, commit: %q, kubernetes version: %q, go version: %q, GOOS: %q, GOARCH: %q\n", 43 | version, ver.GitCommit, ver.KubernetesVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH) 44 | } 45 | -------------------------------------------------------------------------------- /internal/cmd/ansible-operator/version/cmd_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package version 16 | 17 | import ( 18 | "fmt" 19 | "io" 20 | "os" 21 | "runtime" 22 | 23 | . "github.com/onsi/ginkgo/v2" 24 | . "github.com/onsi/gomega" 25 | 26 | ver "github.com/operator-framework/ansible-operator-plugins/internal/version" 27 | ) 28 | 29 | var _ = Describe("Running a version command", func() { 30 | Describe("NewCmd", func() { 31 | It("builds a cobra command", func() { 32 | cmd := NewCmd() 33 | Expect(cmd).NotTo(BeNil()) 34 | Expect(cmd.Use).NotTo(Equal("")) 35 | Expect(cmd.Short).NotTo(Equal("")) 36 | }) 37 | }) 38 | Describe("run", func() { 39 | It("prints the correct version info", func() { 40 | r, w, _ := os.Pipe() 41 | tmp := os.Stdout 42 | defer func() { 43 | os.Stdout = tmp 44 | }() 45 | os.Stdout = w 46 | go func() { 47 | run() 48 | w.Close() 49 | }() 50 | stdout, err := io.ReadAll(r) 51 | Expect(err).ToNot(HaveOccurred()) 52 | stdoutString := string(stdout) 53 | version := ver.GitVersion 54 | if version == "unknown" { 55 | version = ver.Version 56 | } 57 | Expect(stdoutString).To(ContainSubstring(fmt.Sprintf("version: %q", version))) 58 | Expect(stdoutString).To(ContainSubstring(fmt.Sprintf("commit: %q", ver.GitCommit))) 59 | Expect(stdoutString).To(ContainSubstring(fmt.Sprintf("kubernetes version: %q", ver.KubernetesVersion))) 60 | Expect(stdoutString).To(ContainSubstring(fmt.Sprintf("go version: %q", runtime.Version()))) 61 | Expect(stdoutString).To(ContainSubstring(fmt.Sprintf("GOOS: %q", runtime.GOOS))) 62 | Expect(stdoutString).To(ContainSubstring(fmt.Sprintf("GOARCH: %q", runtime.GOARCH))) 63 | }) 64 | }) 65 | }) 66 | -------------------------------------------------------------------------------- /internal/cmd/ansible-operator/version/version_suite_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package version_test 16 | 17 | import ( 18 | "testing" 19 | 20 | . "github.com/onsi/ginkgo/v2" 21 | . "github.com/onsi/gomega" 22 | ) 23 | 24 | func TestVersion(t *testing.T) { 25 | RegisterFailHandler(Fail) 26 | RunSpecs(t, "Version Cmd Suite") 27 | } 28 | -------------------------------------------------------------------------------- /internal/flags/flags.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package flags 16 | 17 | // global command-line flags 18 | const ( 19 | VerboseOpt = "verbose" 20 | ) 21 | -------------------------------------------------------------------------------- /internal/util/k8sutil/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8sutil 16 | 17 | const ( 18 | // KubeConfigEnvVar defines the env variable KUBECONFIG which 19 | // contains the kubeconfig file path. 20 | KubeConfigEnvVar = "KUBECONFIG" 21 | 22 | // WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE 23 | // which is the namespace where the watch activity happens. 24 | // this value is empty if the operator is running with clusterScope. 25 | WatchNamespaceEnvVar = "WATCH_NAMESPACE" 26 | ) 27 | -------------------------------------------------------------------------------- /internal/util/k8sutil/object.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8sutil 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/runtime" 19 | ) 20 | 21 | type MarshalFunc func(interface{}) ([]byte, error) 22 | 23 | // GetObjectBytes marshalls an object with m and removes runtime-managed fields: 24 | // 'status', 'creationTimestamp' 25 | func GetObjectBytes(obj interface{}, m MarshalFunc) ([]byte, error) { 26 | u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) 27 | if err != nil { 28 | return nil, err 29 | } 30 | deleteKeys := []string{"status", "creationTimestamp"} 31 | for _, dk := range deleteKeys { 32 | deleteKeyFromUnstructured(u, dk) 33 | } 34 | return m(u) 35 | } 36 | 37 | func deleteKeyFromUnstructured(u map[string]interface{}, key string) { 38 | if _, ok := u[key]; ok { 39 | delete(u, key) 40 | return 41 | } 42 | 43 | for _, v := range u { 44 | switch t := v.(type) { 45 | case map[string]interface{}: 46 | deleteKeyFromUnstructured(t, key) 47 | case []interface{}: 48 | for _, ti := range t { 49 | if m, ok := ti.(map[string]interface{}); ok { 50 | deleteKeyFromUnstructured(m, key) 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /internal/util/k8sutil/scan.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8sutil 16 | 17 | import ( 18 | "bufio" 19 | "bytes" 20 | "io" 21 | 22 | k8syaml "k8s.io/apimachinery/pkg/util/yaml" 23 | ) 24 | 25 | const maxExecutiveEmpties = 100 26 | 27 | // Scanner scans a yaml manifest file for manifest tokens delimited by "---". 28 | // See bufio.Scanner for semantics. 29 | type Scanner struct { 30 | reader *k8syaml.YAMLReader 31 | token []byte // Last token returned by split. 32 | err error // Sticky error. 33 | empties int // Count of successive empty tokens. 34 | done bool // Scan has finished. 35 | } 36 | 37 | func NewYAMLScanner(r io.Reader) *Scanner { 38 | return &Scanner{reader: k8syaml.NewYAMLReader(bufio.NewReader(r))} 39 | } 40 | 41 | func (s *Scanner) Err() error { 42 | if s.err == io.EOF { 43 | return nil 44 | } 45 | return s.err 46 | } 47 | 48 | func (s *Scanner) Scan() bool { 49 | if s.done { 50 | return false 51 | } 52 | 53 | var ( 54 | tok []byte 55 | err error 56 | ) 57 | 58 | for { 59 | tok, err = s.reader.Read() 60 | if err != nil { 61 | if err == io.EOF { 62 | s.done = true 63 | } 64 | s.err = err 65 | return false 66 | } 67 | if len(bytes.TrimSpace(tok)) == 0 { 68 | s.empties++ 69 | if s.empties > maxExecutiveEmpties { 70 | panic("yaml.Scan: too many empty tokens without progressing") 71 | } 72 | continue 73 | } 74 | s.empties = 0 75 | s.token = tok 76 | return true 77 | } 78 | } 79 | 80 | func (s *Scanner) Text() string { 81 | return string(s.token) 82 | } 83 | 84 | func (s *Scanner) Bytes() []byte { 85 | return s.token 86 | } 87 | -------------------------------------------------------------------------------- /internal/version/version.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package version 16 | 17 | // var needs to be used instead of const for ldflags 18 | var ( 19 | Version = "unknown" 20 | GitVersion = "unknown" 21 | GitCommit = "unknown" 22 | KubernetesVersion = "unknown" 23 | 24 | // ImageVersion represents the ansible-operator, helm-operator, and scorecard subproject versions, 25 | // which is used in each plugin to specify binary and/or image versions. This is set to the 26 | // most recent operator-sdk release tag such that samples are generated with the correct versions 27 | // in a release commit. Once each element that uses this version is moved to a separate repo 28 | // and release process, this variable will be removed. 29 | 30 | // TODO: find a way to make this automated. For now manually update this before releases. 31 | ImageVersion = "v1.38.1" 32 | ) 33 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/constants/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package constants 16 | 17 | import ( 18 | "path/filepath" 19 | ) 20 | 21 | const ( 22 | filePathSep = string(filepath.Separator) 23 | RolesDir = "roles" 24 | PlaybooksDir = "playbooks" 25 | MoleculeDir = "molecule" 26 | MoleculeDefaultDir = MoleculeDir + filePathSep + "default" 27 | MoleculeTestLocalDir = MoleculeDir + filePathSep + "test-local" 28 | MoleculeClusterDir = MoleculeDir + filePathSep + "cluster" 29 | MoleculeTemplatesDir = MoleculeDir + filePathSep + "templates" 30 | ) 31 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/plugin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package ansible 16 | 17 | import ( 18 | "sigs.k8s.io/kubebuilder/v4/pkg/config" 19 | cfgv3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3" 20 | "sigs.k8s.io/kubebuilder/v4/pkg/plugin" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins" 23 | ) 24 | 25 | const pluginName = "base.ansible" + plugins.DefaultNameQualifier 26 | 27 | var ( 28 | pluginVersion = plugin.Version{Number: 1} 29 | supportedProjectVersions = []config.Version{cfgv3.Version} 30 | pluginKey = plugin.KeyFor(Plugin{}) 31 | ) 32 | 33 | var ( 34 | _ plugin.Plugin = Plugin{} 35 | _ plugin.Init = Plugin{} 36 | _ plugin.CreateAPI = Plugin{} 37 | ) 38 | 39 | type Plugin struct { 40 | initSubcommand 41 | createAPISubcommand 42 | } 43 | 44 | func (Plugin) Name() string { return pluginName } 45 | func (Plugin) Version() plugin.Version { return pluginVersion } 46 | func (Plugin) SupportedProjectVersions() []config.Version { return supportedProjectVersions } 47 | func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand } 48 | func (p Plugin) GetCreateAPISubcommand() plugin.CreateAPISubcommand { return &p.createAPISubcommand } 49 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/config/testing/debug_logs_patch.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package testing 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &DebugLogsPatch{} 24 | 25 | // DebugLogsPatch scaffolds the patch file for enabling 26 | // verbose logs during Ansible testing 27 | type DebugLogsPatch struct { 28 | machinery.TemplateMixin 29 | } 30 | 31 | // SetTemplateDefaults implements machinery.Template 32 | func (f *DebugLogsPatch) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = filepath.Join("config", "testing", "debug_logs_patch.yaml") 35 | } 36 | 37 | f.TemplateBody = debugLogsPatchTemplate 38 | 39 | f.IfExistsAction = machinery.Error 40 | 41 | return nil 42 | } 43 | 44 | const debugLogsPatchTemplate = `--- 45 | apiVersion: apps/v1 46 | kind: Deployment 47 | metadata: 48 | name: controller-manager 49 | namespace: system 50 | spec: 51 | template: 52 | spec: 53 | containers: 54 | - name: manager 55 | env: 56 | - name: ANSIBLE_DEBUG_LOGS 57 | value: "TRUE" 58 | ` 59 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/config/testing/kustomization.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package testing 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Kustomization{} 24 | 25 | // Kustomization scaffolds the kustomization file for use 26 | // during Ansible testing 27 | type Kustomization struct { 28 | machinery.TemplateMixin 29 | } 30 | 31 | // SetTemplateDefaults implements machinery.Template 32 | func (f *Kustomization) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = filepath.Join("config", "testing", "kustomization.yaml") 35 | } 36 | 37 | f.TemplateBody = KustomizationTemplate 38 | 39 | f.IfExistsAction = machinery.Error 40 | 41 | return nil 42 | } 43 | 44 | const KustomizationTemplate = `# Adds namespace to all resources. 45 | namespace: osdk-test 46 | 47 | namePrefix: osdk- 48 | 49 | # Labels to add to all resources and selectors. 50 | #commonLabels: 51 | # someName: someValue 52 | 53 | patches: 54 | - path: manager_image.yaml 55 | - path: debug_logs_patch.yaml 56 | - path: ../default/manager_metrics_patch.yaml 57 | target: 58 | kind: Deployment 59 | 60 | apiVersion: kustomize.config.k8s.io/v1beta1 61 | kind: Kustomization 62 | resources: 63 | - ../crd 64 | - ../rbac 65 | - ../manager 66 | images: 67 | - name: testing 68 | newName: testing-operator 69 | ` 70 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/config/testing/manager_image.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package testing 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &ManagerImage{} 24 | 25 | // ManagerImage scaffolds the patch file for overriding the 26 | // default image during Ansible testing 27 | type ManagerImage struct { 28 | machinery.TemplateMixin 29 | } 30 | 31 | // SetTemplateDefaults implements machinery.Template 32 | func (f *ManagerImage) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = filepath.Join("config", "testing", "manager_image.yaml") 35 | } 36 | 37 | f.TemplateBody = managerImageTemplate 38 | 39 | f.IfExistsAction = machinery.Error 40 | 41 | return nil 42 | } 43 | 44 | const managerImageTemplate = `--- 45 | apiVersion: apps/v1 46 | kind: Deployment 47 | metadata: 48 | name: controller-manager 49 | namespace: system 50 | spec: 51 | template: 52 | spec: 53 | containers: 54 | - name: manager 55 | image: testing 56 | ` 57 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/config/testing/pullpolicy/always_pull_patch.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pullpolicy 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &AlwaysPullPatch{} 24 | 25 | // AlwaysPullPatch scaffolds the patch file for overriding the 26 | // default image pull policy during Ansible testing 27 | type AlwaysPullPatch struct { 28 | machinery.TemplateMixin 29 | } 30 | 31 | // SetTemplateDefaults implements machinery.Template 32 | func (f *AlwaysPullPatch) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = filepath.Join("config", "testing", "pull_policy", "Always.yaml") 35 | } 36 | 37 | f.TemplateBody = alwaysPullPatchTemplate 38 | 39 | f.IfExistsAction = machinery.Error 40 | 41 | return nil 42 | } 43 | 44 | const alwaysPullPatchTemplate = `--- 45 | apiVersion: apps/v1 46 | kind: Deployment 47 | metadata: 48 | name: controller-manager 49 | namespace: system 50 | spec: 51 | template: 52 | spec: 53 | containers: 54 | - name: manager 55 | imagePullPolicy: Always 56 | ` 57 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/config/testing/pullpolicy/ifnotpresent_pull_patch.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pullpolicy 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &IfNotPresentPullPatch{} 24 | 25 | // IfNotPresentPullPatch scaffolds the patch file for overriding the 26 | // default image pull policy during Ansible testing 27 | type IfNotPresentPullPatch struct { 28 | machinery.TemplateMixin 29 | } 30 | 31 | // SetTemplateDefaults implements machinery.Template 32 | func (f *IfNotPresentPullPatch) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = filepath.Join("config", "testing", "pull_policy", "IfNotPresent.yaml") 35 | } 36 | 37 | f.TemplateBody = ifNotPresentPullPatchTemplate 38 | 39 | f.IfExistsAction = machinery.Error 40 | 41 | return nil 42 | } 43 | 44 | const ifNotPresentPullPatchTemplate = `--- 45 | apiVersion: apps/v1 46 | kind: Deployment 47 | metadata: 48 | name: controller-manager 49 | namespace: system 50 | spec: 51 | template: 52 | spec: 53 | containers: 54 | - name: manager 55 | imagePullPolicy: IfNotPresent 56 | ` 57 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/config/testing/pullpolicy/never_pull_patch.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pullpolicy 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &NeverPullPatch{} 24 | 25 | // NeverPullPatch scaffolds the patch file for overriding the 26 | // default image pull policy during Ansible testing 27 | type NeverPullPatch struct { 28 | machinery.TemplateMixin 29 | } 30 | 31 | // SetTemplateDefaults implements machinery.Template 32 | func (f *NeverPullPatch) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = filepath.Join("config", "testing", "pull_policy", "Never.yaml") 35 | } 36 | 37 | f.TemplateBody = neverPullPatchTemplate 38 | 39 | f.IfExistsAction = machinery.Error 40 | 41 | return nil 42 | } 43 | 44 | const neverPullPatchTemplate = `--- 45 | apiVersion: apps/v1 46 | kind: Deployment 47 | metadata: 48 | name: controller-manager 49 | namespace: system 50 | spec: 51 | template: 52 | spec: 53 | containers: 54 | - name: manager 55 | imagePullPolicy: Never 56 | ` 57 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/dockerfile.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package templates 16 | 17 | import ( 18 | "errors" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins/ansible/v1/constants" 23 | ) 24 | 25 | var _ machinery.Template = &Dockerfile{} 26 | 27 | // Dockerfile scaffolds a Dockerfile for building a main 28 | type Dockerfile struct { 29 | machinery.TemplateMixin 30 | 31 | // AnsibleOperatorVersion is the version of the Dockerfile's base image. 32 | AnsibleOperatorVersion string 33 | 34 | // These variables are always overwritten. 35 | RolesDir string 36 | PlaybooksDir string 37 | } 38 | 39 | // SetTemplateDefaults implements machinery.Template 40 | func (f *Dockerfile) SetTemplateDefaults() error { 41 | if f.Path == "" { 42 | f.Path = "Dockerfile" 43 | } 44 | 45 | f.TemplateBody = dockerfileTemplate 46 | 47 | if f.AnsibleOperatorVersion == "" { 48 | return errors.New("ansible-operator version is required in scaffold") 49 | } 50 | 51 | f.RolesDir = constants.RolesDir 52 | f.PlaybooksDir = constants.PlaybooksDir 53 | 54 | return nil 55 | } 56 | 57 | const dockerfileTemplate = `FROM quay.io/operator-framework/ansible-operator:{{ .AnsibleOperatorVersion }} 58 | 59 | COPY requirements.yml ${HOME}/requirements.yml 60 | RUN ansible-galaxy collection install -r ${HOME}/requirements.yml \ 61 | && chmod -R ug+rwx ${HOME}/.ansible 62 | 63 | COPY watches.yaml ${HOME}/watches.yaml 64 | COPY {{ .RolesDir }}/ ${HOME}/{{ .RolesDir }}/ 65 | COPY {{ .PlaybooksDir }}/ ${HOME}/{{ .PlaybooksDir }}/ 66 | ` 67 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/gitignore.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | Modifications copyright 2020 The Operator-SDK Authors 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package templates 19 | 20 | import ( 21 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 22 | ) 23 | 24 | var _ machinery.Template = &GitIgnore{} 25 | 26 | // GitIgnore scaffolds the .gitignore file 27 | type GitIgnore struct { 28 | machinery.TemplateMixin 29 | } 30 | 31 | // SetTemplateDefaults implements machinery.Template 32 | func (f *GitIgnore) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = ".gitignore" 35 | } 36 | 37 | f.TemplateBody = gitignoreTemplate 38 | 39 | return nil 40 | } 41 | 42 | const gitignoreTemplate = ` 43 | # Binaries for programs and plugins 44 | *.exe 45 | *.exe~ 46 | *.dll 47 | *.so 48 | *.dylib 49 | bin 50 | 51 | # editor and IDE paraphernalia 52 | .idea 53 | *.swp 54 | *.swo 55 | *~ 56 | ` 57 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mdefault/converge.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mdefault 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Converge{} 24 | 25 | // Converge scaffolds a Converge for building a main 26 | type Converge struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Converge) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "default", "converge.yml") 34 | } 35 | f.TemplateBody = convergeTemplate 36 | return nil 37 | } 38 | 39 | const convergeTemplate = `--- 40 | - name: Converge 41 | hosts: localhost 42 | connection: local 43 | gather_facts: no 44 | collections: 45 | - kubernetes.core 46 | 47 | tasks: 48 | - name: Create Namespace 49 | k8s: 50 | api_version: v1 51 | kind: Namespace 52 | name: '{{ "{{ namespace }}" }}' 53 | 54 | - import_tasks: kustomize.yml 55 | vars: 56 | state: present 57 | ` 58 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mdefault/create.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mdefault 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Create{} 24 | 25 | // Create scaffolds a Create for building a main 26 | type Create struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Create) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "default", "create.yml") 34 | } 35 | f.TemplateBody = createTemplate 36 | return nil 37 | } 38 | 39 | const createTemplate = `--- 40 | - name: Create 41 | hosts: localhost 42 | connection: local 43 | gather_facts: false 44 | tasks: [] 45 | ` 46 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mdefault/destroy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mdefault 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Destroy{} 24 | 25 | // Destroy scaffolds a Destroy for building a main 26 | type Destroy struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Destroy) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "default", "destroy.yml") 34 | } 35 | f.TemplateBody = destroyTemplate 36 | return nil 37 | } 38 | 39 | const destroyTemplate = `--- 40 | - name: Destroy 41 | hosts: localhost 42 | connection: local 43 | gather_facts: false 44 | collections: 45 | - kubernetes.core 46 | 47 | tasks: 48 | - import_tasks: kustomize.yml 49 | vars: 50 | state: absent 51 | 52 | - name: Destroy Namespace 53 | k8s: 54 | api_version: v1 55 | kind: Namespace 56 | name: '{{ "{{ namespace }}" }}' 57 | state: absent 58 | 59 | - name: Unset pull policy 60 | command: '{{ "{{ kustomize }}" }} edit remove patch pull_policy/{{ "{{ operator_pull_policy }}" }}.yaml' 61 | args: 62 | chdir: '{{ "{{ config_dir }}" }}/testing' 63 | ` 64 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mdefault/kustomize.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mdefault 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Kustomize{} 24 | 25 | // Kustomize scaffolds a Kustomize for building a main 26 | type Kustomize struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Kustomize) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "default", "kustomize.yml") 34 | } 35 | f.TemplateBody = kustomizeTemplate 36 | return nil 37 | } 38 | 39 | const kustomizeTemplate = `--- 40 | - name: Build kustomize testing overlay 41 | # load_restrictor must be set to none so we can load patch files from the default overlay 42 | command: '{{ "{{ kustomize }}" }} build --load-restrictor LoadRestrictionsNone' 43 | args: 44 | chdir: '{{ "{{ config_dir }}" }}/testing' 45 | register: resources 46 | changed_when: false 47 | 48 | - name: Set resources to {{ "{{ state }}" }} 49 | k8s: 50 | definition: '{{ "{{ item }}" }}' 51 | state: '{{ "{{ state }}" }}' 52 | wait: no 53 | loop: '{{ "{{ resources.stdout | from_yaml_all | list }}" }}' 54 | 55 | - name: Wait for resources to get to {{ "{{ state }}" }} 56 | k8s: 57 | definition: '{{ "{{ item }}" }}' 58 | state: '{{ "{{ state }}" }}' 59 | wait: yes 60 | loop: '{{ "{{ resources.stdout | from_yaml_all | list }}" }}' 61 | ` 62 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mdefault/molecule.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mdefault 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Molecule{} 24 | 25 | // Molecule scaffolds a Molecule for building a main 26 | type Molecule struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Molecule) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "default", "molecule.yml") 34 | } 35 | f.TemplateBody = moleculeTemplate 36 | return nil 37 | } 38 | 39 | const moleculeTemplate = `--- 40 | dependency: 41 | name: galaxy 42 | driver: 43 | name: delegated 44 | platforms: 45 | - name: cluster 46 | groups: 47 | - k8s 48 | provisioner: 49 | name: ansible 50 | inventory: 51 | group_vars: 52 | all: 53 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 54 | host_vars: 55 | localhost: 56 | ansible_python_interpreter: '{{ "{{ ansible_playbook_python }}" }}' 57 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 58 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 59 | operator_image: ${OPERATOR_IMAGE:-""} 60 | operator_pull_policy: ${OPERATOR_PULL_POLICY:-"Always"} 61 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 62 | env: 63 | K8S_AUTH_KUBECONFIG: ${KUBECONFIG:-"~/.kube/config"} 64 | verifier: 65 | name: ansible 66 | ` 67 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mdefault/prepare.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mdefault 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Prepare{} 24 | 25 | // Prepare scaffolds a Prepare for building a main 26 | type Prepare struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Prepare) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "default", "prepare.yml") 34 | } 35 | f.TemplateBody = prepareTemplate 36 | return nil 37 | } 38 | 39 | const prepareTemplate = `--- 40 | - name: Prepare 41 | hosts: localhost 42 | connection: local 43 | gather_facts: false 44 | 45 | tasks: 46 | - name: Ensure operator image is set 47 | fail: 48 | msg: | 49 | You must specify the OPERATOR_IMAGE environment variable in order to run the 50 | 'default' scenario 51 | when: not operator_image 52 | 53 | - name: Set testing image 54 | command: '{{ "{{ kustomize }}" }} edit set image testing={{ "{{ operator_image }}" }}' 55 | args: 56 | chdir: '{{ "{{ config_dir }}" }}/testing' 57 | 58 | - name: Set pull policy 59 | command: '{{ "{{ kustomize }}" }} edit add patch --path pull_policy/{{ "{{ operator_pull_policy }}" }}.yaml' 60 | args: 61 | chdir: '{{ "{{ config_dir }}" }}/testing' 62 | 63 | - name: Set testing namespace 64 | command: '{{ "{{ kustomize }}" }} edit set namespace {{ "{{ namespace }}" }}' 65 | args: 66 | chdir: '{{ "{{ config_dir }}" }}/testing' 67 | ` 68 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mdefault/tasks_test_resource.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mdefault 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &ResourceTest{} 24 | 25 | // ResourceTest scaffolds a ResourceTest for building a main 26 | type ResourceTest struct { 27 | machinery.TemplateMixin 28 | machinery.ResourceMixin 29 | SampleFile string 30 | } 31 | 32 | // SetTemplateDefaults implements machinery.Template 33 | func (f *ResourceTest) SetTemplateDefaults() error { 34 | if f.Path == "" { 35 | f.Path = filepath.Join("molecule", "default", "tasks", "%[kind]_test.yml") 36 | f.Path = f.Resource.Replacer().Replace(f.Path) 37 | } 38 | f.SampleFile = f.Resource.Replacer().Replace("%[group]_%[version]_%[kind].yaml") 39 | 40 | f.TemplateBody = resourceTestTemplate 41 | return nil 42 | } 43 | 44 | const resourceTestTemplate = `--- 45 | - name: Create the {{ .Resource.QualifiedGroup }}/{{ .Resource.Version }}.{{ .Resource.Kind }} 46 | k8s: 47 | state: present 48 | namespace: '{{ "{{ namespace }}" }}' 49 | definition: "{{ "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}" }}" 50 | wait: yes 51 | wait_timeout: 300 52 | wait_condition: 53 | type: Successful 54 | status: "True" 55 | vars: 56 | cr_file: '{{ .SampleFile }}' 57 | 58 | - name: Add assertions here 59 | assert: 60 | that: false 61 | fail_msg: FIXME Add real assertions for your operator 62 | ` 63 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mkind/converge.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mkind 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Converge{} 24 | 25 | // Converge scaffolds a Converge for building a main 26 | type Converge struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Converge) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "kind", "converge.yml") 34 | } 35 | f.TemplateBody = convergeTemplate 36 | return nil 37 | } 38 | 39 | const convergeTemplate = `--- 40 | - name: Converge 41 | hosts: localhost 42 | connection: local 43 | gather_facts: no 44 | 45 | tasks: 46 | - name: Build operator image 47 | docker_image: 48 | build: 49 | path: '{{ "{{ project_dir }}" }}' 50 | pull: no 51 | name: '{{ "{{ operator_image }}" }}' 52 | tag: latest 53 | push: no 54 | source: build 55 | force_source: yes 56 | 57 | - name: Load image into kind cluster 58 | command: kind load docker-image --name osdk-test '{{ "{{ operator_image }}" }}' 59 | register: result 60 | changed_when: '"not yet present" in result.stdout' 61 | 62 | - import_playbook: ../default/converge.yml 63 | ` 64 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mkind/create.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mkind 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Create{} 24 | 25 | // Create scaffolds a Create for building a main 26 | type Create struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Create) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "kind", "create.yml") 34 | } 35 | f.TemplateBody = createTemplate 36 | return nil 37 | } 38 | 39 | const createTemplate = `--- 40 | - name: Create 41 | hosts: localhost 42 | connection: local 43 | gather_facts: false 44 | tasks: 45 | - name: Create test kind cluster 46 | command: kind create cluster --name osdk-test --kubeconfig {{ "{{ kubeconfig }}" }} 47 | ` 48 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mkind/destroy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mkind 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Destroy{} 24 | 25 | // Destroy scaffolds a Destroy for building a main 26 | type Destroy struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Destroy) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "kind", "destroy.yml") 34 | } 35 | f.TemplateBody = destroyTemplate 36 | return nil 37 | } 38 | 39 | const destroyTemplate = `--- 40 | - name: Destroy 41 | hosts: localhost 42 | connection: local 43 | gather_facts: false 44 | collections: 45 | - kubernetes.core 46 | 47 | tasks: 48 | - name: Destroy test kind cluster 49 | command: kind delete cluster --name osdk-test --kubeconfig {{ "{{ kubeconfig }}" }} 50 | 51 | - name: Unset pull policy 52 | command: '{{ "{{ kustomize }}" }} edit remove patch pull_policy/{{ "{{ operator_pull_policy }}" }}.yaml' 53 | args: 54 | chdir: '{{ "{{ config_dir }}" }}/testing' 55 | ` 56 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/molecule/mkind/molecule.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package mkind 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Molecule{} 24 | 25 | // Molecule scaffolds a Molecule for building a main 26 | type Molecule struct { 27 | machinery.TemplateMixin 28 | } 29 | 30 | // SetTemplateDefaults implements machinery.Template 31 | func (f *Molecule) SetTemplateDefaults() error { 32 | if f.Path == "" { 33 | f.Path = filepath.Join("molecule", "kind", "molecule.yml") 34 | } 35 | f.TemplateBody = moleculeTemplate 36 | return nil 37 | } 38 | 39 | const moleculeTemplate = `--- 40 | dependency: 41 | name: galaxy 42 | driver: 43 | name: delegated 44 | platforms: 45 | - name: cluster 46 | groups: 47 | - k8s 48 | provisioner: 49 | name: ansible 50 | playbooks: 51 | prepare: ../default/prepare.yml 52 | verify: ../default/verify.yml 53 | inventory: 54 | group_vars: 55 | all: 56 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 57 | host_vars: 58 | localhost: 59 | ansible_python_interpreter: '{{ "{{ ansible_playbook_python }}" }}' 60 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 61 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 62 | project_dir: ${MOLECULE_PROJECT_DIRECTORY} 63 | operator_image: testing-operator 64 | operator_pull_policy: "Never" 65 | kubeconfig: "{{ "{{ lookup('env', 'KUBECONFIG') }}" }}" 66 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 67 | env: 68 | K8S_AUTH_KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 69 | KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 70 | verifier: 71 | name: ansible 72 | ` 73 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/playbooks/placeholder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package playbooks 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Placeholder{} 24 | 25 | type Placeholder struct { 26 | machinery.TemplateMixin 27 | } 28 | 29 | // SetTemplateDefaults implements machinery.Template 30 | func (f *Placeholder) SetTemplateDefaults() error { 31 | if f.Path == "" { 32 | f.Path = filepath.Join("playbooks", ".placeholder") 33 | } 34 | f.TemplateBody = placeholderTemplate 35 | return nil 36 | } 37 | 38 | const placeholderTemplate = `` 39 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/playbooks/playbook.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package playbooks 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Playbook{} 24 | 25 | type Playbook struct { 26 | machinery.TemplateMixin 27 | machinery.ResourceMixin 28 | 29 | GenerateRole bool 30 | } 31 | 32 | func (f *Playbook) SetTemplateDefaults() error { 33 | if f.Path == "" { 34 | f.Path = filepath.Join("playbooks", "%[kind].yml") 35 | } 36 | f.Path = f.Resource.Replacer().Replace(f.Path) 37 | 38 | f.TemplateBody = playbookTmpl 39 | 40 | return nil 41 | } 42 | 43 | const playbookTmpl = `--- 44 | - hosts: localhost 45 | gather_facts: no 46 | collections: 47 | - kubernetes.core 48 | - operator_sdk.util 49 | 50 | {{- if .GenerateRole }} 51 | tasks: 52 | - import_role: 53 | name: "{{ lower .Resource.Kind }}" 54 | {{- else }} 55 | tasks: [] 56 | {{- end }} 57 | ` 58 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/requirements.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package templates 16 | 17 | import ( 18 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 19 | ) 20 | 21 | var _ machinery.Template = &RequirementsYml{} 22 | 23 | // RequirementsYml - A requirements file for Ansible collection dependencies 24 | type RequirementsYml struct { 25 | machinery.TemplateMixin 26 | } 27 | 28 | func (f *RequirementsYml) SetTemplateDefaults() error { 29 | if f.Path == "" { 30 | f.Path = "requirements.yml" 31 | } 32 | f.TemplateBody = requirementsYmlTmpl 33 | return nil 34 | } 35 | 36 | const requirementsYmlTmpl = `--- 37 | collections: 38 | - name: operator_sdk.util 39 | version: "0.5.0" 40 | - name: kubernetes.core 41 | version: "3.2.0" 42 | - name: cloud.common 43 | version: "3.0.0" 44 | - name: community.docker 45 | version: "3.12.1" 46 | ` 47 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/roles/defaults_main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package roles 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins/ansible/v1/constants" 23 | ) 24 | 25 | var _ machinery.Template = &DefaultsMain{} 26 | 27 | type DefaultsMain struct { 28 | machinery.TemplateMixin 29 | machinery.ResourceMixin 30 | } 31 | 32 | // SetTemplateDefaults implements machinery.Template 33 | func (f *DefaultsMain) SetTemplateDefaults() error { 34 | if f.Path == "" { 35 | f.Path = filepath.Join(constants.RolesDir, "%[kind]", "defaults", "main.yml") 36 | f.Path = f.Resource.Replacer().Replace(f.Path) 37 | } 38 | f.TemplateBody = defaultsMainAnsibleTmpl 39 | return nil 40 | } 41 | 42 | const defaultsMainAnsibleTmpl = `--- 43 | # defaults file for {{ .Resource.Kind }} 44 | ` 45 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/roles/files_dir.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package roles 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins/ansible/v1/constants" 23 | ) 24 | 25 | var _ machinery.Template = &RoleFiles{} 26 | 27 | type RoleFiles struct { 28 | machinery.TemplateMixin 29 | machinery.ResourceMixin 30 | } 31 | 32 | // SetTemplateDefaults implements machinery.Template 33 | func (f *RoleFiles) SetTemplateDefaults() error { 34 | if f.Path == "" { 35 | f.Path = filepath.Join(constants.RolesDir, "%[kind]", "files", ".placeholder") 36 | f.Path = f.Resource.Replacer().Replace(f.Path) 37 | } 38 | 39 | f.TemplateBody = rolesFilesDirPlaceholder 40 | return nil 41 | } 42 | 43 | const rolesFilesDirPlaceholder = `` 44 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/roles/handlers_main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package roles 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins/ansible/v1/constants" 23 | ) 24 | 25 | var _ machinery.Template = &HandlersMain{} 26 | 27 | type HandlersMain struct { 28 | machinery.TemplateMixin 29 | machinery.ResourceMixin 30 | } 31 | 32 | // SetTemplateDefaults implements machinery.Template 33 | func (f *HandlersMain) SetTemplateDefaults() error { 34 | if f.Path == "" { 35 | f.Path = filepath.Join(constants.RolesDir, "%[kind]", "handlers", "main.yml") 36 | f.Path = f.Resource.Replacer().Replace(f.Path) 37 | } 38 | 39 | f.TemplateBody = handlersMainAnsibleTmpl 40 | return nil 41 | } 42 | 43 | const handlersMainAnsibleTmpl = `--- 44 | # handlers file for {{ .Resource.Kind }} 45 | ` 46 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/roles/placeholder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package roles 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | ) 22 | 23 | var _ machinery.Template = &Placeholder{} 24 | 25 | type Placeholder struct { 26 | machinery.TemplateMixin 27 | } 28 | 29 | // SetTemplateDefaults implements machinery.Template 30 | func (f *Placeholder) SetTemplateDefaults() error { 31 | if f.Path == "" { 32 | f.Path = filepath.Join("roles", ".placeholder") 33 | } 34 | f.TemplateBody = placeholderTemplate 35 | return nil 36 | } 37 | 38 | const placeholderTemplate = `` 39 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/roles/tasks_main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package roles 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins/ansible/v1/constants" 23 | ) 24 | 25 | var _ machinery.Template = &TasksMain{} 26 | 27 | type TasksMain struct { 28 | machinery.TemplateMixin 29 | machinery.ResourceMixin 30 | } 31 | 32 | // SetTemplateDefaults implements machinery.Template 33 | func (f *TasksMain) SetTemplateDefaults() error { 34 | if f.Path == "" { 35 | f.Path = filepath.Join(constants.RolesDir, "%[kind]", "tasks", "main.yml") 36 | f.Path = f.Resource.Replacer().Replace(f.Path) 37 | } 38 | 39 | f.TemplateBody = tasksMainAnsibleTmpl 40 | return nil 41 | } 42 | 43 | const tasksMainAnsibleTmpl = `--- 44 | # tasks file for {{ .Resource.Kind }} 45 | ` 46 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/roles/templates_dir.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package roles 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins/ansible/v1/constants" 23 | ) 24 | 25 | var _ machinery.Template = &RoleTemplates{} 26 | 27 | type RoleTemplates struct { 28 | machinery.TemplateMixin 29 | machinery.ResourceMixin 30 | } 31 | 32 | // SetTemplateDefaults implements machinery.Template 33 | func (f *RoleTemplates) SetTemplateDefaults() error { 34 | if f.Path == "" { 35 | f.Path = filepath.Join(constants.RolesDir, "%[kind]", "templates", ".placeholder") 36 | } 37 | f.Path = f.Resource.Replacer().Replace(f.Path) 38 | 39 | f.TemplateBody = templatesDirPlaceholder 40 | return nil 41 | } 42 | 43 | const templatesDirPlaceholder = `` 44 | -------------------------------------------------------------------------------- /pkg/plugins/ansible/v1/scaffolds/internal/templates/roles/vars_main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package roles 16 | 17 | import ( 18 | "path/filepath" 19 | 20 | "sigs.k8s.io/kubebuilder/v4/pkg/machinery" 21 | 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/plugins/ansible/v1/constants" 23 | ) 24 | 25 | var _ machinery.Template = &VarsMain{} 26 | 27 | type VarsMain struct { 28 | machinery.TemplateMixin 29 | machinery.ResourceMixin 30 | } 31 | 32 | // SetTemplateDefaults implements machinery.Template 33 | func (f *VarsMain) SetTemplateDefaults() error { 34 | if f.Path == "" { 35 | f.Path = filepath.Join(constants.RolesDir, "%[kind]", "vars", "main.yml") 36 | } 37 | f.Path = f.Resource.Replacer().Replace(f.Path) 38 | 39 | f.TemplateBody = varsMainAnsibleTmpl 40 | return nil 41 | } 42 | 43 | const varsMainAnsibleTmpl = `--- 44 | # vars file for {{ .Resource.Kind }} 45 | ` 46 | -------------------------------------------------------------------------------- /pkg/plugins/plugins.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package plugins 16 | 17 | // DefaultNameQualifier is the Operator SDK plugin name suffix. Appending 18 | // this suffix to a short name, ex. "go", makes it fully qualified. 19 | const DefaultNameQualifier = ".sdk.operatorframework.io" 20 | -------------------------------------------------------------------------------- /pkg/plugins/util/message.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package util 16 | 17 | const WarnMessageRemovalV1beta1 = "The v1beta1 API version for CRDs and Webhooks is deprecated and is no longer offered since " + 18 | "Kubernetes 1.22. This flag will be removed in a future release. We " + 19 | "recommend that you no longer use the v1beta1 API version" + 20 | "More info: https://kubernetes.io/docs/reference/using-api/deprecation-guide/#v1-22" 21 | -------------------------------------------------------------------------------- /pkg/testutils/e2e/helpers.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/operator-framework/ansible-operator-plugins/pkg/testutils/kubernetes" 10 | "github.com/operator-framework/ansible-operator-plugins/pkg/testutils/sample" 11 | ) 12 | 13 | // CleanUpTestDir removes the test directory 14 | func CleanUpTestDir(path string) error { 15 | return os.RemoveAll(path) 16 | } 17 | 18 | // CreateCustomResources will create the CRs that are specified in a Sample 19 | func CreateCustomResources(sample sample.Sample, kubectl kubernetes.Kubectl) error { 20 | for _, gvk := range sample.GVKs() { 21 | sampleFile := filepath.Join( 22 | "config", 23 | "samples", 24 | fmt.Sprintf("%s_%s_%s.yaml", gvk.Group, gvk.Version, strings.ToLower(gvk.Kind))) 25 | 26 | o, err := kubectl.Apply(true, "-f", sampleFile) 27 | if err != nil { 28 | return fmt.Errorf("encountered an error when applying CRD (%s): %w | OUTPUT: %s", sampleFile, err, o) 29 | } 30 | } 31 | 32 | return nil 33 | } 34 | 35 | // AllowProjectBeMultiGroup will update the PROJECT file with the information to allow we scaffold 36 | // apis with different groups. be available. 37 | func AllowProjectBeMultiGroup(sample sample.Sample) error { 38 | const multiGroup = `multigroup: true 39 | ` 40 | projectBytes, err := os.ReadFile(filepath.Join(sample.Dir(), "PROJECT")) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | projectBytes = append([]byte(multiGroup), projectBytes...) 46 | err = os.WriteFile(filepath.Join(sample.Dir(), "PROJECT"), projectBytes, 0644) 47 | if err != nil { 48 | return err 49 | } 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /pkg/testutils/e2e/kind/helpers.go: -------------------------------------------------------------------------------- 1 | package kind 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "strings" 8 | 9 | "github.com/operator-framework/ansible-operator-plugins/pkg/testutils/command" 10 | "github.com/operator-framework/ansible-operator-plugins/pkg/testutils/kubernetes" 11 | ) 12 | 13 | // IsRunningOnKind checks if the Kubernetes cluster is a KinD cluster 14 | func IsRunningOnKind(kubectl kubernetes.Kubectl) (bool, error) { 15 | kubectx, err := kubectl.Command("config", "current-context") 16 | if err != nil { 17 | return false, err 18 | } 19 | return strings.Contains(kubectx, "kind"), nil 20 | } 21 | 22 | // LoadImageToKindCluster will load an image onto a KinD cluster 23 | func LoadImageToKindCluster(cc command.CommandContext, image string) error { 24 | cluster := "kind" 25 | if v, ok := os.LookupEnv("KIND_CLUSTER"); ok { 26 | cluster = v 27 | } 28 | kindOptions := []string{"load", "docker-image", image, "--name", cluster} 29 | cmd := exec.Command("kind", kindOptions...) 30 | o, err := cc.Run(cmd) 31 | if err != nil { 32 | return fmt.Errorf("encountered an error attempting to load image to KinD cluster: %w | OUTPUT: %s", err, o) 33 | } 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /pkg/testutils/sample/sample.go: -------------------------------------------------------------------------------- 1 | package sample 2 | 3 | import ( 4 | "github.com/operator-framework/ansible-operator-plugins/pkg/testutils/command" 5 | "k8s.io/apimachinery/pkg/runtime/schema" 6 | ) 7 | 8 | // Sample represents a sample project that can be created and used for testing 9 | type Sample interface { 10 | // CommandContext returns the CommandContext that the Sample is using 11 | CommandContext() command.CommandContext 12 | // Name returns the name of the Sample 13 | Name() string 14 | // GVKs return an array of GVKs that are used when generating the apis and webhooks for the Sample 15 | GVKs() []schema.GroupVersionKind 16 | // Domain returs the domain of the sample 17 | Domain() string 18 | // Dir returns the directory the sample is created in 19 | Dir() string 20 | // Binary returns the binary that is used when creating a sample 21 | Binary() string 22 | // GenerateInit scaffolds using the `init` subcommand 23 | GenerateInit() error 24 | // GenerateApi scaffolds using the `create api` subcommand 25 | GenerateApi() error 26 | // GenerateWebhook scaffolds using the `create webhook` subcommand 27 | GenerateWebhook() error 28 | } 29 | -------------------------------------------------------------------------------- /test/common/sa_secret.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package common 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | ) 21 | 22 | var saSecretTemplate = `--- 23 | apiVersion: v1 24 | kind: Secret 25 | type: kubernetes.io/service-account-token 26 | metadata: 27 | name: %s 28 | annotations: 29 | kubernetes.io/service-account.name: "%s" 30 | ` 31 | 32 | // GetSASecret writes a service account token secret to a file. It returns a string to the file or an error if it fails to write the file 33 | func GetSASecret(name string, dir string) (string, error) { 34 | secretName := name + "-secret" 35 | fileName := dir + "/" + secretName + ".yaml" 36 | err := os.WriteFile(fileName, []byte(fmt.Sprintf(saSecretTemplate, secretName, name)), 0777) 37 | if err != nil { 38 | return "", err 39 | } 40 | 41 | return fileName, nil 42 | } 43 | -------------------------------------------------------------------------------- /test/e2e/ansible/local_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Operator-SDK Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package e2e_ansible_test 16 | 17 | import ( 18 | "os/exec" 19 | 20 | . "github.com/onsi/ginkgo/v2" 21 | . "github.com/onsi/gomega" 22 | "github.com/operator-framework/ansible-operator-plugins/pkg/testutils/e2e/operator" 23 | ) 24 | 25 | var _ = Describe("Running Ansible projects", func() { 26 | Context("built with operator-sdk", func() { 27 | BeforeEach(func() { 28 | By("Installing CRD's") 29 | err := operator.InstallCRDs(ansibleSample) 30 | Expect(err).NotTo(HaveOccurred()) 31 | }) 32 | 33 | AfterEach(func() { 34 | By("Uninstalling CRD's") 35 | err := operator.UninstallCRDs(ansibleSample) 36 | Expect(err).NotTo(HaveOccurred()) 37 | }) 38 | 39 | It("Should run correctly when run locally", func() { 40 | By("Running the project") 41 | cmd := exec.Command("make", "run") 42 | cmd.Dir = ansibleSample.Dir() 43 | err := cmd.Start() 44 | Expect(err).NotTo(HaveOccurred()) 45 | 46 | By("Killing the project") 47 | err = cmd.Process.Kill() 48 | Expect(err).NotTo(HaveOccurred()) 49 | }) 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | bin 9 | 10 | # editor and IDE paraphernalia 11 | .idea 12 | *.swp 13 | *.swo 14 | *~ 15 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/operator-framework/ansible-operator:dev 2 | 3 | COPY requirements.yml ${HOME}/requirements.yml 4 | RUN ansible-galaxy collection install -r ${HOME}/requirements.yml \ 5 | && chmod -R ug+rwx ${HOME}/.ansible 6 | 7 | COPY watches.yaml ${HOME}/watches.yaml 8 | COPY roles/ ${HOME}/roles/ 9 | COPY playbooks/ ${HOME}/playbooks/ 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/PROJECT: -------------------------------------------------------------------------------- 1 | # Code generated by tool. DO NOT EDIT. 2 | # This file is used to track the info used to scaffold your project 3 | # and allow the plugins properly work. 4 | # More info: https://book.kubebuilder.io/reference/project-config.html 5 | domain: example.com 6 | layout: 7 | - go.kubebuilder.io/v1 8 | multigroup: true 9 | projectName: memcached-molecule-operator 10 | resources: 11 | - api: 12 | crdVersion: v1 13 | namespaced: true 14 | domain: example.com 15 | group: cache 16 | kind: Memcached 17 | version: v1alpha1 18 | - api: 19 | crdVersion: v1 20 | namespaced: true 21 | domain: example.com 22 | group: cache 23 | kind: Foo 24 | version: v1alpha1 25 | - api: 26 | crdVersion: v1 27 | namespaced: true 28 | domain: example.com 29 | group: cache 30 | kind: Memfin 31 | version: v1alpha1 32 | - api: 33 | crdVersion: v1 34 | namespaced: true 35 | domain: example.com 36 | group: ignore 37 | kind: Secret 38 | version: v1 39 | version: "3" 40 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/crd/bases/cache.example.com_foos.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: foos.cache.example.com 6 | spec: 7 | group: cache.example.com 8 | names: 9 | kind: Foo 10 | listKind: FooList 11 | plural: foos 12 | singular: foo 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: Foo is the Schema for the foos API 19 | properties: 20 | apiVersion: 21 | description: 'APIVersion defines the versioned schema of this representation 22 | of an object. Servers should convert recognized schemas to the latest 23 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 24 | type: string 25 | kind: 26 | description: 'Kind is a string value representing the REST resource this 27 | object represents. Servers may infer this from the endpoint the client 28 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | description: Spec defines the desired state of Foo 34 | type: object 35 | x-kubernetes-preserve-unknown-fields: true 36 | status: 37 | description: Status defines the observed state of Foo 38 | type: object 39 | x-kubernetes-preserve-unknown-fields: true 40 | type: object 41 | served: true 42 | storage: true 43 | subresources: 44 | status: {} 45 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/crd/bases/cache.example.com_memcacheds.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: memcacheds.cache.example.com 6 | spec: 7 | group: cache.example.com 8 | names: 9 | kind: Memcached 10 | listKind: MemcachedList 11 | plural: memcacheds 12 | singular: memcached 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: Memcached is the Schema for the memcacheds API 19 | properties: 20 | apiVersion: 21 | description: 'APIVersion defines the versioned schema of this representation 22 | of an object. Servers should convert recognized schemas to the latest 23 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 24 | type: string 25 | kind: 26 | description: 'Kind is a string value representing the REST resource this 27 | object represents. Servers may infer this from the endpoint the client 28 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | description: Spec defines the desired state of Memcached 34 | type: object 35 | x-kubernetes-preserve-unknown-fields: true 36 | status: 37 | description: Status defines the observed state of Memcached 38 | type: object 39 | x-kubernetes-preserve-unknown-fields: true 40 | type: object 41 | served: true 42 | storage: true 43 | subresources: 44 | status: {} 45 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/crd/bases/cache.example.com_memfins.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: memfins.cache.example.com 6 | spec: 7 | group: cache.example.com 8 | names: 9 | kind: Memfin 10 | listKind: MemfinList 11 | plural: memfins 12 | singular: memfin 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: Memfin is the Schema for the memfins API 19 | properties: 20 | apiVersion: 21 | description: 'APIVersion defines the versioned schema of this representation 22 | of an object. Servers should convert recognized schemas to the latest 23 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 24 | type: string 25 | kind: 26 | description: 'Kind is a string value representing the REST resource this 27 | object represents. Servers may infer this from the endpoint the client 28 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | description: Spec defines the desired state of Memfin 34 | type: object 35 | x-kubernetes-preserve-unknown-fields: true 36 | status: 37 | description: Status defines the observed state of Memfin 38 | type: object 39 | x-kubernetes-preserve-unknown-fields: true 40 | type: object 41 | served: true 42 | storage: true 43 | subresources: 44 | status: {} 45 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/crd/bases/ignore.example.com_secrets.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: secrets.ignore.example.com 6 | spec: 7 | group: ignore.example.com 8 | names: 9 | kind: Secret 10 | listKind: SecretList 11 | plural: secrets 12 | singular: secret 13 | scope: Namespaced 14 | versions: 15 | - name: v1 16 | schema: 17 | openAPIV3Schema: 18 | description: Secret is the Schema for the secrets API 19 | properties: 20 | apiVersion: 21 | description: 'APIVersion defines the versioned schema of this representation 22 | of an object. Servers should convert recognized schemas to the latest 23 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 24 | type: string 25 | kind: 26 | description: 'Kind is a string value representing the REST resource this 27 | object represents. Servers may infer this from the endpoint the client 28 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | description: Spec defines the desired state of Secret 34 | type: object 35 | x-kubernetes-preserve-unknown-fields: true 36 | status: 37 | description: Status defines the observed state of Secret 38 | type: object 39 | x-kubernetes-preserve-unknown-fields: true 40 | type: object 41 | served: true 42 | storage: true 43 | subresources: 44 | status: {} 45 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # This kustomization.yaml is not intended to be run by itself, 2 | # since it depends on service name and namespace that are out of this kustomize package. 3 | # It should be run by config/default 4 | resources: 5 | - bases/cache.example.com_memcacheds.yaml 6 | - bases/cache.example.com_foos.yaml 7 | - bases/cache.example.com_memfins.yaml 8 | - bases/ignore.example.com_secrets.yaml 9 | # +kubebuilder:scaffold:crdkustomizeresource 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: memcached-molecule-operator-system 3 | 4 | # Value of this field is prepended to the 5 | # names of all resources, e.g. a deployment named 6 | # "wordpress" becomes "alices-wordpress". 7 | # Note that it should also match with the prefix (text before '-') of the namespace 8 | # field above. 9 | namePrefix: memcached-molecule-operator- 10 | 11 | # Labels to add to all resources and selectors. 12 | #labels: 13 | #- includeSelectors: true 14 | # pairs: 15 | # someName: someValue 16 | 17 | resources: 18 | - ../crd 19 | - ../rbac 20 | - ../manager 21 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 22 | - ../prometheus 23 | # [METRICS] Expose the controller manager metrics service. 24 | - metrics_service.yaml 25 | # [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. 26 | # Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. 27 | # Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will 28 | # be able to communicate with the Webhook Server. 29 | #- ../network-policy 30 | 31 | # Uncomment the patches line if you enable Metrics 32 | patches: 33 | # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. 34 | # More info: https://book.kubebuilder.io/reference/metrics 35 | - path: manager_metrics_patch.yaml 36 | target: 37 | kind: Deployment 38 | 39 | 40 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/default/manager_metrics_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch adds the args to allow exposing the metrics endpoint using HTTPS 2 | - op: add 3 | path: /spec/template/spec/containers/0/args/0 4 | value: --metrics-bind-address=:8443 5 | # This patch adds the args to allow securing the metrics endpoint 6 | - op: add 7 | path: /spec/template/spec/containers/0/args/0 8 | value: --metrics-secure 9 | # This patch adds the args to allow RBAC-based authn/authz the metrics endpoint 10 | - op: add 11 | path: /spec/template/spec/containers/0/args/0 12 | value: --metrics-require-rbac 13 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/default/metrics_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | app.kubernetes.io/name: memcached-molecule-operator 7 | app.kubernetes.io/managed-by: kustomize 8 | name: controller-manager-metrics-service 9 | namespace: system 10 | spec: 11 | ports: 12 | - name: https 13 | port: 8443 14 | protocol: TCP 15 | targetPort: 8443 16 | selector: 17 | control-plane: controller-manager 18 | app.kubernetes.io/name: memcached-molecule-operator 19 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/network-policy/allow-metrics-traffic.yaml: -------------------------------------------------------------------------------- 1 | # This NetworkPolicy allows ingress traffic 2 | # with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those 3 | # namespaces are able to gather data from the metrics endpoint. 4 | apiVersion: networking.k8s.io/v1 5 | kind: NetworkPolicy 6 | metadata: 7 | labels: 8 | app.kubernetes.io/name: memcached-molecule-operator 9 | app.kubernetes.io/managed-by: kustomize 10 | name: allow-metrics-traffic 11 | namespace: system 12 | spec: 13 | podSelector: 14 | matchLabels: 15 | control-plane: controller-manager 16 | app.kubernetes.io/name: memcached-molecule-operator 17 | policyTypes: 18 | - Ingress 19 | ingress: 20 | # This allows ingress traffic from any namespace with the label metrics: enabled 21 | - from: 22 | - namespaceSelector: 23 | matchLabels: 24 | metrics: enabled # Only from namespaces with this label 25 | ports: 26 | - port: 8443 27 | protocol: TCP 28 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/network-policy/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - allow-metrics-traffic.yaml 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | 4 | 5 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | # Prometheus Monitor Service (Metrics) 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | labels: 6 | control-plane: controller-manager 7 | app.kubernetes.io/name: memcached-molecule-operator 8 | app.kubernetes.io/managed-by: kustomize 9 | name: controller-manager-metrics-monitor 10 | namespace: system 11 | spec: 12 | endpoints: 13 | - path: /metrics 14 | port: https # Ensure this is the name of the port that exposes HTTPS metrics 15 | scheme: https 16 | bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token 17 | tlsConfig: 18 | # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables 19 | # certificate verification, exposing the system to potential man-in-the-middle attacks. 20 | # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. 21 | # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, 22 | # which securely references the certificate from the 'metrics-server-cert' secret. 23 | insecureSkipVerify: true 24 | selector: 25 | matchLabels: 26 | control-plane: controller-manager 27 | app.kubernetes.io/name: memcached-molecule-operator 28 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/foo_admin_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants full permissions ('*') over cache.example.com. 5 | # This role is intended for users authorized to modify roles and bindings within the cluster, 6 | # enabling them to delegate specific permissions to other users or groups as needed. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: foo-admin-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - foos 20 | verbs: 21 | - '*' 22 | - apiGroups: 23 | - cache.example.com 24 | resources: 25 | - foos/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/foo_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants permissions to create, update, and delete resources within the cache.example.com. 5 | # This role is intended for users who need to manage these resources 6 | # but should not control RBAC or manage permissions for others. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: foo-editor-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - foos 20 | verbs: 21 | - create 22 | - delete 23 | - get 24 | - list 25 | - patch 26 | - update 27 | - watch 28 | - apiGroups: 29 | - cache.example.com 30 | resources: 31 | - foos/status 32 | verbs: 33 | - get 34 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/foo_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants read-only access to cache.example.com resources. 5 | # This role is intended for users who need visibility into these resources 6 | # without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: foo-viewer-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - foos 20 | verbs: 21 | - get 22 | - list 23 | - watch 24 | - apiGroups: 25 | - cache.example.com 26 | resources: 27 | - foos/status 28 | verbs: 29 | - get 30 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/ignore_secret_admin_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants full permissions ('*') over ignore.example.com. 5 | # This role is intended for users authorized to modify roles and bindings within the cluster, 6 | # enabling them to delegate specific permissions to other users or groups as needed. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: ignore-secret-admin-role 15 | rules: 16 | - apiGroups: 17 | - ignore.example.com 18 | resources: 19 | - secrets 20 | verbs: 21 | - '*' 22 | - apiGroups: 23 | - ignore.example.com 24 | resources: 25 | - secrets/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/ignore_secret_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants permissions to create, update, and delete resources within the ignore.example.com. 5 | # This role is intended for users who need to manage these resources 6 | # but should not control RBAC or manage permissions for others. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: ignore-secret-editor-role 15 | rules: 16 | - apiGroups: 17 | - ignore.example.com 18 | resources: 19 | - secrets 20 | verbs: 21 | - create 22 | - delete 23 | - get 24 | - list 25 | - patch 26 | - update 27 | - watch 28 | - apiGroups: 29 | - ignore.example.com 30 | resources: 31 | - secrets/status 32 | verbs: 33 | - get 34 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/ignore_secret_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants read-only access to ignore.example.com resources. 5 | # This role is intended for users who need visibility into these resources 6 | # without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: ignore-secret-viewer-role 15 | rules: 16 | - apiGroups: 17 | - ignore.example.com 18 | resources: 19 | - secrets 20 | verbs: 21 | - get 22 | - list 23 | - watch 24 | - apiGroups: 25 | - ignore.example.com 26 | resources: 27 | - secrets/status 28 | verbs: 29 | - get 30 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | # All RBAC will be applied under this service account in 3 | # the deployment namespace. You may comment out this resource 4 | # if your manager will use a service account that exists at 5 | # runtime. Be sure to update RoleBinding and ClusterRoleBinding 6 | # subjects if changing service account names. 7 | - service_account.yaml 8 | - role.yaml 9 | - role_binding.yaml 10 | - leader_election_role.yaml 11 | - leader_election_role_binding.yaml 12 | # The following RBAC configurations are used to protect 13 | # the metrics endpoint with authn/authz. These configurations 14 | # ensure that only authorized users and service accounts 15 | # can access the metrics endpoint. Comment the following 16 | # permissions if you want to disable this protection. 17 | # More info: https://book.kubebuilder.io/reference/metrics.html 18 | - metrics_auth_role.yaml 19 | - metrics_auth_role_binding.yaml 20 | - metrics_reader_role.yaml 21 | # For each CRD, "Admin", "Editor" and "Viewer" roles are scaffolded by 22 | # default, aiding admins in cluster management. Those roles are 23 | # not used by the {{ .ProjectName }} itself. You can comment the following lines 24 | # if you do not want those helpers be installed with your Project. 25 | - ignore_secret_admin_role.yaml 26 | - ignore_secret_editor_role.yaml 27 | - ignore_secret_viewer_role.yaml 28 | - memfin_admin_role.yaml 29 | - memfin_editor_role.yaml 30 | - memfin_viewer_role.yaml 31 | - foo_admin_role.yaml 32 | - foo_editor_role.yaml 33 | - foo_viewer_role.yaml 34 | - memcached_admin_role.yaml 35 | - memcached_editor_role.yaml 36 | - memcached_viewer_role.yaml 37 | 38 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: memcached-molecule-operator 7 | app.kubernetes.io/managed-by: kustomize 8 | name: leader-election-role 9 | rules: 10 | - apiGroups: 11 | - "" 12 | resources: 13 | - configmaps 14 | verbs: 15 | - get 16 | - list 17 | - watch 18 | - create 19 | - update 20 | - patch 21 | - delete 22 | - apiGroups: 23 | - coordination.k8s.io 24 | resources: 25 | - leases 26 | verbs: 27 | - get 28 | - list 29 | - watch 30 | - create 31 | - update 32 | - patch 33 | - delete 34 | - apiGroups: 35 | - "" 36 | resources: 37 | - events 38 | verbs: 39 | - create 40 | - patch 41 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: memcached-molecule-operator 6 | app.kubernetes.io/managed-by: kustomize 7 | name: leader-election-rolebinding 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: Role 11 | name: leader-election-role 12 | subjects: 13 | - kind: ServiceAccount 14 | name: controller-manager 15 | namespace: system 16 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/memcached_admin_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants full permissions ('*') over cache.example.com. 5 | # This role is intended for users authorized to modify roles and bindings within the cluster, 6 | # enabling them to delegate specific permissions to other users or groups as needed. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: memcached-admin-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - memcacheds 20 | verbs: 21 | - '*' 22 | - apiGroups: 23 | - cache.example.com 24 | resources: 25 | - memcacheds/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/memcached_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants permissions to create, update, and delete resources within the cache.example.com. 5 | # This role is intended for users who need to manage these resources 6 | # but should not control RBAC or manage permissions for others. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: memcached-editor-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - memcacheds 20 | verbs: 21 | - create 22 | - delete 23 | - get 24 | - list 25 | - patch 26 | - update 27 | - watch 28 | - apiGroups: 29 | - cache.example.com 30 | resources: 31 | - memcacheds/status 32 | verbs: 33 | - get 34 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/memcached_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants read-only access to cache.example.com resources. 5 | # This role is intended for users who need visibility into these resources 6 | # without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: memcached-viewer-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - memcacheds 20 | verbs: 21 | - get 22 | - list 23 | - watch 24 | - apiGroups: 25 | - cache.example.com 26 | resources: 27 | - memcacheds/status 28 | verbs: 29 | - get 30 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/memfin_admin_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants full permissions ('*') over cache.example.com. 5 | # This role is intended for users authorized to modify roles and bindings within the cluster, 6 | # enabling them to delegate specific permissions to other users or groups as needed. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: memfin-admin-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - memfins 20 | verbs: 21 | - '*' 22 | - apiGroups: 23 | - cache.example.com 24 | resources: 25 | - memfins/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/memfin_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants permissions to create, update, and delete resources within the cache.example.com. 5 | # This role is intended for users who need to manage these resources 6 | # but should not control RBAC or manage permissions for others. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: memfin-editor-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - memfins 20 | verbs: 21 | - create 22 | - delete 23 | - get 24 | - list 25 | - patch 26 | - update 27 | - watch 28 | - apiGroups: 29 | - cache.example.com 30 | resources: 31 | - memfins/status 32 | verbs: 33 | - get 34 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/memfin_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # This rule is not used by the project memcached-molecule-operator itself. 2 | # It is provided to allow the cluster admin to help manage permissions for users. 3 | # 4 | # Grants read-only access to cache.example.com resources. 5 | # This role is intended for users who need visibility into these resources 6 | # without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: memcached-molecule-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: memfin-viewer-role 15 | rules: 16 | - apiGroups: 17 | - cache.example.com 18 | resources: 19 | - memfins 20 | verbs: 21 | - get 22 | - list 23 | - watch 24 | - apiGroups: 25 | - cache.example.com 26 | resources: 27 | - memfins/status 28 | verbs: 29 | - get 30 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/metrics_auth_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: metrics-auth-role 5 | rules: 6 | - apiGroups: 7 | - authentication.k8s.io 8 | resources: 9 | - tokenreviews 10 | verbs: 11 | - create 12 | - apiGroups: 13 | - authorization.k8s.io 14 | resources: 15 | - subjectaccessreviews 16 | verbs: 17 | - create 18 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/metrics_auth_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: metrics-auth-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: metrics-auth-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/metrics_reader_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: metrics-reader 5 | rules: 6 | - nonResourceURLs: 7 | - "/metrics" 8 | verbs: 9 | - get 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: memcached-molecule-operator 6 | app.kubernetes.io/managed-by: kustomize 7 | name: manager-rolebinding 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: ClusterRole 11 | name: manager-role 12 | subjects: 13 | - kind: ServiceAccount 14 | name: controller-manager 15 | namespace: system 16 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: memcached-molecule-operator 6 | app.kubernetes.io/managed-by: kustomize 7 | name: controller-manager 8 | namespace: system 9 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/samples/cache_v1alpha1_foo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cache.example.com/v1alpha1 2 | kind: Foo 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: memcached-molecule-operator 6 | app.kubernetes.io/managed-by: kustomize 7 | name: foo-sample 8 | spec: 9 | foo: bar 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/samples/cache_v1alpha1_memcached.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cache.example.com/v1alpha1 2 | kind: Memcached 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: memcached-molecule-operator 6 | app.kubernetes.io/managed-by: kustomize 7 | name: memcached-sample 8 | spec: 9 | size: 1 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/samples/cache_v1alpha1_memfin.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cache.example.com/v1alpha1 2 | kind: Memfin 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: memcached-molecule-operator 6 | app.kubernetes.io/managed-by: kustomize 7 | name: memfin-sample 8 | spec: 9 | foo: bar 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/samples/ignore_v1_secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: ignore.example.com/v1 2 | kind: Secret 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: memcached-molecule-operator 6 | app.kubernetes.io/managed-by: kustomize 7 | name: secret-sample 8 | spec: 9 | # TODO(user): Add fields here 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/samples/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples of your project ## 2 | resources: 3 | - cache_v1alpha1_memcached.yaml 4 | - cache_v1alpha1_foo.yaml 5 | - cache_v1alpha1_memfin.yaml 6 | - ignore_v1_secret.yaml 7 | # +kubebuilder:scaffold:manifestskustomizesamples 8 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/testing/debug_logs_patch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | env: 13 | - name: ANSIBLE_DEBUG_LOGS 14 | value: "TRUE" 15 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/testing/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: osdk-test 3 | 4 | namePrefix: osdk- 5 | 6 | # Labels to add to all resources and selectors. 7 | #commonLabels: 8 | # someName: someValue 9 | 10 | patches: 11 | - path: watch_namespace_patch.yaml 12 | - path: manager_image.yaml 13 | - path: debug_logs_patch.yaml 14 | - path: ../default/manager_metrics_patch.yaml 15 | target: 16 | kind: Deployment 17 | 18 | apiVersion: kustomize.config.k8s.io/v1beta1 19 | kind: Kustomization 20 | resources: 21 | - ../crd 22 | - ../rbac 23 | - ../manager 24 | images: 25 | - name: testing 26 | newName: testing-operator 27 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/testing/manager_image.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | image: testing 13 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/testing/pull_policy/Always.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | imagePullPolicy: Always 13 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/testing/pull_policy/IfNotPresent.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | imagePullPolicy: IfNotPresent 13 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/testing/pull_policy/Never.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | imagePullPolicy: Never 13 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/config/testing/watch_namespace_patch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | env: 13 | - name: WATCH_NAMESPACE 14 | valueFrom: 15 | fieldRef: 16 | fieldPath: metadata.namespace 17 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | collections: 7 | - kubernetes.core 8 | 9 | tasks: 10 | - name: Create Namespace 11 | k8s: 12 | api_version: v1 13 | kind: Namespace 14 | name: '{{ namespace }}' 15 | 16 | - import_tasks: kustomize.yml 17 | vars: 18 | state: present 19 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | tasks: [] 7 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | collections: 7 | - kubernetes.core 8 | 9 | tasks: 10 | - import_tasks: kustomize.yml 11 | vars: 12 | state: absent 13 | 14 | - name: Destroy Namespace 15 | k8s: 16 | api_version: v1 17 | kind: Namespace 18 | name: '{{ namespace }}' 19 | state: absent 20 | 21 | - name: Unset pull policy 22 | command: '{{ kustomize }} edit remove patch pull_policy/{{ operator_pull_policy }}.yaml' 23 | args: 24 | chdir: '{{ config_dir }}/testing' 25 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/kustomize.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Build kustomize testing overlay 3 | # load_restrictor must be set to none so we can load patch files from the default overlay 4 | command: '{{ kustomize }} build --load-restrictor LoadRestrictionsNone' 5 | args: 6 | chdir: '{{ config_dir }}/testing' 7 | register: resources 8 | changed_when: false 9 | 10 | - name: Set resources to {{ state }} 11 | k8s: 12 | definition: '{{ item }}' 13 | state: '{{ state }}' 14 | wait: no 15 | loop: '{{ resources.stdout | from_yaml_all | list }}' 16 | 17 | - name: Wait for resources to get to {{ state }} 18 | k8s: 19 | definition: '{{ item }}' 20 | state: '{{ state }}' 21 | wait: yes 22 | loop: '{{ resources.stdout | from_yaml_all | list }}' 23 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: delegated 6 | platforms: 7 | - name: cluster 8 | groups: 9 | - k8s 10 | provisioner: 11 | name: ansible 12 | inventory: 13 | group_vars: 14 | all: 15 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 16 | host_vars: 17 | localhost: 18 | ansible_python_interpreter: '{{ ansible_playbook_python }}' 19 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 20 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 21 | operator_image: ${OPERATOR_IMAGE:-""} 22 | operator_pull_policy: ${OPERATOR_PULL_POLICY:-"Always"} 23 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 24 | env: 25 | K8S_AUTH_KUBECONFIG: ${KUBECONFIG:-"~/.kube/config"} 26 | verifier: 27 | name: ansible 28 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Ensure operator image is set 9 | fail: 10 | msg: | 11 | You must specify the OPERATOR_IMAGE environment variable in order to run the 12 | 'default' scenario 13 | when: not operator_image 14 | 15 | - name: Set testing image 16 | command: '{{ kustomize }} edit set image testing={{ operator_image }}' 17 | args: 18 | chdir: '{{ config_dir }}/testing' 19 | 20 | - name: Set pull policy 21 | command: '{{ kustomize }} edit add patch --path pull_policy/{{ operator_pull_policy }}.yaml' 22 | args: 23 | chdir: '{{ config_dir }}/testing' 24 | 25 | - name: Set testing namespace 26 | command: '{{ kustomize }} edit set namespace {{ namespace }}' 27 | args: 28 | chdir: '{{ config_dir }}/testing' 29 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/tasks/foo_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the cache.example.com/v1alpha1.Foo 3 | k8s: 4 | state: present 5 | namespace: '{{ namespace }}' 6 | definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}" 7 | wait: yes 8 | wait_timeout: 300 9 | wait_condition: 10 | type: Successful 11 | status: "True" 12 | vars: 13 | cr_file: 'cache_v1alpha1_foo.yaml' 14 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/tasks/memfin_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the cache.example.com/v1alpha1.Memfin 3 | k8s: 4 | state: present 5 | namespace: '{{ namespace }}' 6 | definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}" 7 | wait: yes 8 | wait_timeout: 300 9 | wait_condition: 10 | type: Successful 11 | status: "True" 12 | vars: 13 | cr_file: 'cache_v1alpha1_memfin.yaml' 14 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/default/verify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Verify 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | collections: 7 | - kubernetes.core 8 | 9 | vars: 10 | ctrl_label: control-plane=controller-manager 11 | 12 | tasks: 13 | - block: 14 | - name: Import all test files from tasks/ 15 | include_tasks: '{{ item }}' 16 | with_fileglob: 17 | - tasks/*_test.yml 18 | rescue: 19 | - name: Retrieve relevant resources 20 | k8s_info: 21 | api_version: '{{ item.api_version }}' 22 | kind: '{{ item.kind }}' 23 | namespace: '{{ namespace }}' 24 | loop: 25 | - api_version: v1 26 | kind: Pod 27 | - api_version: apps/v1 28 | kind: Deployment 29 | - api_version: v1 30 | kind: Secret 31 | - api_version: v1 32 | kind: ConfigMap 33 | register: debug_resources 34 | 35 | - name: Retrieve Pod logs 36 | k8s_log: 37 | name: '{{ item.metadata.name }}' 38 | namespace: '{{ namespace }}' 39 | container: manager 40 | loop: "{{ q('k8s', api_version='v1', kind='Pod', namespace=namespace, label_selector=ctrl_label) }}" 41 | register: debug_logs 42 | 43 | - name: Output gathered resources 44 | debug: 45 | var: debug_resources 46 | 47 | - name: Output gathered logs 48 | debug: 49 | var: item.log_lines 50 | loop: '{{ debug_logs.results }}' 51 | 52 | - name: Re-emit failure 53 | vars: 54 | failed_task: 55 | result: '{{ ansible_failed_result }}' 56 | fail: 57 | msg: '{{ failed_task }}' 58 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/kind/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | 7 | tasks: 8 | - name: Build operator image 9 | docker_image: 10 | build: 11 | path: '{{ project_dir }}' 12 | pull: no 13 | name: '{{ operator_image }}' 14 | tag: latest 15 | push: no 16 | source: build 17 | force_source: yes 18 | 19 | - name: Load image into kind cluster 20 | command: kind load docker-image --name osdk-test '{{ operator_image }}' 21 | register: result 22 | changed_when: '"not yet present" in result.stdout' 23 | 24 | - import_playbook: ../default/converge.yml 25 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/kind/create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | tasks: 7 | - name: Create test kind cluster 8 | command: kind create cluster --name osdk-test --kubeconfig {{ kubeconfig }} 9 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/kind/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | collections: 7 | - kubernetes.core 8 | 9 | tasks: 10 | - name: Destroy test kind cluster 11 | command: kind delete cluster --name osdk-test --kubeconfig {{ kubeconfig }} 12 | 13 | - name: Unset pull policy 14 | command: '{{ kustomize }} edit remove patch pull_policy/{{ operator_pull_policy }}.yaml' 15 | args: 16 | chdir: '{{ config_dir }}/testing' 17 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/molecule/kind/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: delegated 6 | platforms: 7 | - name: cluster 8 | groups: 9 | - k8s 10 | provisioner: 11 | name: ansible 12 | playbooks: 13 | prepare: ../default/prepare.yml 14 | verify: ../default/verify.yml 15 | inventory: 16 | group_vars: 17 | all: 18 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 19 | host_vars: 20 | localhost: 21 | ansible_python_interpreter: '{{ ansible_playbook_python }}' 22 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 23 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 24 | project_dir: ${MOLECULE_PROJECT_DIRECTORY} 25 | operator_image: testing-operator 26 | operator_pull_policy: "Never" 27 | kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" 28 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 29 | env: 30 | K8S_AUTH_KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 31 | KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 32 | verifier: 33 | name: ansible 34 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/playbooks/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/playbooks/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/playbooks/foo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | collections: 5 | - kubernetes.core 6 | - operator_sdk.util 7 | tasks: 8 | - import_role: 9 | name: "foo" 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/playbooks/memcached.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | collections: 5 | - kubernetes.core 6 | - operator_sdk.util 7 | tasks: 8 | - import_role: 9 | name: "memcached" 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/playbooks/memfin.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | collections: 5 | - kubernetes.core 6 | - operator_sdk.util 7 | tasks: 8 | - import_role: 9 | name: "memfin" 10 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: operator_sdk.util 4 | version: "0.5.0" 5 | - name: kubernetes.core 6 | version: "3.2.0" 7 | - name: cloud.common 8 | version: "3.0.0" 9 | - name: community.docker 10 | version: "3.12.1" 11 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, 10 | if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 11 | 12 | Role Variables 13 | -------------- 14 | 15 | A description of the settable variables for this role should go here, including any variables that are in 16 | defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables 17 | that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well 18 | 19 | Dependencies 20 | ------------ 21 | 22 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set 23 | for other roles, or variables that are used from other roles. 24 | 25 | Example Playbook 26 | ---------------- 27 | 28 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for 29 | users too: 30 | 31 | - hosts: servers 32 | roles: 33 | - { role: username.rolename, x: 42 } 34 | 35 | License 36 | ------- 37 | 38 | BSD 39 | 40 | Author Information 41 | ------------------ 42 | 43 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 44 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for Foo 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/foo/files/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for Foo 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: your name 4 | description: your description 5 | company: your company (optional) 6 | 7 | # If the issue tracker for your role is not on github, uncomment the 8 | # next line and provide a value 9 | # issue_tracker_url: http://example.com/issue/tracker 10 | 11 | # Some suggested licenses: 12 | # - BSD (default) 13 | # - MIT 14 | # - GPLv2 15 | # - GPLv3 16 | # - Apache 17 | # - CC-BY 18 | license: license (GPLv2, CC-BY, etc) 19 | 20 | min_ansible_version: 2.9 21 | 22 | # If this a Container Enabled role, provide the minimum Ansible Container version. 23 | # min_ansible_container_version: 24 | 25 | # Optionally specify the branch Galaxy will use when accessing the GitHub 26 | # repo for this role. During role install, if no tags are available, 27 | # Galaxy will use this branch. During import Galaxy will access files on 28 | # this branch. If Travis integration is configured, only notifications for this 29 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 30 | # (usually master) will be used. 31 | #github_branch: 32 | 33 | # 34 | # Provide a list of supported platforms, and for each platform a list of versions. 35 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 36 | # To view available platforms and versions (or releases), visit: 37 | # https://galaxy.ansible.com/api/v1/platforms/ 38 | # 39 | # platforms: 40 | # - name: Fedora 41 | # versions: 42 | # - all 43 | # - 25 44 | # - name: SomePlatform 45 | # versions: 46 | # - all 47 | # - 1.0 48 | # - 7 49 | # - 99.99 50 | 51 | galaxy_tags: [] 52 | # List tags for your role here, one per line. A tag is a keyword that describes 53 | # and categorizes the role. Users find roles by searching for tags. Be sure to 54 | # remove the '[]' above, if you add tags to this list. 55 | # 56 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 57 | # Maximum 20 tags per role. 58 | 59 | dependencies: [] 60 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 61 | # if you add dependencies to this list. 62 | collections: 63 | - operator_sdk.util 64 | - kubernetes.core 65 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for Foo 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/foo/templates/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/foo/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for Foo 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memcached/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, 10 | if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 11 | 12 | Role Variables 13 | -------------- 14 | 15 | A description of the settable variables for this role should go here, including any variables that are in 16 | defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables 17 | that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well 18 | 19 | Dependencies 20 | ------------ 21 | 22 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set 23 | for other roles, or variables that are used from other roles. 24 | 25 | Example Playbook 26 | ---------------- 27 | 28 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for 29 | users too: 30 | 31 | - hosts: servers 32 | roles: 33 | - { role: username.rolename, x: 42 } 34 | 35 | License 36 | ------- 37 | 38 | BSD 39 | 40 | Author Information 41 | ------------------ 42 | 43 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 44 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memcached/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | size: 1 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memcached/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/memcached/files/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memcached/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for Memcached 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memcached/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: your name 4 | description: your description 5 | company: your company (optional) 6 | 7 | # If the issue tracker for your role is not on github, uncomment the 8 | # next line and provide a value 9 | # issue_tracker_url: http://example.com/issue/tracker 10 | 11 | # Some suggested licenses: 12 | # - BSD (default) 13 | # - MIT 14 | # - GPLv2 15 | # - GPLv3 16 | # - Apache 17 | # - CC-BY 18 | license: license (GPLv2, CC-BY, etc) 19 | 20 | min_ansible_version: 2.9 21 | 22 | # If this a Container Enabled role, provide the minimum Ansible Container version. 23 | # min_ansible_container_version: 24 | 25 | # Optionally specify the branch Galaxy will use when accessing the GitHub 26 | # repo for this role. During role install, if no tags are available, 27 | # Galaxy will use this branch. During import Galaxy will access files on 28 | # this branch. If Travis integration is configured, only notifications for this 29 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 30 | # (usually master) will be used. 31 | #github_branch: 32 | 33 | # 34 | # Provide a list of supported platforms, and for each platform a list of versions. 35 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 36 | # To view available platforms and versions (or releases), visit: 37 | # https://galaxy.ansible.com/api/v1/platforms/ 38 | # 39 | # platforms: 40 | # - name: Fedora 41 | # versions: 42 | # - all 43 | # - 25 44 | # - name: SomePlatform 45 | # versions: 46 | # - all 47 | # - 1.0 48 | # - 7 49 | # - 99.99 50 | 51 | galaxy_tags: [] 52 | # List tags for your role here, one per line. A tag is a keyword that describes 53 | # and categorizes the role. Users find roles by searching for tags. Be sure to 54 | # remove the '[]' above, if you add tags to this list. 55 | # 56 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 57 | # Maximum 20 tags per role. 58 | 59 | dependencies: [] 60 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 61 | # if you add dependencies to this list. 62 | collections: 63 | - operator_sdk.util 64 | - kubernetes.core 65 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memcached/templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/memcached/templates/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memcached/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for Memcached 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, 10 | if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 11 | 12 | Role Variables 13 | -------------- 14 | 15 | A description of the settable variables for this role should go here, including any variables that are in 16 | defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables 17 | that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well 18 | 19 | Dependencies 20 | ------------ 21 | 22 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set 23 | for other roles, or variables that are used from other roles. 24 | 25 | Example Playbook 26 | ---------------- 27 | 28 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for 29 | users too: 30 | 31 | - hosts: servers 32 | roles: 33 | - { role: username.rolename, x: 42 } 34 | 35 | License 36 | ------- 37 | 38 | BSD 39 | 40 | Author Information 41 | ------------------ 42 | 43 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 44 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for Memfin 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/memfin/files/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for Memfin 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: your name 4 | description: your description 5 | company: your company (optional) 6 | 7 | # If the issue tracker for your role is not on github, uncomment the 8 | # next line and provide a value 9 | # issue_tracker_url: http://example.com/issue/tracker 10 | 11 | # Some suggested licenses: 12 | # - BSD (default) 13 | # - MIT 14 | # - GPLv2 15 | # - GPLv3 16 | # - Apache 17 | # - CC-BY 18 | license: license (GPLv2, CC-BY, etc) 19 | 20 | min_ansible_version: 2.9 21 | 22 | # If this a Container Enabled role, provide the minimum Ansible Container version. 23 | # min_ansible_container_version: 24 | 25 | # Optionally specify the branch Galaxy will use when accessing the GitHub 26 | # repo for this role. During role install, if no tags are available, 27 | # Galaxy will use this branch. During import Galaxy will access files on 28 | # this branch. If Travis integration is configured, only notifications for this 29 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 30 | # (usually master) will be used. 31 | #github_branch: 32 | 33 | # 34 | # Provide a list of supported platforms, and for each platform a list of versions. 35 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 36 | # To view available platforms and versions (or releases), visit: 37 | # https://galaxy.ansible.com/api/v1/platforms/ 38 | # 39 | # platforms: 40 | # - name: Fedora 41 | # versions: 42 | # - all 43 | # - 25 44 | # - name: SomePlatform 45 | # versions: 46 | # - all 47 | # - 1.0 48 | # - 7 49 | # - 99.99 50 | 51 | galaxy_tags: [] 52 | # List tags for your role here, one per line. A tag is a keyword that describes 53 | # and categorizes the role. Users find roles by searching for tags. Be sure to 54 | # remove the '[]' above, if you add tags to this list. 55 | # 56 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 57 | # Maximum 20 tags per role. 58 | 59 | dependencies: [] 60 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 61 | # if you add dependencies to this list. 62 | collections: 63 | - operator_sdk.util 64 | - kubernetes.core 65 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: delete configmap for test 3 | kubernetes.core.k8s: 4 | kind: ConfigMap 5 | api_version: v1 6 | name: deleteme 7 | namespace: default 8 | state: absent 9 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/memfin/templates/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/memfin/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for Memfin 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, 10 | if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 11 | 12 | Role Variables 13 | -------------- 14 | 15 | A description of the settable variables for this role should go here, including any variables that are in 16 | defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables 17 | that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well 18 | 19 | Dependencies 20 | ------------ 21 | 22 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set 23 | for other roles, or variables that are used from other roles. 24 | 25 | Example Playbook 26 | ---------------- 27 | 28 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for 29 | users too: 30 | 31 | - hosts: servers 32 | roles: 33 | - { role: username.rolename, x: 42 } 34 | 35 | License 36 | ------- 37 | 38 | BSD 39 | 40 | Author Information 41 | ------------------ 42 | 43 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 44 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for Secret 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/secret/files/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for Secret 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: your name 4 | description: your description 5 | company: your company (optional) 6 | 7 | # If the issue tracker for your role is not on github, uncomment the 8 | # next line and provide a value 9 | # issue_tracker_url: http://example.com/issue/tracker 10 | 11 | # Some suggested licenses: 12 | # - BSD (default) 13 | # - MIT 14 | # - GPLv2 15 | # - GPLv3 16 | # - Apache 17 | # - CC-BY 18 | license: license (GPLv2, CC-BY, etc) 19 | 20 | min_ansible_version: 2.9 21 | 22 | # If this a Container Enabled role, provide the minimum Ansible Container version. 23 | # min_ansible_container_version: 24 | 25 | # Optionally specify the branch Galaxy will use when accessing the GitHub 26 | # repo for this role. During role install, if no tags are available, 27 | # Galaxy will use this branch. During import Galaxy will access files on 28 | # this branch. If Travis integration is configured, only notifications for this 29 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 30 | # (usually master) will be used. 31 | #github_branch: 32 | 33 | # 34 | # Provide a list of supported platforms, and for each platform a list of versions. 35 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 36 | # To view available platforms and versions (or releases), visit: 37 | # https://galaxy.ansible.com/api/v1/platforms/ 38 | # 39 | # platforms: 40 | # - name: Fedora 41 | # versions: 42 | # - all 43 | # - 25 44 | # - name: SomePlatform 45 | # versions: 46 | # - all 47 | # - 1.0 48 | # - 7 49 | # - 99.99 50 | 51 | galaxy_tags: [] 52 | # List tags for your role here, one per line. A tag is a keyword that describes 53 | # and categorizes the role. Users find roles by searching for tags. Be sure to 54 | # remove the '[]' above, if you add tags to this list. 55 | # 56 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 57 | # Maximum 20 tags per role. 58 | 59 | dependencies: [] 60 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 61 | # if you add dependencies to this list. 62 | collections: 63 | - operator_sdk.util 64 | - kubernetes.core 65 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Create test service 2 | kubernetes.core.k8s: 3 | definition: 4 | kind: Service 5 | api_version: v1 6 | metadata: 7 | name: test-service 8 | namespace: default 9 | spec: 10 | ports: 11 | - protocol: TCP 12 | port: 8332 13 | targetPort: 8332 14 | name: rpc 15 | 16 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/ansible-operator-plugins/87d6d1f8c369f5f538ce6f230c891bb9f4e94f12/testdata/memcached-molecule-operator/roles/secret/templates/.placeholder -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/roles/secret/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for Secret 3 | -------------------------------------------------------------------------------- /testdata/memcached-molecule-operator/watches.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Use the 'create api' subcommand to add watches to this file. 3 | - version: v1alpha1 4 | group: cache.example.com 5 | kind: Memcached 6 | playbook: playbooks/memcached.yml 7 | finalizer: 8 | name: cache.example.com/finalizer 9 | role: memfin 10 | blacklist: 11 | - group: "" 12 | version: v1 13 | kind: ConfigMap 14 | - version: v1alpha1 15 | group: cache.example.com 16 | kind: Foo 17 | playbook: playbooks/foo.yml 18 | - version: v1alpha1 19 | group: cache.example.com 20 | kind: Memfin 21 | playbook: playbooks/memfin.yml 22 | - version: v1 23 | group: "" 24 | kind: Secret 25 | role: secret 26 | manageStatus: false 27 | # +kubebuilder:scaffold:watch 28 | -------------------------------------------------------------------------------- /tools/scripts/fetch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ROOT="$( git rev-parse --show-toplevel )" 4 | DEST="${ROOT}/tools/bin" 5 | 6 | fetch() { 7 | local tool=$1; shift 8 | local ver=$1; shift 9 | 10 | local arch="$(uname -m)" 11 | case "$arch" in 12 | x86_64) arch="amd64" ;; 13 | aarch64) arch="arm64" ;; 14 | *);; 15 | esac 16 | local os="$(uname -s | awk '{ print tolower($0) }')" 17 | 18 | local ver_cmd="" 19 | local fetch_cmd="" 20 | case "$tool" in 21 | "kubectl") 22 | ver_cmd="${DEST}/kubectl version 2>/dev/null | grep Client | cut -d' ' -f5 | sed 's/\w\+:\"v\(.*\)\",/\1/'" 23 | fetch_cmd="(curl -sSfLo '${DEST}/kubectl' 'https://dl.k8s.io/release/v${ver}/bin/${os}/${arch}/kubectl' && chmod +x ${DEST}/kubectl)" 24 | ;; 25 | *) 26 | echo "unknown tool $tool" 27 | return 1 28 | ;; 29 | esac 30 | 31 | if [[ "${ver}" != "$(eval ${ver_cmd})" ]]; then 32 | echo "${tool} missing or not version '${ver}', downloading..." 33 | mkdir -p ${DEST} 34 | eval ${fetch_cmd} 35 | fi 36 | } 37 | 38 | fetch $@ 39 | -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | // +build tools 2 | 3 | package tools 4 | 5 | import ( 6 | _ "github.com/maxbrunsfeld/counterfeiter/v6" 7 | ) 8 | --------------------------------------------------------------------------------