Bug 1866261 - Need to indicate the intentional behavior for Ansible in the `create api` help info
Summary: Need to indicate the intentional behavior for Ansible in the `create api` hel...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: OpenShift Container Platform
Classification: Red Hat
Component: Operator SDK
Version: 4.6
Hardware: Unspecified
OS: Unspecified
unspecified
medium
Target Milestone: ---
: 4.7.0
Assignee: amacdona@redhat.com
QA Contact: Jian Zhang
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-08-05 08:55 UTC by Jian Zhang
Modified: 2021-02-24 15:14 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-02-24 15:14:01 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2020:5633 0 None None None 2021-02-24 15:14:42 UTC

Description Jian Zhang 2020-08-05 08:55:47 UTC
Description of problem:
Failed to run the Ansible operator by using the `make run`.

Version-Release number of selected component (if applicable):
[root@preserve-olm-env nginx-operator-ansible]# operator-sdk version
operator-sdk version: "v1.0.0-alpha.2-4-gce96b75", commit: "ce96b751a9e377e4e138e76356bf2409ac1fc457", kubernetes version: "v1.18.2", go version: "go1.14 linux/amd64", GOOS: "linux", GOARCH: "amd64"

How reproducible:
always

Steps to Reproduce:
1. Install the operator-sdk.
2. Login the OCP 4.6.
3. Create a Ansible type operator.
[root@preserve-olm-env memcached-operator]# operator-sdk init --project-name memcached-operator --plugins "ansible.sdk.operatorframework.io/v1" 
Next: define a resource with:
$ operator-sdk create api
[root@preserve-olm-env memcached-operator]# ls
config  Dockerfile  Makefile  molecule  playbooks  PROJECT  requirements.yml  roles  watches.yaml
[root@preserve-olm-env memcached-operator]# operator-sdk create api --group apps --version v1beta1 --kind Memcached
[root@preserve-olm-env memcached-operator]# vim Makefile 
[root@preserve-olm-env memcached-operator]# make install
/usr/local/go/bin/kustomize build config/crd | oc apply -f -
customresourcedefinition.apiextensions.k8s.io/memcacheds.apps.my.domain created


4, Run this operator.
[root@preserve-olm-env memcached-operator]# make run
/usr/local/go/bin/ansible-operator run
{"level":"info","ts":1596617372.0929112,"logger":"cmd","msg":"Version","Go Version":"go1.14","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.0.0-alpha.2+git"}
{"level":"info","ts":1596617372.0957646,"logger":"cmd","msg":"WATCH_NAMESPACE environment variable not set. Watching all namespaces.","Namespace":""}
I0805 04:49:33.212094    9035 request.go:621] Throttling request took 1.010798418s, request: GET:https://api.qe-jiazha464.qe.devcluster.openshift.com:6443/apis/build.openshift.io/v1?timeout=32s
..

Actual results:
It failed. Got the below errors:
...
{"level":"info","ts":1596617374.8367717,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"}
{"level":"info","ts":1596617374.8374665,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_APPS_MY_DOMAIN","default":2}
{"level":"error","ts":1596617374.8375247,"logger":"watches","msg":"Invalid ansible path for GVK: apps.my.domain/v1beta1, Kind=Memcached","error":"must specify Role or Playbook","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\tpkg/mod/github.com/go-logr/zapr.0/zapr.go:128\ngithub.com/operator-framework/operator-sdk/internal/ansible/watches.(*Watch).Validate\n\tsrc/github.com/operator-framework/operator-sdk/internal/ansible/watches/watches.go:282\ngithub.com/operator-framework/operator-sdk/internal/ansible/watches.Load\n\tsrc/github.com/operator-framework/operator-sdk/internal/ansible/watches/watches.go:364\ngithub.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run.run\n\tsrc/github.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run/cmd.go:158\ngithub.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run.NewCmd.func1\n\tsrc/github.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run/cmd.go:72\ngithub.com/spf13/cobra.(*Command).execute\n\tpkg/mod/github.com/spf13/cobra.0/command.go:846\ngithub.com/spf13/cobra.(*Command).ExecuteC\n\tpkg/mod/github.com/spf13/cobra.0/command.go:950\ngithub.com/spf13/cobra.(*Command).Execute\n\tpkg/mod/github.com/spf13/cobra.0/command.go:887\nmain.main\n\tsrc/github.com/operator-framework/operator-sdk/cmd/ansible-operator/main.go:34\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:203"}
{"level":"error","ts":1596617374.837628,"logger":"watches","msg":"Watch with GVK apps.my.domain/v1beta1, Kind=Memcached failed validation","error":"must specify Role or Playbook","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\tpkg/mod/github.com/go-logr/zapr.0/zapr.go:128\ngithub.com/operator-framework/operator-sdk/internal/ansible/watches.Load\n\tsrc/github.com/operator-framework/operator-sdk/internal/ansible/watches/watches.go:366\ngithub.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run.run\n\tsrc/github.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run/cmd.go:158\ngithub.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run.NewCmd.func1\n\tsrc/github.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run/cmd.go:72\ngithub.com/spf13/cobra.(*Command).execute\n\tpkg/mod/github.com/spf13/cobra.0/command.go:846\ngithub.com/spf13/cobra.(*Command).ExecuteC\n\tpkg/mod/github.com/spf13/cobra.0/command.go:950\ngithub.com/spf13/cobra.(*Command).Execute\n\tpkg/mod/github.com/spf13/cobra.0/command.go:887\nmain.main\n\tsrc/github.com/operator-framework/operator-sdk/cmd/ansible-operator/main.go:34\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:203"}
{"level":"error","ts":1596617374.8376646,"logger":"cmd","msg":"Failed to load watches.","Namespace":"","error":"must specify Role or Playbook","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\tpkg/mod/github.com/go-logr/zapr.0/zapr.go:128\ngithub.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run.run\n\tsrc/github.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run/cmd.go:160\ngithub.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run.NewCmd.func1\n\tsrc/github.com/operator-framework/operator-sdk/internal/cmd/ansible-operator/run/cmd.go:72\ngithub.com/spf13/cobra.(*Command).execute\n\tpkg/mod/github.com/spf13/cobra.0/command.go:846\ngithub.com/spf13/cobra.(*Command).ExecuteC\n\tpkg/mod/github.com/spf13/cobra.0/command.go:950\ngithub.com/spf13/cobra.(*Command).Execute\n\tpkg/mod/github.com/spf13/cobra.0/command.go:887\nmain.main\n\tsrc/github.com/operator-framework/operator-sdk/cmd/ansible-operator/main.go:34\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:203"}
make: *** [run] Error 1


Expected results:
It should work.

Additional info:

Comment 1 amacdona@redhat.com 2020-08-05 14:26:37 UTC
This behavior is intentional. When running `create api` without `--generate-role` or `--generate-playbook` the watches file cannot be scaffolded with a role or playbook, so we use a #FIXME comment.

watches.yaml
---
# Use the 'create api' subcommand to add watches to this file.
- version: v1alpha1
  group: cache.example.com
  kind: Memcached
  # FIXME: Specify the role or playbook for this resource.
# +kubebuilder:scaffold:watch

To do a sanity check like this, use `--generate-role` or `--generate-playbook`.

Comment 2 Jian Zhang 2020-08-06 09:41:20 UTC
Thanks Austin! It works well after I set the "--generate-role --generate-playbook" flags.


[root@preserve-olm-env memcached-operator]# operator-sdk init --project-name memcached-operator --plugins "ansible.sdk.operatorframework.io/v1" 
Next: define a resource with:
$ operator-sdk create api

[root@preserve-olm-env memcached-operator]# operator-sdk create api --group apps --version v1beta1 --kind Memcached --generate-role --generate-playbook
[root@preserve-olm-env memcached-operator]# cat watches.yaml 
---
# Use the 'create api' subcommand to add watches to this file.
- version: v1beta1
  group: apps.my.domain
  kind: Memcached
  playbook: playbooks/memcached.yml
# +kubebuilder:scaffold:watch

[root@preserve-olm-env memcached-operator]# vim Makefile 
[root@preserve-olm-env memcached-operator]# make install
/usr/local/go/bin/kustomize build config/crd | oc apply -f -
customresourcedefinition.apiextensions.k8s.io/memcacheds.apps.my.domain created

[root@preserve-olm-env memcached-operator]# make run
/usr/local/go/bin/ansible-operator run
{"level":"info","ts":1596705928.2306075,"logger":"cmd","msg":"Version","Go Version":"go1.14","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.0.0-alpha.2+git"}
{"level":"info","ts":1596705928.2336016,"logger":"cmd","msg":"WATCH_NAMESPACE environment variable not set. Watching all namespaces.","Namespace":""}
I0806 05:25:30.002644   22390 request.go:621] Throttling request took 1.04921705s, request: GET:https://api.qe-jiazha77.qe.devcluster.openshift.com:6443/apis/samples.operator.openshift.io/v1?timeout=32s
{"level":"info","ts":1596705931.435945,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"}
{"level":"info","ts":1596705931.437807,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_APPS_MY_DOMAIN","default":2}
{"level":"info","ts":1596705931.4378943,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false}
{"level":"info","ts":1596705931.4379318,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"apps.my.domain","Options.Version":"v1beta1","Options.Kind":"Memcached"}
{"level":"info","ts":1596705931.444073,"l

In antoher terminal, create a CR.
[root@preserve-olm-env memcached-operator]# cat config/samples/apps_v1beta1_memcached.yaml 
apiVersion: apps.my.domain/v1beta1
kind: Memcached
metadata:
  name: memcached-sample
spec:
  foo: bar
[root@preserve-olm-env memcached-operator]# oc create -f config/samples/apps_v1beta1_memcached.yaml -n default
memcached.apps.my.domain/memcached-sample created
[root@preserve-olm-env memcached-operator]# oc get memcached -n default
NAME               AGE
memcached-sample   12s

[root@preserve-olm-env memcached-operator]# oc delete memcached memcached-sample -n default
memcached.apps.my.domain "memcached-sample" deleted
[root@preserve-olm-env memcached-operator]# oc get memcached -A
No resources found

It looks good to me. But, as an end user, I cound't find this intentional behavior. Can we update the help info to add this infomation? Thanks! Reopen it.

[root@preserve-olm-env memcached-operator]# operator-sdk create api --help
Scaffold a Kubernetes API in which the controller is an Ansible role or playbook.

    - generates a Custom Resource Definition and sample
    - Updates watches.yaml
    - optionally generates Ansible Role tree
    - optionally generates Ansible playbook

Usage:
  operator-sdk create api [flags]

Examples:
# Create a new API, without Ansible roles or playbooks
  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService \
      --generate-role

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService \
      --generate-playbook

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService
      --generate-playbook
      --generate-role


Flags:
      --group string         resource group
      --version string       resource version
      --kind string          resource kind
      --crd-version string   crd version to generate (default "v1")
      --generate-playbook    Generate an Ansible playbook. If passed with --generate-role, the playbook will invoke the role.
      --generate-role        Generate an Ansible role skeleton.
  -h, --help                 help for api

Global Flags:
      --verbose   Enable verbose logging

Comment 3 amacdona@redhat.com 2020-08-06 15:20:56 UTC
Thanks Jian, the docs could be clearer. I've added "For the scaffolded operator to be runnable with no changes, specify either --generate-role or --generate-playbook." to the helptext.

https://github.com/operator-framework/operator-sdk/pull/3662

Comment 4 Jesus M. Rodriguez 2020-08-20 02:23:26 UTC
Fixed in v1.0.0-7-g34fe8037 or later. I used v1.0.0-29-g5cf9e6c5 for this example:

$ operator-sdk version
operator-sdk version: "v1.0.0-29-g5cf9e6c5", commit: "5cf9e6c57502230f3e432216215d9aa183a57fcb", kubernetes version: "v1.18.2", go version: "go1.13.11 linux/amd64", GOOS: "linux", GOARCH: "amd64"

============
$ operator-sdk create api --help
Scaffold a Kubernetes API in which the controller is an Ansible role or playbook.

    - generates a Custom Resource Definition and sample
    - Updates watches.yaml
    - optionally generates Ansible Role tree
    - optionally generates Ansible playbook

    For the scaffolded operator to be runnable with no changes, specify either --generate-role or --generate-playbook.

Usage:
  operator-sdk create api [flags]

Examples:
# Create a new API, without Ansible roles or playbooks
  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService \
      --generate-role

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService \
      --generate-playbook

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService
      --generate-playbook
      --generate-role


Flags:
      --group string         resource group
      --version string       resource version
      --kind string          resource kind
      --crd-version string   crd version to generate (default "v1")
      --generate-playbook    Generate an Ansible playbook. If passed with --generate-role, the playbook will invoke the role.
      --generate-role        Generate an Ansible role skeleton.
  -h, --help                 help for api

Global Flags:
      --verbose   Enable verbose logging

Comment 8 Jian Zhang 2020-08-21 02:08:39 UTC
Thanks! But, as follows, I use the latest version, and couldn't find any help info now. Any big changes? Thanks!

[root@preserve-olm-env data]# operator-sdk version
operator-sdk version: "v1.0.0-alpha.2-53-ge3b1cc0", commit: "e3b1cc0dff990cfc5d615630f033e0e2c8033a54", kubernetes version: "v1.18.2", go version: "go1.14 linux/amd64", GOOS: "linux", GOARCH: "amd64"


[root@preserve-olm-env data]# operator-sdk create api --help
Scaffold a Kubernetes API.

For project-specific information, run this command in the root directory of a
project.

Note: unable to find configuration file, project must be initialized

Usage:
  operator-sdk create api [flags]

Flags:
  -h, --help   help for api

Global Flags:
      --verbose   Enable verbose logging


[root@preserve-olm-env data]# operator-sdk create api --generate-role --help
Error: unknown flag: --generate-role
Usage:
  operator-sdk create api [flags]

Flags:
  -h, --help   help for api

Global Flags:
      --verbose   Enable verbose logging

FATA[0000] unknown flag: --generate-role

Comment 9 Jesus M. Rodriguez 2020-08-21 14:37:50 UTC
this is not a 4.6  bug since this affect operator-sdk 1.0, moving to 4.7.

Comment 11 amacdona@redhat.com 2020-08-25 14:54:22 UTC
The CLI dynamically changes if a project has been created. In this case, `create api` cannot be run because a project has not yet been initialized, and the `create api` options are specific to only ansible operators.

To see the help text for `create api`, you will first need to initialize a project. The error message you saw seems correct to me:

[root@preserve-olm-env data]# operator-sdk create api --help
Scaffold a Kubernetes API.

For project-specific information, run this command in the root directory of a
project.

Note: unable to find configuration file, project must be initialized

Comment 12 Jian Zhang 2020-08-27 07:13:53 UTC
Thanks! LGTM, verify it. Details:
[root@preserve-olm-env operator-sdk]# operator-sdk version
operator-sdk version: "v1.0.0-alpha.2-62-ga9d6b1b", commit: "a9d6b1bb561e22a6a78996ca86acbd6a59cc24c3", kubernetes version: "v1.18.2", go version: "go1.14 linux/amd64", GOOS: "linux", GOARCH: "amd64"

[root@preserve-olm-env bug2-operator]# operator-sdk init bug-operator --plugins ansible.sdk.operatorframework.io/v1
Next: define a resource with:
$ operator-sdk create api
[root@preserve-olm-env bug2-operator]# operator-sdk create api --help
Scaffold a Kubernetes API in which the controller is an Ansible role or playbook.

    - generates a Custom Resource Definition and sample
    - Updates watches.yaml
    - optionally generates Ansible Role tree
    - optionally generates Ansible playbook

    For the scaffolded operator to be runnable with no changes, specify either --generate-role or --generate-playbook.

Usage:
  operator-sdk create api [flags]

Examples:
# Create a new API, without Ansible roles or playbooks
  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService \
      --generate-role

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService \
      --generate-playbook

  $ operator-sdk create api \
      --group=apps --version=v1alpha1 \
      --kind=AppService
      --generate-playbook
      --generate-role


Flags:
      --group string         resource group
      --version string       resource version
      --kind string          resource kind
      --crd-version string   crd version to generate (default "v1")
      --generate-playbook    Generate an Ansible playbook. If passed with --generate-role, the playbook will invoke the role.
      --generate-role        Generate an Ansible role skeleton.
  -h, --help                 help for api

Global Flags:
      --verbose   Enable verbose logging

Comment 16 errata-xmlrpc 2021-02-24 15:14:01 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (Moderate: OpenShift Container Platform 4.7.0 security, bug fix, and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2020:5633


Note You need to log in before you can comment on or make changes to this bug.