├── .ansible-lint ├── .github └── workflows │ ├── build-operator-image.yaml │ ├── ci.yaml │ └── kind-awx.yaml ├── .gitignore ├── .yamllint ├── Dockerfile ├── Dockerfile.runner ├── Makefile ├── PROJECT ├── README.md ├── config ├── crd │ ├── bases │ │ ├── tower.ansible.com_ansiblecredentials.yaml │ │ ├── tower.ansible.com_ansibleinstancegroups.yaml │ │ ├── tower.ansible.com_ansibleinventories.yaml │ │ ├── tower.ansible.com_ansiblejobs.yaml │ │ ├── tower.ansible.com_ansibleprojects.yaml │ │ ├── tower.ansible.com_ansibleschedules.yaml │ │ ├── tower.ansible.com_ansibleworkflows.yaml │ │ ├── tower.ansible.com_jobtemplates.yaml │ │ └── tower.ansible.com_workflowtemplates.yaml │ └── kustomization.yaml ├── default │ ├── kustomization.yaml │ ├── manager_auth_proxy_patch.yaml │ └── manager_config_patch.yaml ├── manager │ ├── controller_manager_config.yaml │ ├── kustomization.yaml │ └── manager.yaml ├── manifests │ ├── bases │ │ ├── annotations.yaml │ │ ├── awx-resource-operator.clusterserviceversion.yaml │ │ └── inject-custom-annotations.py │ └── kustomization.yaml ├── prometheus │ ├── kustomization.yaml │ └── monitor.yaml ├── rbac │ ├── ansiblecredential_editor_role.yaml │ ├── ansiblecredential_viewer_role.yaml │ ├── ansibleinstancegroup_editor_role.yaml │ ├── ansibleinstancegroup_viewer_role.yaml │ ├── ansiblejob_editor_role.yaml │ ├── ansiblejob_viewer_role.yaml │ ├── ansibleproject_editor_role.yaml │ ├── ansibleproject_viewer_role.yaml │ ├── ansibleschedule_editor_role.yaml │ ├── ansibleschedule_viewer_role.yaml │ ├── ansibleworkflow_editor_role.yaml │ ├── ansibleworkflow_viewer_role.yaml │ ├── auth_proxy_client_clusterrole.yaml │ ├── auth_proxy_role.yaml │ ├── auth_proxy_role_binding.yaml │ ├── auth_proxy_service.yaml │ ├── inventory_editor_role.yaml │ ├── inventory_viewer_role.yaml │ ├── jobtemplate_editor_role.yaml │ ├── jobtemplate_viewer_role.yaml │ ├── kustomization.yaml │ ├── leader_election_role.yaml │ ├── leader_election_role_binding.yaml │ ├── role.yaml │ ├── role_binding.yaml │ ├── service_account.yaml │ ├── workflowtemplate_editor_role.yaml │ └── workflowtemplate_viewer_role.yaml ├── samples │ ├── credentials │ │ ├── kustomization.yaml │ │ ├── tower_v1alpha1_ansiblecredential-aws.yaml │ │ ├── tower_v1alpha1_ansiblecredential-bearer.yaml │ │ ├── tower_v1alpha1_ansiblecredential-broken.yaml │ │ ├── tower_v1alpha1_ansiblecredential-git.yaml │ │ ├── tower_v1alpha1_ansiblecredential-sc.yaml │ │ └── tower_v1alpha1_ansiblecredential-ssh.yaml │ ├── instancegroup │ │ ├── kustomization.yaml │ │ ├── tower_v1alpha1_ansiblecontainergroup.yaml │ │ └── tower_v1alpha1_ansibleinstancegroup.yaml │ ├── inventory │ │ ├── kustomization.yaml │ │ ├── tower_v1alpha1_ansibleinventory-clone.yaml │ │ └── tower_v1alpha1_ansibleinventory-new.yaml │ ├── jobtemplate │ │ ├── kustomization.yaml │ │ ├── tower_v1alpha1_jobtemplate-broken.yaml │ │ ├── tower_v1alpha1_jobtemplate.yaml │ │ └── tower_v1alpha1_jobtemplate_deprecated.yaml │ ├── kustomization.yaml │ ├── projects │ │ ├── kustomization.yaml │ │ ├── tower_v1alpha1_ansibleproject-archive.yaml │ │ ├── tower_v1alpha1_ansibleproject-git-cred.yaml │ │ └── tower_v1alpha1_ansibleproject-git.yaml │ ├── tower_v1alpha1_ansiblejob-broken-dep.yaml │ ├── tower_v1alpha1_ansiblejob-broken.yaml │ ├── tower_v1alpha1_ansiblejob-dep.yaml │ ├── tower_v1alpha1_ansiblejob.yaml │ ├── tower_v1alpha1_ansibleschedule.yaml │ ├── workflow │ │ ├── kustomization.yaml │ │ ├── tower_v1alpha1_ansibleworkflow-broken.yaml │ │ └── tower_v1alpha1_ansibleworkflow.yaml │ └── workflowtemplate │ │ ├── kustomization.yaml │ │ ├── tower_v1alpha1_workflowtemplate-broken.yaml │ │ └── tower_v1alpha1_workflowtemplate.yaml ├── scorecard │ ├── bases │ │ └── config.yaml │ ├── kustomization.yaml │ └── patches │ │ ├── basic.config.yaml │ │ └── olm.config.yaml └── testing │ ├── debug_logs_patch.yaml │ ├── kustomization.yaml │ ├── manager_image.yaml │ └── pull_policy │ ├── Always.yaml │ ├── IfNotPresent.yaml │ └── Never.yaml ├── dev └── create_oauth2_token.yml ├── docs ├── development.md └── images │ └── on-launch-configuration.png ├── down.sh ├── molecule ├── default │ ├── converge.yml │ ├── create.yml │ ├── destroy.yml │ ├── kustomize.yml │ ├── molecule.yml │ ├── prepare.yml │ ├── tasks │ │ ├── ansiblecredential_test.yml │ │ ├── ansibleinstancegroup_test.yml │ │ ├── ansiblejob_test.yml │ │ ├── ansibleproject_test.yml │ │ ├── ansibleschedule_test.yml │ │ ├── ansibleworkflow_test.yml │ │ ├── inventory_test.yml │ │ ├── jobtemplate_test.yml │ │ └── workflowtemplate_test.yml │ └── verify.yml ├── kind │ ├── converge.yml │ ├── create.yml │ ├── destroy.yml │ └── molecule.yml ├── requirements.txt └── requirements.yml ├── playbooks └── .placeholder ├── requirements.yml ├── roles ├── credential │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── .placeholder │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── .placeholder │ │ ├── job_definition.yml.j2 │ │ └── service_account.yml.j2 │ └── vars │ │ └── main.yml ├── instancegroup │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── .placeholder │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── job_definition.yml.j2 │ │ └── service_account.yml.j2 │ └── vars │ │ └── main.yml ├── inventory │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── .placeholder │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── vars │ │ └── main.yml ├── job │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── job_definition.yml.j2 │ │ └── service_account.yml.j2 │ └── vars │ │ └── main.yml ├── job_runner │ ├── defaults │ │ └── main.yml │ ├── meta │ │ └── main.yml │ └── tasks │ │ ├── create_instance_group.yml │ │ ├── create_project.yml │ │ ├── create_schedule.yml │ │ ├── credentials.yml │ │ ├── credentials │ │ ├── create_bearer_credential.yml │ │ ├── create_generic_credential.yml │ │ ├── create_ssh_credential.yml │ │ ├── create_token_credential.yml │ │ └── create_userpass_credential.yml │ │ ├── launch_deprecated_job.yml │ │ ├── launch_job.yml │ │ ├── launch_workflow.yml │ │ └── main.yml ├── jobtemplate │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── vars │ │ └── main.yml ├── project │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── .placeholder │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── job_definition.yml.j2 │ │ └── service_account.yml.j2 │ └── vars │ │ └── main.yml ├── schedule │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── .placeholder │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── job_definition.yml.j2 │ │ └── service_account.yml.j2 │ └── vars │ │ └── main.yml ├── workflow │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── .placeholder │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── job_definition.yml.j2 │ │ └── service_account.yml.j2 │ └── vars │ │ └── main.yml └── workflowtemplate │ ├── defaults │ └── main.yml │ ├── handlers │ └── main.yml │ ├── meta │ └── main.yml │ ├── tasks │ └── main.yml │ └── vars │ └── main.yml ├── test-e2e ├── awx-demo.yml ├── awx-deploy.yaml ├── base-operator-install.yaml ├── tests │ ├── bearer.yaml │ ├── job-deprecated.yaml │ └── job.yaml ├── token-container │ ├── Dockerfile │ ├── playbook.yaml │ └── requirements.yml └── token.yaml ├── up.sh └── watches.yaml /.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | skip_list: 3 | - '306' 4 | - '602' 5 | - '503' 6 | 7 | exclude_paths: 8 | - deploy/ 9 | - .cache/ 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/build-operator-image.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: Build Operator Image 4 | 5 | on: 6 | push: 7 | branches: [devel] 8 | 9 | jobs: 10 | operator-image-build: 11 | runs-on: ubuntu-latest 12 | name: Push Operator Image 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Build Image 17 | run: | 18 | IMG=awx-resource-operator:devel make docker-build 19 | 20 | - name: Push To Quay 21 | uses: redhat-actions/push-to-registry@v2.1.1 22 | with: 23 | image: awx-resource-operator 24 | tags: devel 25 | registry: quay.io/ansible/ 26 | username: ${{ secrets.QUAY_USER }} 27 | password: ${{ secrets.QUAY_TOKEN }} 28 | runner-image-build: 29 | runs-on: ubuntu-latest 30 | name: Push Runner Image 31 | steps: 32 | - uses: actions/checkout@v2 33 | 34 | - name: Build Image 35 | run: | 36 | docker build -t awx-resource-runner:devel -f Dockerfile.runner . 37 | 38 | - name: Push To Quay 39 | uses: redhat-actions/push-to-registry@v2.1.1 40 | with: 41 | image: awx-resource-runner 42 | tags: devel 43 | registry: quay.io/ansible/ 44 | username: ${{ secrets.QUAY_USER }} 45 | password: ${{ secrets.QUAY_TOKEN }} 46 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: CI 4 | 5 | on: 6 | pull_request: 7 | branches: [devel] 8 | 9 | push: 10 | branches: [devel] 11 | 12 | jobs: 13 | pull_request: 14 | runs-on: ubuntu-latest 15 | name: pull_request 16 | env: 17 | DOCKER_API_VERSION: "1.41" 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - uses: actions/setup-python@v2 22 | with: 23 | python-version: "3.8" 24 | 25 | - name: Install Dependencies 26 | run: | 27 | pip install -r molecule/requirements.txt 28 | 29 | - name: Install Collections 30 | run: | 31 | ansible-galaxy collection install -r molecule/requirements.yml 32 | ansible-galaxy collection install community.docker 33 | - name: Run Molecule 34 | env: 35 | MOLECULE_VERBOSITY: 3 36 | PY_COLORS: '1' 37 | ANSIBLE_FORCE_COLOR: '1' 38 | run: | 39 | make kustomize 40 | KUSTOMIZE_PATH=$(readlink -f bin/kustomize) molecule test -s kind 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .cache/ 3 | /bin 4 | /bundle 5 | /bundle_tmp* 6 | /bundle.Dockerfile 7 | 8 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | ignore: | 5 | .cache/ 6 | kustomization.yaml 7 | awx-resource-operator.clusterserviceversion.yaml 8 | bundle 9 | config/testing/kustomization.yaml 10 | 11 | rules: 12 | truthy: disable 13 | line-length: 14 | max: 170 15 | document-start: disable 16 | comments-indentation: disable 17 | indentation: 18 | level: warning 19 | indent-sequences: consistent 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/operator-framework/ansible-operator:v1.22.2 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 | 11 | ENTRYPOINT ["/tini", "--", "/usr/local/bin/ansible-operator", "run", "--watches-file=./watches.yaml", "--reconcile-period=0s"] 12 | -------------------------------------------------------------------------------- /Dockerfile.runner: -------------------------------------------------------------------------------- 1 | FROM quay.io/ansible/ansible-runner:latest 2 | ENV ANSIBLE_ROLES_PATH ${HOME}/roles 3 | 4 | COPY requirements.yml ${HOME}/requirements.yml 5 | 6 | RUN ansible-galaxy collection install -r ${HOME}/requirements.yml --force \ 7 | && chmod -R ug+rwx ${HOME}/.ansible && mkdir -p ${HOME}/roles 8 | 9 | RUN pip3 install awxkit kubernetes openshift 10 | 11 | COPY roles/job_runner ${HOME}/roles/job_runner 12 | CMD ["ansible-runner", "run", "/runner", "--hosts", "localhost", "--role", "job_runner", "--role-skip-facts"] 13 | -------------------------------------------------------------------------------- /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: ansible.com 6 | layout: 7 | - ansible.sdk.operatorframework.io/v1 8 | plugins: 9 | manifests.sdk.operatorframework.io/v2: {} 10 | scorecard.sdk.operatorframework.io/v2: {} 11 | projectName: awx-resource-operator 12 | resources: 13 | - api: 14 | crdVersion: v1 15 | namespaced: true 16 | domain: ansible.com 17 | group: tower 18 | kind: AnsibleJob 19 | version: v1alpha1 20 | - api: 21 | crdVersion: v1 22 | namespaced: true 23 | domain: ansible.com 24 | group: tower 25 | kind: JobTemplate 26 | version: v1alpha1 27 | - api: 28 | crdVersion: v1 29 | namespaced: true 30 | domain: ansible.com 31 | group: tower 32 | kind: AnsibleProject 33 | version: v1alpha1 34 | - api: 35 | crdVersion: v1 36 | namespaced: true 37 | domain: ansible.com 38 | group: tower 39 | kind: AnsibleWorkflow 40 | version: v1alpha1 41 | - api: 42 | crdVersion: v1 43 | namespaced: true 44 | domain: ansible.com 45 | group: tower 46 | kind: AnsibleCredential 47 | version: v1alpha1 48 | - api: 49 | crdVersion: v1 50 | namespaced: true 51 | domain: ansible.com 52 | group: tower 53 | kind: AnsibleSchedule 54 | version: v1alpha1 55 | - api: 56 | crdVersion: v1 57 | namespaced: true 58 | domain: ansible.com 59 | group: tower 60 | kind: AnsibleInstanceGroup 61 | version: v1alpha1 62 | - api: 63 | crdVersion: v1 64 | namespaced: true 65 | domain: ansible.com 66 | group: tower 67 | kind: WorkflowTemplate 68 | version: v1alpha1 69 | - api: 70 | crdVersion: v1 71 | namespaced: true 72 | domain: ansible.com 73 | group: tower 74 | kind: AnsibleInventory 75 | version: v1alpha1 76 | version: "3" 77 | -------------------------------------------------------------------------------- /config/crd/bases/tower.ansible.com_ansiblecredentials.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: ansiblecredentials.tower.ansible.com 6 | spec: 7 | group: tower.ansible.com 8 | names: 9 | kind: AnsibleCredential 10 | listKind: AnsibleCredentialList 11 | plural: ansiblecredentials 12 | singular: ansiblecredential 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: (Tech Preview) AnsibleCredential is the Schema for the ansiblecredentials 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 | properties: 34 | name: 35 | type: string 36 | description: The name for the credential 37 | organization: 38 | type: string 39 | description: The organization for the credential 40 | runner_image: 41 | type: string 42 | description: Runner image used when running jobs 43 | runner_version: 44 | type: string 45 | description: Runner image version used when running jobs 46 | runner_pull_policy: 47 | type: string 48 | description: Runner image pull policy used when running jobs 49 | description: 50 | type: string 51 | description: The description for the credential 52 | type: 53 | type: string 54 | description: The credential type for the credential 55 | inputs: 56 | type: string 57 | description: The credential inputs for the credential 58 | ssh_secret: 59 | type: string 60 | description: The k8s secret for the SSH credential 61 | kubernetes_api: 62 | type: string 63 | description: The k8s api for the Bearer credential 64 | kubernetes_bearer_token_secret: 65 | type: string 66 | description: The k8s secret for the Bearer credential 67 | ssh_username: 68 | type: string 69 | description: The username for the SSH credential 70 | connection_secret: 71 | description: | 72 | A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 73 | type: string 74 | required: 75 | - connection_secret 76 | - name 77 | - organization 78 | - type 79 | description: Spec defines the definition of the AnsibleCredential 80 | type: object 81 | x-kubernetes-preserve-unknown-fields: true 82 | status: 83 | description: Status defines the observed state of AnsibleCredential 84 | type: object 85 | x-kubernetes-preserve-unknown-fields: true 86 | type: object 87 | served: true 88 | storage: true 89 | subresources: 90 | status: {} 91 | -------------------------------------------------------------------------------- /config/crd/bases/tower.ansible.com_ansibleinventories.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: ansibleinventories.tower.ansible.com 6 | spec: 7 | group: tower.ansible.com 8 | names: 9 | kind: AnsibleInventory 10 | listKind: AnsibleInventoryList 11 | plural: ansibleinventories 12 | singular: ansibleinventory 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: Inventory is the Schema for the inventories 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 | properties: 34 | name: 35 | type: string 36 | description: The name to use for the inventory 37 | description: 38 | type: string 39 | description: The description for the inventory 40 | organization: 41 | type: string 42 | description: Organization name, ID, or named URL the inventory belongs to 43 | instance_groups: 44 | type: array 45 | description: list of Instance Group names, IDs, or named URLs for this Organization to run on 46 | items: 47 | type: string 48 | copy_from: 49 | type: string 50 | description: Name or id to copy the inventory from 51 | This will copy an existing inventory and change any parameters supplied 52 | The new inventory name will be the one provided in the name parameter 53 | The organization parameter is not used in this, to facilitate copy from one organization to another 54 | Provide the id or use the lookup plugin to provide the id if multiple inventories share the same name 55 | state: 56 | type: string 57 | default: present 58 | enum: ["present", "absent", "exists"] 59 | description: Desired state of the resource 60 | variables: 61 | type: object 62 | description: The desired inventory variables for the inventory 63 | additionalProperties: 64 | x-kubernetes-preserve-unknown-fields: true 65 | connection_secret: 66 | type: string 67 | description: | 68 | A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 69 | description: Spec defines the desired state of Inventory 70 | type: object 71 | x-kubernetes-preserve-unknown-fields: true 72 | required: 73 | - name 74 | - organization 75 | status: 76 | description: Status defines the observed state of Inventory 77 | type: object 78 | x-kubernetes-preserve-unknown-fields: true 79 | type: object 80 | served: true 81 | storage: true 82 | subresources: 83 | status: {} 84 | -------------------------------------------------------------------------------- /config/crd/bases/tower.ansible.com_ansiblejobs.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: ansiblejobs.tower.ansible.com 6 | spec: 7 | group: tower.ansible.com 8 | names: 9 | kind: AnsibleJob 10 | listKind: AnsibleJobList 11 | plural: ansiblejobs 12 | singular: ansiblejob 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: AnsibleJob is the Schema for the ansiblejobs 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 | properties: 34 | extra_vars: 35 | type: object 36 | x-kubernetes-preserve-unknown-fields: true 37 | inventory: 38 | type: string 39 | job_template_name: 40 | type: string 41 | workflow_template_name: 42 | type: string 43 | request_timeout: 44 | type: integer 45 | description: Timeout in seconds to wait for a response when querying the API for the job status 46 | runner_image: 47 | type: string 48 | description: Runner image used when running jobs 49 | runner_version: 50 | type: string 51 | description: Runner image version used when running jobs 52 | runner_pull_policy: 53 | type: string 54 | description: Runner image pull policy used when running jobs 55 | job_ttl: 56 | description: Time to live for k8s job object after the playbook run has finished 57 | type: integer 58 | job_tags: 59 | type: string 60 | description: A comma-separated list of tags to specify which sets of ansible tasks in a job should be run 61 | skip_tags: 62 | type: string 63 | description: A comma-separated list of tags to specify which sets of ansible tasks in a job should not be run 64 | tower_auth_secret: 65 | description: | 66 | (DEPRECATED) A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 67 | type: string 68 | connection_secret: 69 | description: | 70 | A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 71 | type: string 72 | required: 73 | description: Spec defines the desired state of AnsibleJob 74 | type: object 75 | x-kubernetes-preserve-unknown-fields: true 76 | status: 77 | description: Status defines the observed state of AnsibleJob 78 | type: object 79 | x-kubernetes-preserve-unknown-fields: true 80 | type: object 81 | served: true 82 | storage: true 83 | subresources: 84 | status: {} 85 | -------------------------------------------------------------------------------- /config/crd/bases/tower.ansible.com_ansibleprojects.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: ansibleprojects.tower.ansible.com 6 | spec: 7 | group: tower.ansible.com 8 | names: 9 | kind: AnsibleProject 10 | listKind: AnsibleProjectList 11 | plural: ansibleprojects 12 | singular: ansibleproject 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: (Tech Preview) AnsibleProject is the Schema for the ansibleprojects 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 | properties: 34 | repo: 35 | type: string 36 | description: The URL of the project resources 37 | branch: 38 | type: string 39 | description: The branch of the project repository 40 | name: 41 | type: string 42 | description: The name of the project 43 | organization: 44 | type: string 45 | description: The organization of the project 46 | scm_credential: 47 | type: string 48 | description: The SCM credential for the project 49 | scm_type: 50 | type: string 51 | description: The SCM type of the project 52 | description: 53 | type: string 54 | description: The description of the project 55 | connection_secret: 56 | description: | 57 | A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 58 | type: string 59 | runner_image: 60 | type: string 61 | description: Runner image used when running jobs 62 | runner_version: 63 | type: string 64 | description: Runner image version used when running jobs 65 | runner_pull_policy: 66 | type: string 67 | description: Runner image pull policy used when running jobs 68 | required: 69 | - connection_secret 70 | - scm_type 71 | - name 72 | - organization 73 | description: Spec defines the definition of the AnsibleProject 74 | type: object 75 | x-kubernetes-preserve-unknown-fields: true 76 | status: 77 | description: Status defines the observed state of AnsibleProject 78 | type: object 79 | x-kubernetes-preserve-unknown-fields: true 80 | type: object 81 | served: true 82 | storage: true 83 | subresources: 84 | status: {} 85 | -------------------------------------------------------------------------------- /config/crd/bases/tower.ansible.com_ansibleschedules.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: ansibleschedules.tower.ansible.com 6 | spec: 7 | group: tower.ansible.com 8 | names: 9 | kind: AnsibleSchedule 10 | listKind: AnsibleScheduleList 11 | plural: ansibleschedules 12 | singular: ansibleschedule 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: (Tech Preview) AnsibleSchedule is the Schema for the ansibleschedules 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 | properties: 34 | name: 35 | type: string 36 | description: The name of the schedule 37 | rrule: 38 | type: string 39 | description: A value representing the schedules iCal recurrence rule. 40 | unified_job_template: 41 | type: string 42 | description: The unified job template to schedule 43 | connection_secret: 44 | description: | 45 | A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 46 | type: string 47 | runner_image: 48 | type: string 49 | description: Runner image used when running jobs 50 | runner_version: 51 | type: string 52 | description: Runner image version used when running jobs 53 | runner_pull_policy: 54 | type: string 55 | description: Runner image pull policy used when running jobs 56 | required: 57 | - connection_secret 58 | - name 59 | - rrule 60 | - unified_job_template 61 | description: Spec defines the definition of the AnsibleSchedule 62 | type: object 63 | x-kubernetes-preserve-unknown-fields: true 64 | status: 65 | description: Status defines the observed state of AnsibleSchedule 66 | type: object 67 | x-kubernetes-preserve-unknown-fields: true 68 | type: object 69 | served: true 70 | storage: true 71 | subresources: 72 | status: {} 73 | -------------------------------------------------------------------------------- /config/crd/bases/tower.ansible.com_ansibleworkflows.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: ansibleworkflows.tower.ansible.com 6 | spec: 7 | group: tower.ansible.com 8 | names: 9 | kind: AnsibleWorkflow 10 | listKind: AnsibleWorkflowList 11 | plural: ansibleworkflows 12 | singular: ansibleworkflow 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: (Tech Preview) AnsibleWorkflow is the Schema for the ansibleworkflows 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 | properties: 34 | extra_vars: 35 | type: object 36 | x-kubernetes-preserve-unknown-fields: true 37 | inventory: 38 | type: string 39 | workflow_template_name: 40 | type: string 41 | request_timeout: 42 | type: integer 43 | description: Timeout in seconds to wait for a response when querying the API for the job status 44 | runner_image: 45 | type: string 46 | description: Runner image used when running jobs 47 | runner_version: 48 | type: string 49 | description: Runner image version used when running jobs 50 | runner_pull_policy: 51 | type: string 52 | description: Runner image pull policy used when running jobs 53 | connection_secret: 54 | type: string 55 | description: | 56 | A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 57 | required: 58 | - connection_secret 59 | description: Spec defines the desired state of AnsibleWorkflow 60 | type: object 61 | x-kubernetes-preserve-unknown-fields: true 62 | status: 63 | description: Status defines the observed state of AnsibleWorkflow 64 | type: object 65 | x-kubernetes-preserve-unknown-fields: true 66 | type: object 67 | served: true 68 | storage: true 69 | subresources: 70 | status: {} 71 | -------------------------------------------------------------------------------- /config/crd/bases/tower.ansible.com_jobtemplates.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: jobtemplates.tower.ansible.com 6 | spec: 7 | group: tower.ansible.com 8 | names: 9 | kind: JobTemplate 10 | listKind: JobTemplateList 11 | plural: jobtemplates 12 | singular: jobtemplate 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: JobTemplate is the Schema for the jobtemplates 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 | properties: 34 | job_template_inventory: 35 | description: This field is deprecated, please use 'inventory' instead. 36 | type: string 37 | job_template_name: 38 | description: This field is deprecated, please use 'name' instead. 39 | type: string 40 | job_template_playbook: 41 | description: This field is deprecated, please use 'playbook' instead. 42 | type: string 43 | job_template_project: 44 | description: This field is deprecated, please use 'project' instead. 45 | type: string 46 | job_template_ask_vars: 47 | description: This field is deprecated, please use 'ask_variables_on_launch' instead. 48 | type: boolean 49 | job_template_ask_inventory: 50 | description: This field is deprecated, please use 'ask_inventory_on_launch' instead. 51 | type: boolean 52 | inventory: 53 | type: string 54 | name: 55 | type: string 56 | playbook: 57 | type: string 58 | project: 59 | type: string 60 | ask_variables_on_launch: 61 | type: boolean 62 | ask_inventory_on_launch: 63 | type: boolean 64 | tower_auth_secret: 65 | type: string 66 | description: | 67 | (DEPRECATED) A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 68 | connection_secret: 69 | type: string 70 | description: | 71 | A k8s secret that contains an access token for AWX. To create an access token see these docs: https://docs.ansible.com/automation-controller/4.1.0/html/userguide/applications_auth.html#add-tokens. 72 | description: Spec defines the desired state of JobTemplate 73 | type: object 74 | x-kubernetes-preserve-unknown-fields: true 75 | status: 76 | description: Status defines the observed state of JobTemplate 77 | type: object 78 | x-kubernetes-preserve-unknown-fields: true 79 | type: object 80 | served: true 81 | storage: true 82 | subresources: 83 | status: {} 84 | 85 | -------------------------------------------------------------------------------- /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/tower.ansible.com_ansiblejobs.yaml 6 | - bases/tower.ansible.com_jobtemplates.yaml 7 | - bases/tower.ansible.com_ansibleprojects.yaml 8 | - bases/tower.ansible.com_ansibleworkflows.yaml 9 | - bases/tower.ansible.com_ansiblecredentials.yaml 10 | - bases/tower.ansible.com_ansibleschedules.yaml 11 | - bases/tower.ansible.com_ansibleinstancegroups.yaml 12 | - bases/tower.ansible.com_workflowtemplates.yaml 13 | - bases/tower.ansible.com_ansibleinventories.yaml 14 | #+kubebuilder:scaffold:crdkustomizeresource 15 | -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: awx-resource-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: resource-operator- 10 | 11 | # Labels to add to all resources and selectors. 12 | #commonLabels: 13 | # someName: someValue 14 | 15 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 16 | #- ../prometheus 17 | 18 | # Protect the /metrics endpoint by putting it behind auth. 19 | # If you want your controller-manager to expose the /metrics 20 | # endpoint w/o any authn/z, please comment the following line. 21 | apiVersion: kustomize.config.k8s.io/v1beta1 22 | kind: Kustomization 23 | resources: 24 | - ../crd 25 | - ../rbac 26 | - ../manager 27 | patches: 28 | - path: manager_auth_proxy_patch.yaml 29 | -------------------------------------------------------------------------------- /config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | securityContext: 14 | allowPrivilegeEscalation: false 15 | # TODO(user): uncomment for common cases that do not require escalating privileges 16 | # capabilities: 17 | # drop: 18 | # - "ALL" 19 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0 20 | args: 21 | - "--secure-listen-address=0.0.0.0:8443" 22 | - "--upstream=http://127.0.0.1:8080/" 23 | - "--logtostderr=true" 24 | - "--v=10" 25 | ports: 26 | - containerPort: 8443 27 | protocol: TCP 28 | name: https 29 | resources: 30 | limits: 31 | cpu: 1000m 32 | memory: 512Mi 33 | requests: 34 | cpu: 5m 35 | memory: 64Mi 36 | - name: awx-resource-manager 37 | args: 38 | - "--health-probe-bind-address=:6789" 39 | - "--metrics-bind-address=127.0.0.1:8080" 40 | - "--leader-elect" 41 | - "--leader-election-id=awx-resource-operator" 42 | -------------------------------------------------------------------------------- /config/default/manager_config_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: awx-resource-manager 11 | args: 12 | - "--config=controller_manager_config.yaml" 13 | volumeMounts: 14 | - name: awx-resource-manager-config 15 | mountPath: /controller_manager_config.yaml 16 | subPath: controller_manager_config.yaml 17 | volumes: 18 | - name: awx-resource-manager-config 19 | configMap: 20 | name: awx-resource-manager-config 21 | -------------------------------------------------------------------------------- /config/manager/controller_manager_config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 2 | kind: ControllerManagerConfig 3 | health: 4 | healthProbeBindAddress: :6789 5 | metrics: 6 | bindAddress: 127.0.0.1:8080 7 | 8 | leaderElection: 9 | leaderElect: true 10 | resourceName: 811c9dc5.ansible.com 11 | # leaderElectionReleaseOnCancel defines if the leader should step down volume 12 | # when the Manager ends. This requires the binary to immediately end when the 13 | # Manager is stopped, otherwise, this setting is unsafe. Setting this significantly 14 | # speeds up voluntary leader transitions as the new leader don't have to wait 15 | # LeaseDuration time first. 16 | # In the default scaffold provided, the program ends immediately after 17 | # the manager stops, so would be fine to enable this option. However, 18 | # if you are doing or is intended to do any operation such as perform cleanups 19 | # after the manager stops then its usage might be unsafe. 20 | # leaderElectionReleaseOnCancel: true 21 | -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | 4 | generatorOptions: 5 | disableNameSuffixHash: true 6 | 7 | configMapGenerator: 8 | - files: 9 | - controller_manager_config.yaml 10 | name: awx-resource-manager-config 11 | apiVersion: kustomize.config.k8s.io/v1beta1 12 | kind: Kustomization 13 | images: 14 | - name: controller 15 | newName: quay.io/ansible/awx-resource-operator 16 | newTag: 0.2.0 17 | -------------------------------------------------------------------------------- /config/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: system 7 | --- 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | metadata: 11 | name: controller-manager 12 | namespace: system 13 | labels: 14 | control-plane: controller-manager 15 | spec: 16 | selector: 17 | matchLabels: 18 | control-plane: controller-manager 19 | replicas: 1 20 | template: 21 | metadata: 22 | annotations: 23 | kubectl.kubernetes.io/default-container: manager 24 | labels: 25 | control-plane: controller-manager 26 | spec: 27 | securityContext: 28 | runAsNonRoot: true 29 | # TODO(user): For common cases that do not require escalating privileges 30 | # it is recommended to ensure that all your Pods/Containers are restrictive. 31 | # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 32 | # Please uncomment the following code if your project does NOT have to work on old Kubernetes 33 | # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). 34 | #seccompProfile: 35 | # type: RuntimeDefault 36 | containers: 37 | - args: 38 | - --leader-elect 39 | - --leader-election-id=awx-resource-operator 40 | - --max-concurrent-reconciles=15 41 | image: controller:latest 42 | imagePullPolicy: IfNotPresent 43 | name: awx-resource-manager 44 | env: 45 | - name: ANSIBLE_GATHERING 46 | value: explicit 47 | - name: ANSIBLE_DEBUG_LOGS 48 | value: 'false' 49 | - name: WATCH_NAMESPACE 50 | valueFrom: 51 | fieldRef: 52 | fieldPath: metadata.namespace 53 | - name: RELATED_IMAGE_ANSIBLE_JOB_RUNNER_IMAGE 54 | # Replace this with the job runner built image name 55 | value: quay.io/ansible/awx-resource-runner:latest 56 | securityContext: 57 | allowPrivilegeEscalation: false 58 | capabilities: 59 | drop: 60 | - "ALL" 61 | livenessProbe: 62 | httpGet: 63 | path: /healthz 64 | port: 6789 65 | initialDelaySeconds: 15 66 | periodSeconds: 20 67 | readinessProbe: 68 | httpGet: 69 | path: /readyz 70 | port: 6789 71 | initialDelaySeconds: 5 72 | periodSeconds: 10 73 | # TODO(user): Configure the resources accordingly based on the project requirements. 74 | # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ 75 | resources: 76 | limits: 77 | cpu: 1000m 78 | memory: 2Gi 79 | requests: 80 | cpu: 100m 81 | memory: 256Mi 82 | serviceAccountName: controller-manager 83 | imagePullSecrets: 84 | - name: redhat-operators-pull-secret 85 | terminationGracePeriodSeconds: 10 86 | -------------------------------------------------------------------------------- /config/manifests/bases/annotations.yaml: -------------------------------------------------------------------------------- 1 | annotations: 2 | operators.openshift.io/infrastructure-features: '["disconnected"]' 3 | -------------------------------------------------------------------------------- /config/manifests/bases/inject-custom-annotations.py: -------------------------------------------------------------------------------- 1 | ''' 2 | After generating the bundle, inject custom configuration for annotations. 3 | ''' 4 | 5 | import yaml 6 | 7 | annotations_path = "../../../bundle/metadata/annotations.yaml" 8 | existing_annotations = open(annotations_path, 'r') 9 | annotations = yaml.safe_load(existing_annotations) 10 | 11 | 12 | raw_annotations = open("annotations.yaml") 13 | base_annotations = yaml.safe_load(raw_annotations) 14 | 15 | # Inject custom annotations 16 | annotations['annotations'].update(base_annotations['annotations']) 17 | 18 | file_content = yaml.safe_dump(annotations, default_flow_style=False, explicit_start=True) 19 | 20 | with open(annotations_path, 'w') as f: 21 | f.write(file_content) 22 | -------------------------------------------------------------------------------- /config/manifests/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # These resources constitute the fully configured set of manifests 2 | # used to generate the 'manifests/' directory in a bundle. 3 | resources: 4 | - bases/awx-resource-operator.clusterserviceversion.yaml 5 | - ../default 6 | - ../samples 7 | - ../scorecard 8 | -------------------------------------------------------------------------------- /config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | -------------------------------------------------------------------------------- /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 | name: controller-manager-metrics-monitor 8 | namespace: system 9 | spec: 10 | endpoints: 11 | - path: /metrics 12 | port: https 13 | scheme: https 14 | bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token 15 | tlsConfig: 16 | insecureSkipVerify: true 17 | selector: 18 | matchLabels: 19 | control-plane: controller-manager 20 | -------------------------------------------------------------------------------- /config/rbac/ansiblecredential_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit ansiblecredentials. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansiblecredential-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansiblecredentials 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - ansiblecredentials/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/ansiblecredential_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view ansiblecredentials. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansiblecredential-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansiblecredentials 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - ansiblecredentials/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/ansibleinstancegroup_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit ansibleinstancegroups. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleinstancegroup-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleinstancegroups 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - ansibleinstancegroups/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/ansibleinstancegroup_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view ansibleinstancegroups. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleinstancegroup-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleinstancegroups 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - ansibleinstancegroups/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/ansiblejob_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit ansiblejobs. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansiblejob-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansiblejobs 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - ansiblejobs/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/ansiblejob_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view ansiblejobs. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansiblejob-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansiblejobs 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - ansiblejobs/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/ansibleproject_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit ansibleprojects. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleproject-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleprojects 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - ansibleprojects/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/ansibleproject_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view ansibleprojects. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleproject-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleprojects 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - ansibleprojects/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/ansibleschedule_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit ansibleschedules. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleschedule-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleschedules 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - ansibleschedules/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/ansibleschedule_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view ansibleschedules. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleschedule-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleschedules 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - ansibleschedules/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/ansibleworkflow_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit ansibleworkflows. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleworkflow-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleworkflows 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - ansibleworkflows/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/ansibleworkflow_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view ansibleworkflows. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ansibleworkflow-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - ansibleworkflows 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - ansibleworkflows/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_client_clusterrole.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 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: proxy-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 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: proxy-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: proxy-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: controller-manager-metrics-service 7 | namespace: system 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | protocol: TCP 13 | targetPort: https 14 | selector: 15 | control-plane: controller-manager 16 | -------------------------------------------------------------------------------- /config/rbac/inventory_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit inventories. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: clusterrole 7 | app.kubernetes.io/instance: inventory-editor-role 8 | app.kubernetes.io/component: rbac 9 | app.kubernetes.io/created-by: awx-resource-operator 10 | app.kubernetes.io/part-of: awx-resource-operator 11 | app.kubernetes.io/managed-by: kustomize 12 | name: inventory-editor-role 13 | rules: 14 | - apiGroups: 15 | - tower.ansible.com 16 | resources: 17 | - inventories 18 | verbs: 19 | - create 20 | - delete 21 | - get 22 | - list 23 | - patch 24 | - update 25 | - watch 26 | - apiGroups: 27 | - tower.ansible.com 28 | resources: 29 | - inventories/status 30 | verbs: 31 | - get 32 | -------------------------------------------------------------------------------- /config/rbac/inventory_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view inventories. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: clusterrole 7 | app.kubernetes.io/instance: inventory-viewer-role 8 | app.kubernetes.io/component: rbac 9 | app.kubernetes.io/created-by: awx-resource-operator 10 | app.kubernetes.io/part-of: awx-resource-operator 11 | app.kubernetes.io/managed-by: kustomize 12 | name: inventory-viewer-role 13 | rules: 14 | - apiGroups: 15 | - tower.ansible.com 16 | resources: 17 | - inventories 18 | verbs: 19 | - get 20 | - list 21 | - watch 22 | - apiGroups: 23 | - tower.ansible.com 24 | resources: 25 | - inventories/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /config/rbac/jobtemplate_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit jobtemplates. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: jobtemplate-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - jobtemplates 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - jobtemplates/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/jobtemplate_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view jobtemplates. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: jobtemplate-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - jobtemplates 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - jobtemplates/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /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 | # Comment the following 4 lines if you want to disable 13 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 14 | # which protects your /metrics endpoint. 15 | - auth_proxy_service.yaml 16 | - auth_proxy_role.yaml 17 | - auth_proxy_role_binding.yaml 18 | - auth_proxy_client_clusterrole.yaml 19 | -------------------------------------------------------------------------------- /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 | name: leader-election-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - coordination.k8s.io 21 | resources: 22 | - leases 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | - create 28 | - update 29 | - patch 30 | - delete 31 | - apiGroups: 32 | - "" 33 | resources: 34 | - events 35 | verbs: 36 | - create 37 | - patch 38 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: awx-resource-manager-role 6 | rules: 7 | ## 8 | ## Base operator rules 9 | ## 10 | - apiGroups: 11 | - "" 12 | - rbac.authorization.k8s.io 13 | resources: 14 | - secrets 15 | - pods 16 | - serviceaccounts 17 | - roles 18 | - rolebindings 19 | - services 20 | - services/finalizers 21 | - endpoints 22 | - persistentvolumeclaims 23 | - events 24 | - configmaps 25 | - jobs 26 | - pods/exec 27 | - pods/log 28 | verbs: 29 | - create 30 | - delete 31 | - get 32 | - list 33 | - patch 34 | - update 35 | - watch 36 | - apiGroups: 37 | - apps 38 | resources: 39 | - deployments 40 | - daemonsets 41 | - replicasets 42 | - statefulsets 43 | - jobs 44 | verbs: 45 | - create 46 | - delete 47 | - get 48 | - list 49 | - patch 50 | - update 51 | - watch 52 | - apiGroups: 53 | - monitoring.coreos.com 54 | resources: 55 | - servicemonitors 56 | verbs: 57 | - get 58 | - create 59 | ## 60 | ## Rules for tower.ansible.com/v1alpha1, Kind: AnsibleJob 61 | ## 62 | - apiGroups: 63 | - tower.ansible.com 64 | resources: 65 | - ansiblejobs 66 | - ansiblejobs/status 67 | - ansiblejobs/finalizers 68 | verbs: 69 | - create 70 | - delete 71 | - get 72 | - list 73 | - patch 74 | - update 75 | - watch 76 | ## 77 | ## Rules for tower.ansible.com/v1alpha1, Kind: JobTemplate 78 | ## Rules for tower.ansible.com/v1alpha1, Kind: AnsibleProject 79 | ## Rules for tower.ansible.com/v1alpha1, Kind: AnsibleWorkflow 80 | ## 81 | - apiGroups: 82 | - tower.ansible.com 83 | resources: 84 | - jobtemplates 85 | - jobtemplates/status 86 | - jobtemplates/finalizers 87 | - ansibleworkflows 88 | - ansibleworkflows/status 89 | - ansibleworkflows/finalizers 90 | - ansibleprojects 91 | - ansibleprojects/status 92 | - ansibleprojects/finalizers 93 | verbs: 94 | - create 95 | - delete 96 | - get 97 | - list 98 | - patch 99 | - update 100 | - watch 101 | 102 | ## 103 | ## Rules needed for managing k8s runner job 104 | ## 105 | 106 | - apiGroups: 107 | - apps 108 | resourceNames: 109 | - resource-operator-controller-manager 110 | resources: 111 | - deployments/finalizers 112 | verbs: 113 | - update 114 | - apiGroups: 115 | - "" 116 | resources: 117 | - pods 118 | - jobs 119 | verbs: 120 | - get 121 | - apiGroups: 122 | - apps 123 | resources: 124 | - replicasets 125 | - deployments 126 | - jobs 127 | verbs: 128 | - get 129 | - apiGroups: 130 | - tower.ansible.com 131 | resources: 132 | - '*' 133 | verbs: 134 | - create 135 | - delete 136 | - get 137 | - list 138 | - patch 139 | - update 140 | - watch 141 | - apiGroups: 142 | - batch 143 | resources: 144 | - '*' 145 | verbs: 146 | - create 147 | - delete 148 | - get 149 | - list 150 | - patch 151 | - update 152 | - watch 153 | -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: awx-resource-manager-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: awx-resource-manager-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | -------------------------------------------------------------------------------- /config/rbac/workflowtemplate_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit workflowtemplates. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: workflowtemplate-editor-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - workflowtemplates 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - tower.ansible.com 21 | resources: 22 | - workflowtemplates/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/workflowtemplate_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view workflowtemplates. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: workflowtemplate-viewer-role 6 | rules: 7 | - apiGroups: 8 | - tower.ansible.com 9 | resources: 10 | - workflowtemplates 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - tower.ansible.com 17 | resources: 18 | - workflowtemplates/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/samples/credentials/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_ansiblecredential-aws.yaml 4 | - tower_v1alpha1_ansiblecredential-git.yaml 5 | - tower_v1alpha1_ansiblecredential-bearer.yaml 6 | - tower_v1alpha1_ansiblecredential-sc.yaml 7 | - tower_v1alpha1_ansiblecredential-ssh.yaml 8 | #+kubebuilder:scaffold:manifestskustomizesamples 9 | -------------------------------------------------------------------------------- /config/samples/credentials/tower_v1alpha1_ansiblecredential-aws.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleCredential 3 | metadata: 4 | name: aws-cred 5 | spec: 6 | name: aws-access 7 | organization: Default 8 | connection_secret: awxaccess 9 | description: "This is a test credential" 10 | type: "Amazon Web Services" 11 | username_secret: aws-secret 12 | password_secret: aws-secret 13 | runner_pull_policy: IfNotPresent 14 | -------------------------------------------------------------------------------- /config/samples/credentials/tower_v1alpha1_ansiblecredential-bearer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleCredential 3 | metadata: 4 | name: bearer-cred 5 | spec: 6 | name: bearer-cred 7 | organization: Default 8 | connection_secret: awxaccess 9 | description: "Bearer Credential" 10 | type: "OpenShift or Kubernetes API Bearer Token" 11 | kubernetes_api: https://notarealurl.com:6443 12 | kubernetes_bearer_token_secret: bearer-secret 13 | runner_pull_policy: IfNotPresent 14 | -------------------------------------------------------------------------------- /config/samples/credentials/tower_v1alpha1_ansiblecredential-broken.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleCredential 3 | metadata: 4 | name: broken-cred 5 | spec: 6 | name: broken-cred 7 | organization: Orange 8 | connection_secret: awxaccess 9 | description: "This is a test credential" 10 | type: "GitHub Personal Access Token" 11 | token_secret: github-token-secret 12 | runner_pull_policy: IfNotPresent 13 | -------------------------------------------------------------------------------- /config/samples/credentials/tower_v1alpha1_ansiblecredential-git.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleCredential 3 | metadata: 4 | name: gh-cred 5 | spec: 6 | name: gh-cred 7 | organization: Default 8 | connection_secret: awxaccess 9 | description: "This is a test credential" 10 | type: "GitHub Personal Access Token" 11 | token_secret: github-token-secret 12 | runner_pull_policy: IfNotPresent 13 | -------------------------------------------------------------------------------- /config/samples/credentials/tower_v1alpha1_ansiblecredential-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleCredential 3 | metadata: 4 | name: scm-cred 5 | spec: 6 | name: scm-cred 7 | organization: Default 8 | connection_secret: awxaccess 9 | description: "This is a source control cred" 10 | type: "Source Control" 11 | username_secret: github-secret 12 | password_secret: github-secret 13 | runner_pull_policy: IfNotPresent 14 | -------------------------------------------------------------------------------- /config/samples/credentials/tower_v1alpha1_ansiblecredential-ssh.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleCredential 3 | metadata: 4 | name: ssh-cred 5 | spec: 6 | name: ssh-cred 7 | organization: Default 8 | connection_secret: awxaccess 9 | description: "SSH credential" 10 | type: "Machine" 11 | ssh_username: "cat" 12 | ssh_secret: my-ssh-secret 13 | runner_pull_policy: IfNotPresent 14 | -------------------------------------------------------------------------------- /config/samples/instancegroup/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_ansibleinstancegroup.yaml 4 | - tower_v1alpha1_ansiblecontainergroup.yaml 5 | #+kubebuilder:scaffold:manifestskustomizesamples 6 | -------------------------------------------------------------------------------- /config/samples/instancegroup/tower_v1alpha1_ansiblecontainergroup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleInstanceGroup 3 | metadata: 4 | name: container-group 5 | spec: 6 | name: container-group 7 | credential_name: bearer-cred 8 | is_container_group: true 9 | max_concurrent_jobs: 0 10 | max_forks: 0 11 | pod_spec_override: |- 12 | apiVersion: v1 13 | kind: Pod 14 | metadata: 15 | namespace: awx 16 | spec: 17 | serviceAccountName: default 18 | automountServiceAccountToken: false 19 | containers: 20 | - image: quay.io/ansible/awx-ee:latest 21 | name: worker 22 | args: 23 | - ansible-runner 24 | - worker 25 | - '--private-data-dir=/runner' 26 | resources: 27 | requests: 28 | cpu: 250m 29 | memory: 100Mi 30 | runner_pull_policy: IfNotPresent 31 | connection_secret: awxaccess 32 | -------------------------------------------------------------------------------- /config/samples/instancegroup/tower_v1alpha1_ansibleinstancegroup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleInstanceGroup 3 | metadata: 4 | name: kuber-instance-group 5 | spec: 6 | name: kuber-instance-group 7 | is_container_group: false 8 | max_concurrent_jobs: 0 9 | max_forks: 0 10 | policy_instance_percentage: 100 11 | policy_instance_minimum: 1 12 | instance_list: [] 13 | runner_pull_policy: IfNotPresent 14 | connection_secret: awxaccess 15 | -------------------------------------------------------------------------------- /config/samples/inventory/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_ansibleinventory-clone.yaml 4 | - tower_v1alpha1_ansibleinventory-new.yaml 5 | #+kubebuilder:scaffold:manifestskustomizesamples 6 | -------------------------------------------------------------------------------- /config/samples/inventory/tower_v1alpha1_ansibleinventory-clone.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleInventory 3 | metadata: 4 | name: inventory-clone 5 | spec: 6 | connection_secret: awxaccess 7 | copy_from: Demo Inventory 8 | description: my inventory 9 | name: sampleinv 10 | organization: Default 11 | state: present 12 | variables: 13 | msg: "awx is the best" 14 | is_true: true 15 | how_much: 10 16 | item: 17 | - name: apple 18 | value: red 19 | - name: grape 20 | value: blue 21 | - foo: bar 22 | example: 23 | moreexample: "example" 24 | -------------------------------------------------------------------------------- /config/samples/inventory/tower_v1alpha1_ansibleinventory-new.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleInventory 3 | metadata: 4 | name: inventory-new 5 | spec: 6 | connection_secret: awxaccess 7 | description: my new inventory 8 | name: newinventory 9 | organization: Default 10 | state: present 11 | instance_groups: 12 | - default 13 | variables: 14 | string: "string_value" 15 | bool: true 16 | number: 1 17 | list: 18 | - item1: true 19 | - item2: "1" 20 | object: 21 | string: "string_value" 22 | number: 2 23 | -------------------------------------------------------------------------------- /config/samples/jobtemplate/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_jobtemplate.yaml 4 | #+kubebuilder:scaffold:manifestskustomizesamples 5 | -------------------------------------------------------------------------------- /config/samples/jobtemplate/tower_v1alpha1_jobtemplate-broken.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: JobTemplate 3 | metadata: 4 | name: jobtemplate-broken 5 | spec: 6 | connection_secret: awxaccess 7 | job_template_name: ExampleBrokenTemplate 8 | job_template_project: BROKEN PROJECT 9 | job_template_playbook: hello_squirrel.yml 10 | job_template_inventory: Demo Inventory 11 | runner_pull_policy: IfNotPresent 12 | -------------------------------------------------------------------------------- /config/samples/jobtemplate/tower_v1alpha1_jobtemplate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: JobTemplate 3 | metadata: 4 | name: jobtemplate-sample 5 | spec: 6 | tower_auth_secret: awxaccess 7 | name: ExampleJobTemplate 8 | project: Demo Project 9 | playbook: hello_world.yml 10 | inventory: Demo Inventory 11 | -------------------------------------------------------------------------------- /config/samples/jobtemplate/tower_v1alpha1_jobtemplate_deprecated.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: JobTemplate 3 | metadata: 4 | name: jobtemplate-sample 5 | spec: 6 | tower_auth_secret: awxaccess 7 | job_template_name: ExampleJobTemplate 8 | job_template_project: Demo Project 9 | job_template_playbook: hello_world.yml 10 | job_template_inventory: Demo Inventory 11 | -------------------------------------------------------------------------------- /config/samples/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_ansiblejob.yaml 4 | - tower_v1alpha1_ansibleschedule.yaml 5 | - ./credentials/ 6 | - ./inventory/ 7 | - ./instancegroup/ 8 | - ./jobtemplate/ 9 | - ./projects/ 10 | - ./workflow/ 11 | - ./workflowtemplate/ 12 | #+kubebuilder:scaffold:manifestskustomizesamples 13 | -------------------------------------------------------------------------------- /config/samples/projects/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_ansibleproject-archive.yaml 4 | - tower_v1alpha1_ansibleproject-git-cred.yaml 5 | - tower_v1alpha1_ansibleproject-git.yaml 6 | #+kubebuilder:scaffold:manifestskustomizesamples 7 | -------------------------------------------------------------------------------- /config/samples/projects/tower_v1alpha1_ansibleproject-archive.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleProject 3 | metadata: 4 | name: archive 5 | spec: 6 | repo: https://github.com/ansible/ansible-tower-samples/archive/refs/heads/master.zip 7 | name: archive 8 | scm_type: archive 9 | organization: Default 10 | description: demoProject 11 | connection_secret: awxaccess 12 | runner_pull_policy: IfNotPresent 13 | -------------------------------------------------------------------------------- /config/samples/projects/tower_v1alpha1_ansibleproject-git-cred.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleProject 3 | metadata: 4 | name: private-git 5 | spec: 6 | repo: https://github.com/ansible/ansible-tower-samples 7 | branch: master 8 | name: private-git 9 | scm_type: git 10 | scm_credential: scm-cred 11 | organization: Default 12 | description: demoProject 13 | connection_secret: awxaccess 14 | runner_pull_policy: IfNotPresent 15 | -------------------------------------------------------------------------------- /config/samples/projects/tower_v1alpha1_ansibleproject-git.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleProject 3 | metadata: 4 | name: git 5 | spec: 6 | repo: https://github.com/ansible/ansible-tower-samples 7 | branch: master 8 | name: ProjectDemo-git 9 | scm_type: git 10 | organization: Default 11 | description: demoProject 12 | connection_secret: awxaccess 13 | runner_pull_policy: IfNotPresent 14 | -------------------------------------------------------------------------------- /config/samples/tower_v1alpha1_ansiblejob-broken-dep.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleJob 3 | metadata: 4 | name: broke-job-deprecated 5 | spec: 6 | tower_auth_secret: awxaccess 7 | job_template_name: Demo Jerb 8 | inventory: Demo Inventory # Inventory prompt on launch needs to be enabled 9 | runner_pull_policy: IfNotPresent 10 | 11 | -------------------------------------------------------------------------------- /config/samples/tower_v1alpha1_ansiblejob-broken.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleJob 3 | metadata: 4 | name: broke-job 5 | spec: 6 | connection_secret: awxaccess 7 | job_template_name: Demo Jerb 8 | inventory: Demo Inventory # Inventory prompt on launch needs to be enabled 9 | runner_pull_policy: IfNotPresent 10 | -------------------------------------------------------------------------------- /config/samples/tower_v1alpha1_ansiblejob-dep.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleJob 3 | metadata: 4 | name: demo-job-deprecated 5 | # generateName: demo-job- # generate a unique suffix per 'kubectl create' 6 | spec: 7 | tower_auth_secret: awxaccess 8 | job_template_name: Demo Job Template 9 | inventory: Demo Inventory # Inventory prompt on launch needs to be enabled 10 | extra_vars: # Extra variables prompt on launch needs to be enabled 11 | cost: 6.88 12 | ghosts: ["inky", "pinky", "clyde", "sue"] 13 | is_enable: false 14 | other_variable: foo 15 | pacman: mrs 16 | size: 8 17 | targets_list: 18 | - aaa 19 | - bbb 20 | - ccc 21 | version: 1.23.45 22 | job_tags: "provision,install,configuration" 23 | skip_tags: "configuration,restart" 24 | 25 | -------------------------------------------------------------------------------- /config/samples/tower_v1alpha1_ansiblejob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleJob 3 | metadata: 4 | name: demo-job 5 | # generateName: demo-job- # generate a unique suffix per 'kubectl create' 6 | spec: 7 | connection_secret: awxaccess 8 | job_template_name: Demo Job Template 9 | inventory: Demo Inventory # Inventory prompt on launch needs to be enabled 10 | extra_vars: # Extra variables prompt on launch needs to be enabled 11 | cost: 6.88 12 | ghosts: ["inky", "pinky", "clyde", "sue"] 13 | is_enable: false 14 | other_variable: foo 15 | pacman: mrs 16 | size: 8 17 | targets_list: 18 | - aaa 19 | - bbb 20 | - ccc 21 | version: 1.23.45 22 | job_tags: "provision,install,configuration" 23 | skip_tags: "configuration,restart" 24 | -------------------------------------------------------------------------------- /config/samples/tower_v1alpha1_ansibleschedule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleSchedule 3 | metadata: 4 | name: schedule 5 | spec: 6 | connection_secret: awxaccess 7 | runner_pull_policy: IfNotPresent 8 | name: "Demo Schedule" 9 | rrule: "DTSTART:20210101T000000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=1" 10 | unified_job_template: "Demo Job Template" 11 | -------------------------------------------------------------------------------- /config/samples/workflow/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_ansibleworkflow.yaml 4 | #+kubebuilder:scaffold:manifestskustomizesamples 5 | -------------------------------------------------------------------------------- /config/samples/workflow/tower_v1alpha1_ansibleworkflow-broken.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleWorkflow 3 | metadata: 4 | name: broken 5 | spec: 6 | inventory: Demo Inventory 7 | workflow_template_name: Demo jerb 8 | connection_secret: awxaccess 9 | runner_pull_policy: IfNotPresent 10 | -------------------------------------------------------------------------------- /config/samples/workflow/tower_v1alpha1_ansibleworkflow.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleWorkflow 3 | metadata: 4 | name: workflow 5 | spec: 6 | inventory: Demo Inventory 7 | workflow_template_name: Demo Job Template 8 | connection_secret: awxaccess 9 | runner_pull_policy: IfNotPresent 10 | -------------------------------------------------------------------------------- /config/samples/workflowtemplate/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - tower_v1alpha1_workflowtemplate.yaml 4 | #+kubebuilder:scaffold:manifestskustomizesamples 5 | -------------------------------------------------------------------------------- /config/samples/workflowtemplate/tower_v1alpha1_workflowtemplate-broken.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: WorkflowTemplate 3 | metadata: 4 | name: workflowtemplate-broken 5 | spec: 6 | connection_secret: awxaccess 7 | name: BrokenTemplate 8 | description: Example Workflow Template 9 | organization: Default 10 | inventory: Demo Inventory 11 | workflow_nodes: 12 | - identifier: node101 13 | unified_job_template: 14 | name: Demo Job Template Missing 15 | inventory: 16 | organization: 17 | name: Default 18 | type: job_template 19 | - identifier: node102 20 | unified_job_template: 21 | name: Demo Job Template Missing 22 | inventory: 23 | organization: 24 | name: Default 25 | type: job_template 26 | -------------------------------------------------------------------------------- /config/samples/workflowtemplate/tower_v1alpha1_workflowtemplate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: WorkflowTemplate 3 | metadata: 4 | name: workflowtemplate-sample 5 | spec: 6 | connection_secret: awxaccess 7 | name: ExampleTowerWorkflow 8 | description: Example Workflow Template 9 | organization: Default 10 | inventory: Demo Inventory 11 | workflow_nodes: 12 | - identifier: node101 13 | unified_job_template: 14 | name: Demo Job Template 15 | inventory: 16 | organization: 17 | name: Default 18 | type: job_template 19 | - identifier: node102 20 | unified_job_template: 21 | name: Demo Job Template 22 | inventory: 23 | organization: 24 | name: Default 25 | type: job_template 26 | -------------------------------------------------------------------------------- /config/scorecard/bases/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scorecard.operatorframework.io/v1alpha3 2 | kind: Configuration 3 | metadata: 4 | name: config 5 | stages: 6 | - parallel: true 7 | tests: [] 8 | -------------------------------------------------------------------------------- /config/scorecard/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - bases/config.yaml 3 | patchesJson6902: 4 | - path: patches/basic.config.yaml 5 | target: 6 | group: scorecard.operatorframework.io 7 | version: v1alpha3 8 | kind: Configuration 9 | name: config 10 | - path: patches/olm.config.yaml 11 | target: 12 | group: scorecard.operatorframework.io 13 | version: v1alpha3 14 | kind: Configuration 15 | name: config 16 | #+kubebuilder:scaffold:patchesJson6902 17 | -------------------------------------------------------------------------------- /config/scorecard/patches/basic.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - basic-check-spec 7 | image: quay.io/operator-framework/scorecard-test:v1.22.2 8 | labels: 9 | suite: basic 10 | test: basic-check-spec-test 11 | -------------------------------------------------------------------------------- /config/scorecard/patches/olm.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - olm-bundle-validation 7 | image: quay.io/operator-framework/scorecard-test:v1.22.2 8 | labels: 9 | suite: olm 10 | test: olm-bundle-validation-test 11 | - op: add 12 | path: /stages/0/tests/- 13 | value: 14 | entrypoint: 15 | - scorecard-test 16 | - olm-crds-have-validation 17 | image: quay.io/operator-framework/scorecard-test:v1.22.2 18 | labels: 19 | suite: olm 20 | test: olm-crds-have-validation-test 21 | - op: add 22 | path: /stages/0/tests/- 23 | value: 24 | entrypoint: 25 | - scorecard-test 26 | - olm-crds-have-resources 27 | image: quay.io/operator-framework/scorecard-test:v1.22.2 28 | labels: 29 | suite: olm 30 | test: olm-crds-have-resources-test 31 | - op: add 32 | path: /stages/0/tests/- 33 | value: 34 | entrypoint: 35 | - scorecard-test 36 | - olm-spec-descriptors 37 | image: quay.io/operator-framework/scorecard-test:v1.22.2 38 | labels: 39 | suite: olm 40 | test: olm-spec-descriptors-test 41 | - op: add 42 | path: /stages/0/tests/- 43 | value: 44 | entrypoint: 45 | - scorecard-test 46 | - olm-status-descriptors 47 | image: quay.io/operator-framework/scorecard-test:v1.22.2 48 | labels: 49 | suite: olm 50 | test: olm-status-descriptors-test 51 | -------------------------------------------------------------------------------- /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: awx-resource-manager 12 | env: 13 | - name: ANSIBLE_DEBUG_LOGS 14 | value: "TRUE" 15 | -------------------------------------------------------------------------------- /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 | 11 | apiVersion: kustomize.config.k8s.io/v1beta1 12 | kind: Kustomization 13 | resources: 14 | - ../crd 15 | - ../rbac 16 | - ../manager 17 | images: 18 | - name: testing 19 | newName: testing-operator 20 | patches: 21 | - path: pull_policy/Never.yaml 22 | - path: manager_image.yaml 23 | - path: debug_logs_patch.yaml 24 | - path: ../default/manager_auth_proxy_patch.yaml 25 | -------------------------------------------------------------------------------- /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: awx-resource-manager 12 | image: testing 13 | -------------------------------------------------------------------------------- /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: awx-resource-manager 12 | imagePullPolicy: Always 13 | -------------------------------------------------------------------------------- /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: awx-resource-manager 12 | imagePullPolicy: IfNotPresent 13 | -------------------------------------------------------------------------------- /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: awx-resource-manager 12 | imagePullPolicy: Never 13 | -------------------------------------------------------------------------------- /dev/create_oauth2_token.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | collections: 5 | - awx.awx 6 | - ansible.controller 7 | tasks: 8 | - name: Create OAuth2 token for admin user 9 | block: 10 | - name: Try with awx.awx.token 11 | awx.awx.token: 12 | description: "Auto-generated token by up.sh" 13 | scope: "write" 14 | state: present 15 | controller_username: "{{ lookup('env', 'RESOURCE_SERVER_ADMIN_USER') }}" 16 | controller_password: "{{ lookup('env', 'RESOURCE_SERVER_ADMIN_PASSWORD') }}" 17 | controller_host: "{{ lookup('env', 'RESOURCE_SERVER_URL') }}" 18 | validate_certs: false 19 | register: token_result 20 | rescue: 21 | - name: Fallback to ansible.controller.token 22 | ansible.controller.token: 23 | description: "Auto-generated token by up.sh" 24 | scope: "write" 25 | state: present 26 | controller_username: "{{ lookup('env', 'RESOURCE_SERVER_ADMIN_USER') }}" 27 | controller_password: "{{ lookup('env', 'RESOURCE_SERVER_ADMIN_PASSWORD') }}" 28 | controller_host: "{{ lookup('env', 'RESOURCE_SERVER_URL') }}" 29 | validate_certs: false 30 | register: token_result 31 | 32 | - name: Set token as environment variable 33 | set_fact: 34 | oauth2_token: "{{ token_result.ansible_facts.tower_token.token }}" 35 | 36 | - name: Display token information 37 | debug: 38 | msg: "Token created successfully: {{ oauth2_token }}" 39 | 40 | - name: Export token to environment variable 41 | shell: echo "export RESOURCE_SERVER_TOKEN={{ oauth2_token }}" 42 | register: export_result 43 | -------------------------------------------------------------------------------- /docs/development.md: -------------------------------------------------------------------------------- 1 | # Development Guide – `awx-resource-operator` 2 | 3 | This guide covers how to build, deploy, and test the `awx-resource-operator` locally using helper scripts and development manifests. 4 | 5 | The [`dev/`](../dev) directory contains YAML examples and helper resources, and the root of the repo includes `up.sh` and `down.sh` scripts to streamline development and testing. 6 | 7 | --- 8 | 9 | ## Build and Deploy 10 | 11 | After cloning the repository and logging in to your OpenShift or Kubernetes cluster via the CLI (`oc` or `kubectl`), you can bring up the operator and its resources with the following commands: 12 | 13 | ```bash 14 | export QUAY_USER=username 15 | export NAMESPACE=resource 16 | export TAG=test 17 | ./up.sh 18 | ``` 19 | 20 | --- 21 | 22 | ## Connection Secret Configuration 23 | 24 | The operator requires a connection secret to communicate with your AWX instance. There are two ways to configure this: 25 | 26 | ### Option 1: Automatic OAuth2 Token Generation (Recommended) 27 | 28 | The operator can automatically generate an OAuth2 token using admin credentials. Simply set these environment variables: 29 | 30 | ```bash 31 | export RESOURCE_SERVER_URL="https://your-awx-instance.com" 32 | export RESOURCE_SERVER_ADMIN_USER="admin" 33 | export RESOURCE_SERVER_ADMIN_PASSWORD="password" 34 | ``` 35 | 36 | When these variables are set, `up.sh` will: 37 | 1. Automatically generate an OAuth2 token using the provided credentials 38 | 2. Create a connection secret named `awxaccess` in your specified namespace 39 | 3. Configure the operator to use this connection 40 | 41 | > **Note**: This method requires `ansible-playbook` to be installed on your system. 42 | 43 | ### Option 2: Using an Existing OAuth2 Token 44 | 45 | If you prefer to use an existing token or cannot use automatic generation, set these environment variables: 46 | 47 | ```bash 48 | export RESOURCE_SERVER_URL="https://your-awx-instance.com" 49 | export RESOURCE_SERVER_TOKEN="your-awx-token" 50 | ``` 51 | 52 | For information about manually creating tokens in AWX, see the [AWX documentation on token creation](https://docs.ansible.com/automation-controller/latest/html/userguide/applications_auth.html#add-tokens). 53 | 54 | If neither option's variables are set, the script will display a warning and skip secret creation. 55 | 56 | --- 57 | 58 | ## Using the Resource Operator 59 | 60 | You can now create a connection k8s secret to connect to your AWX instance, then try out some of the sample job templates and jobs in the config/samples directory. See the top level [README.md](../README.md) for more information on how to do that. 61 | 62 | --- 63 | 64 | ## Clean Up 65 | 66 | To tear down your development namespace and resources: 67 | 68 | ```bash 69 | ./down.sh 70 | ``` 71 | 72 | This will delete the namespace you specified (via `NAMESPACE`) and all related resources. 73 | 74 | --- 75 | 76 | ## Running CI Tests Locally 77 | 78 | Basic linting and CI checks can be run with: 79 | 80 | ```bash 81 | make lint 82 | ``` 83 | 84 | Additional test coverage and integration tests will be added in future updates. 85 | 86 | --- 87 | 88 | Let me know if you'd like a separate section on debugging or pushing updated manifests for CRDs or CSVs! 89 | -------------------------------------------------------------------------------- /docs/images/on-launch-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/docs/images/on-launch-configuration.png -------------------------------------------------------------------------------- /down.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # AWX Resource Operator down.sh 3 | 4 | # -- Usage 5 | # NAMESPACE=resource ./down.sh 6 | 7 | # -- Variables 8 | NAMESPACE=${NAMESPACE:-resource} 9 | TAG=${TAG:-dev} 10 | QUAY_USER=${QUAY_USER:-developer} 11 | IMG=quay.io/$QUAY_USER/eda-server-operator:$TAG 12 | 13 | # Delete old operator deployment 14 | oc delete deployment resource-operator-controller-manager 15 | 16 | # Deploy Operator 17 | make undeploy IMG=$IMG NAMESPACE=$NAMESPACE 18 | 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /molecule/default/create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | tasks: [] 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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: yes 15 | loop: '{{ resources.stdout | from_yaml_all | list }}' 16 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: delegated 6 | lint: | 7 | set -e 8 | yamllint -d "{extends: relaxed, rules: {line-length: {max: 120}}}" . 9 | ansible-lint 10 | platforms: 11 | - name: cluster 12 | groups: 13 | - k8s 14 | provisioner: 15 | name: ansible 16 | inventory: 17 | group_vars: 18 | all: 19 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 20 | host_vars: 21 | localhost: 22 | ansible_python_interpreter: '{{ ansible_playbook_python }}' 23 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 24 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 25 | operator_image: ${OPERATOR_IMAGE:-""} 26 | operator_pull_policy: ${OPERATOR_PULL_POLICY:-"Always"} 27 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 28 | env: 29 | K8S_AUTH_KUBECONFIG: ${KUBECONFIG:-"~/.kube/config"} 30 | verifier: 31 | name: ansible 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /molecule/default/tasks/ansiblecredential_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the tower.ansible.com/v1alpha1.AnsibleCredential 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: 'tower_v1alpha1_ansiblecredential.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /molecule/default/tasks/ansibleinstancegroup_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the tower.ansible.com/v1alpha1.AnsibleInstanceGroup 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: 'tower_v1alpha1_ansibleinstancegroup.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /molecule/default/tasks/ansiblejob_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # TODO: Find a way to create a temp AWX, create a token with awx.awx collection and test integration 3 | # - name: Create the tower.ansible.com/v1alpha1.AnsibleJob 4 | # k8s: 5 | # state: present 6 | # namespace: '{{ namespace }}' 7 | # definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}" 8 | # wait: yes 9 | # wait_timeout: 300 10 | # wait_condition: 11 | # type: Running 12 | # reason: Successful 13 | # status: "True" 14 | # vars: 15 | # cr_file: 'tower_v1alpha1_ansiblejob.yaml' 16 | 17 | # TODO: Remove once CI is fully added 18 | - name: Add assertions here 19 | assert: 20 | that: true 21 | fail_msg: FIXME Add real assertions for your operator 22 | -------------------------------------------------------------------------------- /molecule/default/tasks/ansibleproject_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the tower.ansible.com/v1alpha1.AnsibleProject 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: 'tower_v1alpha1_ansibleproject.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /molecule/default/tasks/ansibleschedule_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the tower.ansible.com/v1alpha1.AnsibleSchedule 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: 'tower_v1alpha1_ansibleschedule.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /molecule/default/tasks/ansibleworkflow_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the tower.ansible.com/v1alpha1.AnsibleWorkflow 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: 'tower_v1alpha1_ansibleworkflow.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /molecule/default/tasks/inventory_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the tower.ansible.com/v1alpha1.Inventory 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: 'tower_v1alpha1_inventory.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /molecule/default/tasks/jobtemplate_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # TODO: Find a way to create a temp AWX, create a token with awx.awx collection and test integration 3 | # - name: Create the tower.ansible.com/v1alpha1.JobTemplate 4 | # k8s: 5 | # state: present 6 | # namespace: '{{ namespace }}' 7 | # definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}" 8 | # wait: yes 9 | # wait_timeout: 300 10 | # wait_condition: 11 | # type: Running 12 | # reason: Successful 13 | # status: "True" 14 | # vars: 15 | # cr_file: 'tower_v1alpha1_jobtemplate.yaml' 16 | 17 | # TODO: Remove once CI is fully added 18 | - name: Add assertions here 19 | assert: 20 | that: true 21 | fail_msg: FIXME Add real assertions for your operator 22 | -------------------------------------------------------------------------------- /molecule/default/tasks/workflowtemplate_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the tower.ansible.com/v1alpha1.WorkflowTemplate 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: 'tower_v1alpha1_workflowtemplate.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /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 | # kubernetes.core.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /molecule/kind/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: delegated 6 | lint: | 7 | set -e 8 | yamllint -d "{extends: relaxed, rules: {line-length: {max: 170}}}" . 9 | platforms: 10 | - name: cluster 11 | groups: 12 | - k8s 13 | provisioner: 14 | name: ansible 15 | playbooks: 16 | prepare: ../default/prepare.yml 17 | verify: ../default/verify.yml 18 | inventory: 19 | group_vars: 20 | all: 21 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 22 | host_vars: 23 | localhost: 24 | ansible_python_interpreter: '{{ ansible_playbook_python }}' 25 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 26 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 27 | project_dir: ${MOLECULE_PROJECT_DIRECTORY} 28 | operator_image: testing-operator 29 | operator_pull_policy: "Never" 30 | kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" 31 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 32 | env: 33 | K8S_AUTH_KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 34 | KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 35 | verifier: 36 | name: ansible 37 | -------------------------------------------------------------------------------- /molecule/requirements.txt: -------------------------------------------------------------------------------- 1 | molecule 2 | molecule-docker 3 | yamllint 4 | ansible-lint 5 | openshift!=0.13.0 6 | jmespath 7 | ansible-core 8 | -------------------------------------------------------------------------------- /molecule/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: community.general 4 | - name: community.docker 5 | - name: kubernetes.core 6 | version: "2.4.2" 7 | - name: operator_sdk.util 8 | version: "0.4.0" 9 | - name: awx.awx 10 | version: ">=22.7.0" 11 | -------------------------------------------------------------------------------- /playbooks/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/playbooks/.placeholder -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: kubernetes.core 4 | version: "2.4.2" 5 | - name: operator_sdk.util 6 | version: "0.4.0" 7 | - name: awx.awx 8 | version: ">=22.7.0" 9 | -------------------------------------------------------------------------------- /roles/credential/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for AnsibleCredential 3 | job_ttl: 60 4 | backoff_limit: 1 5 | -------------------------------------------------------------------------------- /roles/credential/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/roles/credential/files/.placeholder -------------------------------------------------------------------------------- /roles/credential/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for AnsibleCredential 3 | -------------------------------------------------------------------------------- /roles/credential/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 | -------------------------------------------------------------------------------- /roles/credential/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Read AnsibleCredentials info 3 | kubernetes.core.k8s_info: 4 | api_version: tower.ansible.com/v1alpha1 5 | kind: AnsibleCredential 6 | name: "{{ ansible_operator_meta.name }}" 7 | namespace: "{{ ansible_operator_meta.namespace }}" 8 | register: ansiblecred_info 9 | 10 | - name: End play early is AnsibleCredentials has already finished 11 | meta: end_play 12 | when: 13 | - ansiblecred_info['resources'][0]['status']['isFinished'] is defined 14 | - ansiblecred_info['resources'][0]['status']['isFinished'] 15 | 16 | - block: 17 | - name: Check number of attempts to execute the job have been made 18 | set_fact: 19 | _attempts: "{{ k8s_job['resources'][0]['status']['failed'] | default(0) }}" 20 | 21 | - name: Set the maximum failed attempts allowed based on the backoffLimit 22 | set_fact: 23 | _failures_allowed: "{{ backoff_limit }} + 1" 24 | 25 | - name: Update AnsibleCredential status if backoff limit is exceeded 26 | operator_sdk.util.k8s_status: 27 | api_version: tower.ansible.com/v1alpha1 28 | kind: AnsibleCredential 29 | name: "{{ ansible_operator_meta.name }}" 30 | namespace: "{{ ansible_operator_meta.namespace }}" 31 | status: 32 | isFinished: true 33 | message: "This job instance reached its backoff limit. Inspect playbook output for more info." 34 | when: 35 | - _attempts >= _failures_allowed 36 | 37 | - name: Update AnsibleCredential status with message 38 | operator_sdk.util.k8s_status: 39 | api_version: tower.ansible.com/v1alpha1 40 | kind: AnsibleCredential 41 | name: "{{ ansible_operator_meta.name }}" 42 | namespace: "{{ ansible_operator_meta.namespace }}" 43 | status: 44 | message: "This job instance is already running or has reached its end state." 45 | - name: End play early 46 | meta: end_play 47 | when: 48 | - k8s_job['resources'] is defined 49 | - (k8s_job["resources"]|length>0) 50 | 51 | - name: Set user provided runner image 52 | set_fact: 53 | _custom_runner_image: "{{ runner_image }}:{{ runner_version }}" 54 | when: 55 | - runner_image is defined 56 | - runner_version is defined 57 | 58 | - name: Set Runner image URL 59 | set_fact: 60 | _runner_image: "{{ _custom_runner_image | default(lookup('env', 'RELATED_IMAGE_ANSIBLE_JOB_RUNNER_IMAGE')) }}" 61 | 62 | - name: Set Runner Pull Policy 63 | set_fact: 64 | _runner_pull_policy: "{{ runner_pull_policy | default('IfNotPresent') }}" 65 | 66 | - name: Create ServiceAccount to run subsequent jobs 67 | kubernetes.core.k8s: 68 | state: present 69 | definition: "{{ lookup('template', 'service_account.yml.j2') }}" 70 | 71 | - name: Start K8s Runner Job 72 | kubernetes.core.k8s: 73 | state: present 74 | definition: "{{ lookup('template', 'job_definition.yml.j2') }}" 75 | 76 | - name: Set credential name 77 | set_fact: 78 | _credential_name: "{{ name}}" 79 | 80 | - name: Update AnsibleCredential status with K8s job info 81 | operator_sdk.util.k8s_status: 82 | api_version: tower.ansible.com/v1alpha1 83 | kind: AnsibleCredential 84 | name: "{{ ansible_operator_meta.name }}" 85 | namespace: "{{ ansible_operator_meta.namespace }}" 86 | status: 87 | k8sJob: 88 | created: true 89 | message: |- 90 | Monitor the job.batch status for more details with the following commands: 91 | 'kubectl -n {{ ansible_operator_meta.namespace }} get job.batch/{{ ansible_operator_meta.name }}' 92 | 'kubectl -n {{ ansible_operator_meta.namespace }} describe job.batch/{{ ansible_operator_meta.name }}' 93 | 'kubectl -n {{ ansible_operator_meta.namespace }} logs -f job.batch/{{ ansible_operator_meta.name }}' 94 | namespacedName: "{{ ansible_operator_meta.namespace+'/'+ansible_operator_meta.name }}" 95 | env: 96 | inventory: "{{ inventory | default(omit) }}" 97 | secretNamespacedName: "{{ ansible_operator_meta.namespace+'/'+(connection_secret | default(tower_auth_secret, true)) }}" 98 | credentialName: "{{ _credential_name }}" 99 | verifySSL: false 100 | -------------------------------------------------------------------------------- /roles/credential/templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/roles/credential/templates/.placeholder -------------------------------------------------------------------------------- /roles/credential/templates/job_definition.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: "{{ ansible_operator_meta.name }}" 6 | namespace: "{{ ansible_operator_meta.namespace }}" 7 | spec: 8 | ttlSecondsAfterFinished: {{ job_ttl }} 9 | template: 10 | spec: 11 | serviceAccountName: resource-operator-controller-manager-job 12 | containers: 13 | - name: "{{ ansible_operator_meta.name }}" 14 | image: "{{ _runner_image }}" 15 | imagePullPolicy: "{{ _runner_pull_policy }}" 16 | env: 17 | - name: TOWER_OAUTH_TOKEN 18 | valueFrom: 19 | secretKeyRef: 20 | name: "{{ connection_secret }}" 21 | key: token 22 | - name: TOWER_HOST 23 | valueFrom: 24 | secretKeyRef: 25 | name: "{{ connection_secret }}" 26 | key: host 27 | - name: NAME 28 | value: "{{ name }}" 29 | - name: ORGANIZATION 30 | value: "{{ organization }}" 31 | {% if description is defined and description != "" %} 32 | - name: DESCRIPTION 33 | value: "{{ description }}" 34 | {% endif %} 35 | - name: TYPE 36 | value: "{{ type }}" 37 | {% if state is defined and state != "" %} 38 | - name: STATE 39 | value: "{{ state }}" 40 | {% else %} 41 | - name: STATE 42 | value: "present" 43 | {% endif %} 44 | {% if ssh_secret is defined and ssh_secret != "" %} 45 | - name: SSH_SECRET 46 | valueFrom: 47 | secretKeyRef: 48 | name: "{{ ssh_secret }}" 49 | key: id_rsa 50 | {% endif %} 51 | {% if ssh_username is defined and ssh_username != "" %} 52 | - name: SSH_USERNAME 53 | value: "{{ ssh_username }}" 54 | {% endif %} 55 | {% if kubernetes_bearer_token_secret is defined and kubernetes_bearer_token_secret != "" %} 56 | - name: KUBERNETES_API 57 | value: "{{ kubernetes_api }}" 58 | - name: KUBERNETES_BEARER_TOKEN 59 | valueFrom: 60 | secretKeyRef: 61 | name: "{{ kubernetes_bearer_token_secret }}" 62 | key: token 63 | {% endif %} 64 | {% if credential_inputs is defined and credential_inputs != "" %} 65 | - name: CREDENTIAL_INPUTS 66 | value: "{{ credential_inputs }}" 67 | {% endif %} 68 | {% if username_secret is defined and username_secret != "" %} 69 | - name: USERNAME_SECRET 70 | valueFrom: 71 | secretKeyRef: 72 | name: "{{ username_secret }}" 73 | key: username 74 | {% endif %} 75 | {% if token_secret is defined and token_secret != "" %} 76 | - name: TOKEN_SECRET 77 | valueFrom: 78 | secretKeyRef: 79 | name: "{{ token_secret }}" 80 | key: token 81 | {% endif %} 82 | {% if password_secret is defined and password_secret != "" %} 83 | - name: PASSWORD_SECRET 84 | valueFrom: 85 | secretKeyRef: 86 | name: "{{ password_secret }}" 87 | key: password 88 | {% endif %} 89 | - name: TOWER_VERIFY_SSL 90 | value: "False" 91 | - name: ANSIBLECREDENTIAL_NAME 92 | value: "{{ ansible_operator_meta.name }}" 93 | - name: ANSIBLECREDENTIAL_NAMESPACE 94 | value: "{{ ansible_operator_meta.namespace }}" 95 | restartPolicy: Never 96 | backoffLimit: {{ backoff_limit }} 97 | -------------------------------------------------------------------------------- /roles/credential/templates/service_account.yml.j2: -------------------------------------------------------------------------------- 1 | ../../project/templates/service_account.yml.j2 -------------------------------------------------------------------------------- /roles/credential/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for AnsibleCredential 3 | -------------------------------------------------------------------------------- /roles/instancegroup/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for AnsibleInstanceGroup 3 | job_ttl: 3600 4 | backoff_limit: 1 5 | -------------------------------------------------------------------------------- /roles/instancegroup/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/roles/instancegroup/files/.placeholder -------------------------------------------------------------------------------- /roles/instancegroup/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for AnsibleInstanceGroup 3 | -------------------------------------------------------------------------------- /roles/instancegroup/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 | -------------------------------------------------------------------------------- /roles/instancegroup/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Read AnsibleInstanceGroup info 3 | kubernetes.core.k8s_info: 4 | api_version: tower.ansible.com/v1alpha1 5 | kind: AnsibleInstanceGroup 6 | name: "{{ ansible_operator_meta.name }}" 7 | namespace: "{{ ansible_operator_meta.namespace }}" 8 | register: ansibleig_info 9 | 10 | - name: End play early is AnsibleInstanceGroup has already finished 11 | meta: end_play 12 | when: 13 | - ansibleig_info['resources'][0]['status']['isFinished'] is defined 14 | - ansibleig_info['resources'][0]['status']['isFinished'] 15 | 16 | - block: 17 | - name: Check number of attempts to execute the job have been made 18 | set_fact: 19 | _attempts: "{{ k8s_job['resources'][0]['status']['failed'] | default(0) }}" 20 | 21 | - name: Set the maximum failed attempts allowed based on the backoffLimit 22 | set_fact: 23 | _failures_allowed: "{{ backoff_limit }} + 1" 24 | 25 | - name: Update AnsibleInstanceGroup status if backoff limit is exceeded 26 | operator_sdk.util.k8s_status: 27 | api_version: tower.ansible.com/v1alpha1 28 | kind: AnsibleInstanceGroup 29 | name: "{{ ansible_operator_meta.name }}" 30 | namespace: "{{ ansible_operator_meta.namespace }}" 31 | status: 32 | isFinished: true 33 | message: "This job instance reached its backoff limit. Inspect playbook output for more info." 34 | when: 35 | - _attempts >= _failures_allowed 36 | 37 | - name: Update AnsibleInstanceGroup status with message 38 | operator_sdk.util.k8s_status: 39 | api_version: tower.ansible.com/v1alpha1 40 | kind: AnsibleInstanceGroup 41 | name: "{{ ansible_operator_meta.name }}" 42 | namespace: "{{ ansible_operator_meta.namespace }}" 43 | status: 44 | message: "This job instance is already running or has reached its end state." 45 | - name: End play early 46 | meta: end_play 47 | when: 48 | - k8s_job['resources'] is defined 49 | - (k8s_job["resources"]|length>0) 50 | 51 | - name: Read Secret Configuration 52 | kubernetes.core.k8s_info: 53 | kind: Secret 54 | api_version: v1 55 | name: "{{ connection_secret }}" 56 | namespace: "{{ ansible_operator_meta.namespace }}" 57 | register: tower_config_secret 58 | 59 | - name: Validate Secret Exists 60 | assert: 61 | that: 62 | - tower_config_secret["resources"] is defined and (tower_config_secret["resources"]|length>0) 63 | fail_msg: "Tower Secret must exist" 64 | 65 | - name: Set user provided runner image 66 | set_fact: 67 | _custom_runner_image: "{{ runner_image }}:{{ runner_version }}" 68 | when: 69 | - runner_image is defined 70 | - runner_version is defined 71 | 72 | - name: Set Runner image URL 73 | set_fact: 74 | _runner_image: "{{ _custom_runner_image | default(lookup('env', 'RELATED_IMAGE_ANSIBLE_JOB_RUNNER_IMAGE')) }}" 75 | 76 | - name: Set Runner Pull Policy 77 | set_fact: 78 | _runner_pull_policy: "{{ runner_pull_policy | default('IfNotPresent') }}" 79 | 80 | - name: Create ServiceAccount to run subsequent jobs 81 | kubernetes.core.k8s: 82 | state: present 83 | definition: "{{ lookup('template', 'service_account.yml.j2') }}" 84 | 85 | - name: Start K8s Runner Job 86 | kubernetes.core.k8s: 87 | state: present 88 | definition: "{{ lookup('template', 'job_definition.yml.j2') }}" 89 | 90 | - name: Set instance_group name 91 | set_fact: 92 | _instance_group_name: "{{ name}}" 93 | 94 | - name: Update AnsibleInstanceGroup status with K8s job info 95 | operator_sdk.util.k8s_status: 96 | api_version: tower.ansible.com/v1alpha1 97 | kind: AnsibleInstanceGroup 98 | name: "{{ ansible_operator_meta.name }}" 99 | namespace: "{{ ansible_operator_meta.namespace }}" 100 | status: 101 | k8sJob: 102 | created: true 103 | message: |- 104 | Monitor the job.batch status for more details with the following commands: 105 | 'kubectl -n {{ ansible_operator_meta.namespace }} get job.batch/{{ ansible_operator_meta.name }}' 106 | 'kubectl -n {{ ansible_operator_meta.namespace }} describe job.batch/{{ ansible_operator_meta.name }}' 107 | 'kubectl -n {{ ansible_operator_meta.namespace }} logs -f job.batch/{{ ansible_operator_meta.name }}' 108 | namespacedName: "{{ ansible_operator_meta.namespace+'/'+ansible_operator_meta.name }}" 109 | env: 110 | inventory: "{{ inventory | default(omit) }}" 111 | secretNamespacedName: "{{ ansible_operator_meta.namespace+'/'+(connection_secret | default(tower_auth_secret, true)) }}" 112 | instance_groupName: "{{ _instance_group_name }}" 113 | verifySSL: false 114 | -------------------------------------------------------------------------------- /roles/instancegroup/templates/job_definition.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: "{{ ansible_operator_meta.name }}" 6 | namespace: "{{ ansible_operator_meta.namespace }}" 7 | spec: 8 | ttlSecondsAfterFinished: {{ job_ttl }} 9 | template: 10 | spec: 11 | serviceAccountName: resource-operator-controller-manager-job 12 | containers: 13 | - name: "{{ ansible_operator_meta.name }}" 14 | image: "{{ _runner_image }}" 15 | imagePullPolicy: "{{ _runner_pull_policy }}" 16 | env: 17 | - name: TOWER_OAUTH_TOKEN 18 | valueFrom: 19 | secretKeyRef: 20 | name: "{{ connection_secret }}" 21 | key: token 22 | - name: TOWER_HOST 23 | valueFrom: 24 | secretKeyRef: 25 | name: "{{ connection_secret }}" 26 | key: host 27 | - name: NAME 28 | value: "{{ name }}" 29 | {% if state is defined and state != "" %} 30 | - name: STATE 31 | value: "{{ state }}" 32 | {% else %} 33 | - name: STATE 34 | value: "present" 35 | {% endif %} 36 | {% if credential_name is defined and credential_name != "" %} 37 | - name: CREDENTIAL_NAME 38 | value: "{{ credential_name }}" 39 | {% endif %} 40 | {% if is_container_group is defined %} 41 | - name: IS_CONTAINER_GROUP 42 | value: "{{ is_container_group }}" 43 | {% endif %} 44 | {% if max_concurrent_jobs is defined %} 45 | - name: MAX_CONCURRENT_JOBS 46 | value: "{{ max_concurrent_jobs }}" 47 | {% endif %} 48 | {% if max_forks is defined %} 49 | - name: MAX_FORKS 50 | value: "{{ max_forks }}" 51 | {% endif %} 52 | {% if pod_spec_override is defined and pod_spec_override != "" %} 53 | - name: POD_SPEC_OVERRIDE 54 | value: "{{ pod_spec_override }}" 55 | {% elif policy_spec_override is defined and policy_spec_override != "" %} 56 | - name: POD_SPEC_OVERRIDE 57 | value: "{{ policy_spec_override }}" 58 | {% endif %} 59 | {% if policy_instance_percentage is defined %} 60 | - name: POLICY_INSTANCE_PERCENTAGE 61 | value: "{{ policy_instance_percentage }}" 62 | {% endif %} 63 | {% if policy_instance_minimum is defined %} 64 | - name: POLICY_INSTANCE_MINIMUM 65 | value: "{{ policy_instance_minimum }}" 66 | {% endif %} 67 | {% if instance_list is defined and instance_list != "" %} 68 | - name: INSTANCE_LIST 69 | value: "{{ instance_list }}" 70 | {% endif %} 71 | - name: TOWER_VERIFY_SSL 72 | value: "False" 73 | - name: ANSIBLEINSTANCEGROUP_NAME 74 | value: "{{ ansible_operator_meta.name }}" 75 | - name: ANSIBLEINSTANCEGROUP_NAMESPACE 76 | value: "{{ ansible_operator_meta.namespace }}" 77 | restartPolicy: Never 78 | backoffLimit: {{ backoff_limit }} 79 | -------------------------------------------------------------------------------- /roles/instancegroup/templates/service_account.yml.j2: -------------------------------------------------------------------------------- 1 | ../../project/templates/service_account.yml.j2 -------------------------------------------------------------------------------- /roles/instancegroup/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for AnsibleInstanceGroup 3 | -------------------------------------------------------------------------------- /roles/inventory/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 | -------------------------------------------------------------------------------- /roles/inventory/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for Inventory 3 | job_ttl: 3600 4 | backoff_limit: 1 5 | -------------------------------------------------------------------------------- /roles/inventory/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/roles/inventory/files/.placeholder -------------------------------------------------------------------------------- /roles/inventory/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for Inventory 3 | -------------------------------------------------------------------------------- /roles/inventory/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 | -------------------------------------------------------------------------------- /roles/inventory/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Read Secret Configuration from connection_secret 3 | kubernetes.core.k8s_info: 4 | kind: Secret 5 | api_version: v1 6 | name: "{{ connection_secret }}" 7 | namespace: "{{ ansible_operator_meta.namespace }}" 8 | register: tower_connection_secret 9 | when: connection_secret is defined 10 | 11 | - name: Set fact based on secret results 12 | set_fact: 13 | tower_config_secret: "{{ tower_connection_secret }}" 14 | 15 | - name: Validate Secret Exists 16 | assert: 17 | that: 18 | - tower_config_secret["resources"] is defined and (tower_config_secret["resources"]|length>0) 19 | fail_msg: "Tower Secret must exist" 20 | 21 | - name: Create inventory based on a copy of the source inventory 22 | awx.awx.inventory: 23 | name: "{{ name }}" 24 | description: "{{ description }}" 25 | organization: "{{ organization }}" 26 | copy_from: "{{ copy_from | default(omit) }}" 27 | state: "{{ state | default('present') }}" 28 | instance_groups: "{{ instance_groups | default(omit) }}" 29 | variables: "{{ variables | default(omit) }}" 30 | environment: 31 | TOWER_OAUTH_TOKEN: "{{ tower_config_secret['resources'][0]['data']['token'] | b64decode }}" 32 | TOWER_HOST: "{{ tower_config_secret['resources'][0]['data']['host'] | b64decode }}" 33 | TOWER_VERIFY_SSL: "False" 34 | register: inventory 35 | ignore_errors: true 36 | 37 | - name: Update the k8s status 38 | operator_sdk.util.k8s_status: 39 | api_version: tower.ansible.com/v1alpha1 40 | kind: ansibleinventory 41 | name: '{{ ansible_operator_meta.name }}' 42 | namespace: '{{ ansible_operator_meta.namespace }}' 43 | status: 44 | isFinished: true 45 | message: "Inventory Created" 46 | when: 47 | - inventory.changed 48 | 49 | - name: Update the k8s status 50 | operator_sdk.util.k8s_status: 51 | api_version: tower.ansible.com/v1alpha1 52 | kind: ansibleinventory 53 | name: '{{ ansible_operator_meta.name }}' 54 | namespace: '{{ ansible_operator_meta.namespace }}' 55 | status: 56 | isFinished: true 57 | error: true 58 | message: "There was an error when creating the inventory" 59 | when: 60 | - inventory.failed 61 | -------------------------------------------------------------------------------- /roles/inventory/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for Inventory 3 | -------------------------------------------------------------------------------- /roles/job/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for job 3 | 4 | job_ttl: 3600 5 | backoff_limit: 1 6 | -------------------------------------------------------------------------------- /roles/job/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for jobtemplate 3 | -------------------------------------------------------------------------------- /roles/job/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Ansible 4 | description: Job role for launching a job in AWX from an openshift or k8s cluster. 5 | company: Red Hat, Inc. 6 | 7 | license: MIT 8 | 9 | min_ansible_version: 2.9 10 | 11 | # If this a Container Enabled role, provide the minimum Ansible Container version. 12 | # min_ansible_container_version: 13 | 14 | # Optionally specify the branch Galaxy will use when accessing the GitHub 15 | # repo for this role. During role install, if no tags are available, 16 | # Galaxy will use this branch. During import Galaxy will access files on 17 | # this branch. If Travis integration is configured, only notifications for this 18 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 19 | # (usually master) will be used. 20 | # github_branch: 21 | 22 | # 23 | # Provide a list of supported platforms, and for each platform a list of versions. 24 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 25 | # To view available platforms and versions (or releases), visit: 26 | # https://galaxy.ansible.com/api/v1/platforms/ 27 | # 28 | platforms: 29 | - name: EL 30 | versions: 31 | - all 32 | - name: Fedora 33 | versions: 34 | - all 35 | - name: Debian 36 | versions: 37 | - all 38 | 39 | galaxy_tags: 40 | - tower 41 | - resource 42 | - awx 43 | - ansible 44 | - automation 45 | - ci 46 | - cd 47 | - deployment 48 | 49 | # List tags for your role here, one per line. A tag is a keyword that describes 50 | # and categorizes the role. Users find roles by searching for tags. Be sure to 51 | # remove the '[]' above, if you add tags to this list. 52 | # 53 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 54 | # Maximum 20 tags per role. 55 | 56 | dependencies: [] 57 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 58 | # if you add dependencies to this list. 59 | 60 | collections: 61 | - operator_sdk.util 62 | - kubernetes.core 63 | -------------------------------------------------------------------------------- /roles/job/templates/job_definition.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: "{{ ansible_operator_meta.name }}" 6 | namespace: "{{ ansible_operator_meta.namespace }}" 7 | spec: 8 | ttlSecondsAfterFinished: {{ job_ttl }} 9 | template: 10 | spec: 11 | serviceAccountName: resource-operator-controller-manager-job 12 | containers: 13 | - name: "{{ ansible_operator_meta.name }}" 14 | image: "{{ _runner_image }}" 15 | imagePullPolicy: "{{ _runner_pull_policy }}" 16 | env: 17 | {% if tower_auth_secret is defined and tower_auth_secret != "" %} 18 | - name: TOWER_OAUTH_TOKEN 19 | valueFrom: 20 | secretKeyRef: 21 | name: "{{ tower_auth_secret }}" 22 | key: token 23 | - name: TOWER_HOST 24 | valueFrom: 25 | secretKeyRef: 26 | name: "{{ tower_auth_secret }}" 27 | key: host 28 | {% endif %} 29 | {% if connection_secret is defined and connection_secret != "" %} 30 | - name: TOWER_OAUTH_TOKEN 31 | valueFrom: 32 | secretKeyRef: 33 | name: "{{ connection_secret }}" 34 | key: token 35 | - name: TOWER_HOST 36 | valueFrom: 37 | secretKeyRef: 38 | name: "{{ connection_secret }}" 39 | key: host 40 | {% endif %} 41 | {% if job_template_name is defined and job_template_name != "" %} 42 | - name: TOWER_JOB_TEMPLATE_NAME 43 | value: "{{ job_template_name }}" 44 | {% endif %} 45 | {% if workflow_template_name is defined and workflow_template_name != "" %} 46 | - name: TOWER_DEPRECATED_WORKFLOW_TEMPLATE_NAME 47 | value: "{{ workflow_template_name }}" 48 | {% endif %} 49 | - name: TOWER_VERIFY_SSL 50 | value: "False" 51 | - name: ANSIBLEJOB_NAME 52 | value: "{{ ansible_operator_meta.name }}" 53 | - name: ANSIBLEJOB_NAMESPACE 54 | value: "{{ ansible_operator_meta.namespace }}" 55 | restartPolicy: Never 56 | backoffLimit: {{ backoff_limit }} 57 | -------------------------------------------------------------------------------- /roles/job/templates/service_account.yml.j2: -------------------------------------------------------------------------------- 1 | ../../project/templates/service_account.yml.j2 -------------------------------------------------------------------------------- /roles/job/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for jobtemplate 3 | -------------------------------------------------------------------------------- /roles/job_runner/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Time before request to AWX api/v2/jobs/{id}/stdout/ times out (in seconds) 4 | request_timeout: 600 5 | -------------------------------------------------------------------------------- /roles/job_runner/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Ansible 4 | description: Job Runner role used by ansible-runner inside the runner container. 5 | company: Red Hat, Inc. 6 | 7 | license: MIT 8 | 9 | min_ansible_version: 2.9 10 | 11 | # If this a Container Enabled role, provide the minimum Ansible Container version. 12 | # min_ansible_container_version: 13 | 14 | # Optionally specify the branch Galaxy will use when accessing the GitHub 15 | # repo for this role. During role install, if no tags are available, 16 | # Galaxy will use this branch. During import Galaxy will access files on 17 | # this branch. If Travis integration is configured, only notifications for this 18 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 19 | # (usually master) will be used. 20 | # github_branch: 21 | 22 | # 23 | # Provide a list of supported platforms, and for each platform a list of versions. 24 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 25 | # To view available platforms and versions (or releases), visit: 26 | # https://galaxy.ansible.com/api/v1/platforms/ 27 | # 28 | platforms: 29 | - name: EL 30 | versions: 31 | - all 32 | - name: Fedora 33 | versions: 34 | - all 35 | - name: Debian 36 | versions: 37 | - all 38 | 39 | galaxy_tags: 40 | - tower 41 | - resource 42 | - awx 43 | - ansible 44 | - automation 45 | - ci 46 | - cd 47 | - deployment 48 | 49 | # List tags for your role here, one per line. A tag is a keyword that describes 50 | # and categorizes the role. Users find roles by searching for tags. Be sure to 51 | # remove the '[]' above, if you add tags to this list. 52 | # 53 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 54 | # Maximum 20 tags per role. 55 | 56 | dependencies: [] 57 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 58 | # if you add dependencies to this list. 59 | 60 | collections: 61 | - operator_sdk.util 62 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/create_instance_group.yml: -------------------------------------------------------------------------------- 1 | - name: Define a instance group, if error update AnsibleInstanceGroup status then end play 2 | block: 3 | - name: Launch instance_group with credentials 4 | awx.awx.instance_group: 5 | name: "{{ lookup('env','NAME') }}" 6 | state: "{{ lookup('env','STATE') | default('present') }}" 7 | credential: "{{ lookup('env','CREDENTIAL_NAME') | default(omit, true) }}" 8 | is_container_group: "{{ lookup('env','IS_CONTAINER_GROUP') | default(omit, true) }}" 9 | max_concurrent_jobs: "{{ lookup('env','MAX_CONCURRENT_JOBS')| default(omit, true) }}" 10 | max_forks: "{{ lookup('env','MAX_FORKS')| default(omit, true) }}" 11 | pod_spec_override: "{{ lookup('env','POD_SPEC_OVERRIDE')| default(omit, true) }}" 12 | policy_instance_percentage: "{{ lookup('env','POLICY_INSTANCE_PERCENTAGE')| default(omit, true) }}" 13 | policy_instance_minimum: "{{ lookup('env','POLICY_INSTANCE_MINIMUM')| default(omit, true) }}" 14 | policy_instance_list: "{{ lookup('env','POLICY_INSTANCE_LIST')| default(omit, true) }}" 15 | instances: "{{ lookup('env','INSTANCES')| default(omit, true) }}" 16 | register: instance_group 17 | 18 | rescue: 19 | - name: Update status if creation resulted in an error 20 | operator_sdk.util.k8s_status: 21 | api_version: tower.ansible.com/v1alpha1 22 | kind: AnsibleInstanceGroup 23 | name: "{{ lookup('env', 'ANSIBLEINSTANCEGROUP_NAME') }}" 24 | namespace: "{{ lookup('env', 'ANSIBLEINSTANCEGROUP_NAMESPACE') }}" 25 | status: 26 | isFinished: true 27 | AnsibleInstanceGroupResult: 28 | status: "error" 29 | - name: End playbook run 30 | meta: end_play 31 | 32 | - name: Update AnsibleInstanceGroup status 33 | operator_sdk.util.k8s_status: 34 | api_version: tower.ansible.com/v1alpha1 35 | kind: AnsibleInstanceGroup 36 | name: "{{ lookup('env', 'ANSIBLEINSTANCEGROUP_NAME') }}" 37 | namespace: "{{ lookup('env', 'ANSIBLEINSTANCEGROUP_NAMESPACE') }}" 38 | status: 39 | isFinished: true 40 | AnsibleInstanceGroupResult: 41 | changed: "{{ instance_group.changed }}" 42 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/create_project.yml: -------------------------------------------------------------------------------- 1 | - name: Define a project, if error update AnsibleProject status then end play 2 | block: 3 | - name: Launch project without credentials 4 | awx.awx.project: 5 | name: "{{ lookup('env','NAME') }}" 6 | description: "{{ lookup('env','DESCRIPTION') }}" 7 | organization: "{{ lookup('env','ORGANIZATION') }}" 8 | scm_update_on_launch: True 9 | scm_type: "{{ lookup('env','SCM_TYPE') }}" 10 | scm_url: "{{ lookup('env','REPO') | default(omit) }}" 11 | state: "{{ lookup('env','STATE') | default('present') }}" 12 | scm_credential: 13 | scm_branch: "{{ lookup('env','BRANCH'| default(omit)) }}" 14 | register: project 15 | when: 16 | - lookup('env','SCM_CREDENTIAL') is not defined or lookup('env','SCM_CREDENTIAL') == '' 17 | 18 | - name: Launch project with credentials 19 | awx.awx.project: 20 | name: "{{ lookup('env','NAME') }}" 21 | description: "{{ lookup('env','DESCRIPTION') }}" 22 | organization: "{{ lookup('env','ORGANIZATION') }}" 23 | scm_update_on_launch: True 24 | scm_type: "{{ lookup('env','SCM_TYPE') }}" 25 | scm_url: "{{ lookup('env','REPO') | default(omit) }}" 26 | scm_credential: "{{ lookup('env','SCM_CREDENTIAL') }}" 27 | state: "{{ lookup('env','STATE') | default('present') }}" 28 | scm_branch: "{{ lookup('env','BRANCH'| default(omit)) }}" 29 | register: project 30 | when: 31 | - lookup('env','SCM_CREDENTIAL') is defined 32 | - lookup('env','SCM_CREDENTIAL') != '' 33 | 34 | rescue: 35 | - name: Update status if creation resulted in an error 36 | operator_sdk.util.k8s_status: 37 | api_version: tower.ansible.com/v1alpha1 38 | kind: AnsibleProject 39 | name: "{{ lookup('env', 'ANSIBLEPROJECT_NAME') }}" 40 | namespace: "{{ lookup('env', 'ANSIBLEPROJECT_NAMESPACE') }}" 41 | status: 42 | isFinished: true 43 | AnsibleProjectResult: 44 | status: "error" 45 | - name: End playbook run 46 | meta: end_play 47 | 48 | - name: Update AnsibleProject status 49 | operator_sdk.util.k8s_status: 50 | api_version: tower.ansible.com/v1alpha1 51 | kind: AnsibleProject 52 | name: "{{ lookup('env', 'ANSIBLEPROJECT_NAME') }}" 53 | namespace: "{{ lookup('env', 'ANSIBLEPROJECT_NAMESPACE') }}" 54 | status: 55 | isFinished: true 56 | AnsibleProjectResult: 57 | changed: "{{ project.changed }}" 58 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/create_schedule.yml: -------------------------------------------------------------------------------- 1 | - name: Define a schedule, if error update AnsibleSchedule status then end play 2 | block: 3 | - name: Launch schedule 4 | awx.awx.schedule: 5 | name: "{{ lookup('env','NAME') }}" 6 | rrule: "{{ lookup('env','RRULE') }}" 7 | state: "{{ lookup('env','STATE') | default('present') }}" 8 | unified_job_template: "{{ lookup('env','UNIFIED_JOB_TEMPLATE') }}" 9 | register: schedule 10 | rescue: 11 | - name: Update status if creation resulted in an error 12 | operator_sdk.util.k8s_status: 13 | api_version: tower.ansible.com/v1alpha1 14 | kind: AnsibleSchedule 15 | name: "{{ lookup('env', 'ANSIBLESCHEDULE_NAME') }}" 16 | namespace: "{{ lookup('env', 'ANSIBLESCHEDULE_NAMESPACE') }}" 17 | status: 18 | isFinished: true 19 | AnsibleCredentialsResult: 20 | status: "error" 21 | - name: End playbook run 22 | meta: end_play 23 | 24 | - name: Update AnsibleSchedule status 25 | operator_sdk.util.k8s_status: 26 | api_version: tower.ansible.com/v1alpha1 27 | kind: AnsibleSchedule 28 | name: "{{ lookup('env', 'ANSIBLESCHEDULE_NAME') }}" 29 | namespace: "{{ lookup('env', 'ANSIBLESCHEDULE_NAMESPACE') }}" 30 | status: 31 | isFinished: true 32 | AnsibleScheduleResult: 33 | changed: "{{ schedule.changed }}" 34 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/credentials.yml: -------------------------------------------------------------------------------- 1 | - name: Launch SSH Credential 2 | include_tasks: credentials/create_ssh_credential.yml 3 | when: 4 | - lookup('env','SSH_SECRET') != '' 5 | - lookup('env','KUBERNETES_BEARER_TOKEN') == '' 6 | - lookup('env','USERNAME_SECRET') == '' 7 | - lookup('env','PASSWORD_SECRET') == '' 8 | - lookup('env','TOKEN_SECRET') == '' 9 | 10 | - name: Launch Bearer Credential 11 | include_tasks: credentials/create_bearer_credential.yml 12 | when: 13 | - lookup('env','KUBERNETES_BEARER_TOKEN') != '' 14 | - lookup('env','SSH_SECRET') == '' 15 | - lookup('env','USERNAME_SECRET') == '' 16 | - lookup('env','PASSWORD_SECRET') == '' 17 | - lookup('env','TOKEN_SECRET') == '' 18 | 19 | - name: Launch Username Credential 20 | include_tasks: credentials/create_userpass_credential.yml 21 | when: 22 | - lookup('env','KUBERNETES_BEARER_TOKEN') == '' 23 | - lookup('env','SSH_SECRET') == '' 24 | - lookup('env','USERNAME_SECRET') != '' 25 | - lookup('env','PASSWORD_SECRET') != '' 26 | - lookup('env','TOKEN_SECRET') == '' 27 | 28 | - name: Launch Token Credential 29 | include_tasks: credentials/create_token_credential.yml 30 | when: 31 | - lookup('env','KUBERNETES_BEARER_TOKEN') == '' 32 | - lookup('env','SSH_SECRET') == '' 33 | - lookup('env','USERNAME_SECRET') == '' 34 | - lookup('env','PASSWORD_SECRET') == '' 35 | - lookup('env','TOKEN_SECRET') != '' 36 | 37 | - name: Launch Generic Credential 38 | include_tasks: credentials/create_generic_credential.yml 39 | when: 40 | - lookup('env','SSH_SECRET') == '' 41 | - lookup('env','KUBERNETES_BEARER_TOKEN') == '' 42 | - lookup('env','USERNAME_SECRET') == '' 43 | - lookup('env','PASSWORD_SECRET') == '' 44 | - lookup('env','TOKEN_SECRET') == '' 45 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/credentials/create_bearer_credential.yml: -------------------------------------------------------------------------------- 1 | - name: Define Bearer credentials, if error update AnsibleCredential status then end play 2 | block: 3 | - name: Create Bearer Credential 4 | awx.awx.credential: 5 | name: "{{ lookup('env','NAME') }}" 6 | description: "{{ lookup('env','DESCRIPTION') }}" 7 | organization: "{{ lookup('env','ORGANIZATION') }}" 8 | credential_type: "{{ lookup('env','TYPE') }}" 9 | inputs: 10 | bearer_token: "{{ lookup('env','KUBERNETES_BEARER_TOKEN') }}" 11 | host: "{{ lookup('env','KUBERNETES_API') }}" 12 | verify_ssl: False 13 | state: present 14 | register: credentials 15 | 16 | rescue: 17 | - name: Update status if creation resulted in an error 18 | operator_sdk.util.k8s_status: 19 | api_version: tower.ansible.com/v1alpha1 20 | kind: AnsibleCredential 21 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 22 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 23 | status: 24 | isFinished: true 25 | AnsibleCredentialsResult: 26 | status: "error" 27 | - name: End playbook run 28 | meta: end_play 29 | 30 | - name: Update AnsibleCredential status 31 | operator_sdk.util.k8s_status: 32 | api_version: tower.ansible.com/v1alpha1 33 | kind: AnsibleCredential 34 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 35 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 36 | status: 37 | isFinished: true 38 | AnsibleCredentialsResult: 39 | changed: "{{ credentials.changed }}" 40 | failed: "{{ credentials.failed }}" 41 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/credentials/create_generic_credential.yml: -------------------------------------------------------------------------------- 1 | - name: Define credentials, if error update AnsibleCredential status then end play 2 | block: 3 | - name: Create Credential 4 | awx.awx.credential: 5 | name: "{{ lookup('env','NAME') | default('present') }}" 6 | description: "{{ lookup('env','DESCRIPTION') }}" 7 | organization: "{{ lookup('env','ORGANIZATION') }}" 8 | credential_type: "{{ lookup('env','TYPE') }}" 9 | inputs: "{{ lookup('env','INPUTS') }}" 10 | state: "{{ lookup('env','STATE') }}" 11 | register: credentials 12 | 13 | rescue: 14 | - name: Update status if creation resulted in an error 15 | operator_sdk.util.k8s_status: 16 | api_version: tower.ansible.com/v1alpha1 17 | kind: AnsibleCredential 18 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 19 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 20 | status: 21 | isFinished: true 22 | AnsibleCredentialsResult: 23 | status: "error" 24 | - name: End playbook run 25 | meta: end_play 26 | 27 | - name: Update AnsibleCredential status 28 | operator_sdk.util.k8s_status: 29 | api_version: tower.ansible.com/v1alpha1 30 | kind: AnsibleCredential 31 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 32 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 33 | status: 34 | isFinished: true 35 | AnsibleCredentialsResult: 36 | changed: "{{ credentials.changed }}" 37 | failed: "{{ credentials.failed }}" 38 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/credentials/create_ssh_credential.yml: -------------------------------------------------------------------------------- 1 | - name: Define SSH credentials, if error update AnsibleCredential status then end play 2 | block: 3 | - name: Create SSH Credential 4 | awx.awx.credential: 5 | name: "{{ lookup('env','NAME') }}" 6 | description: "{{ lookup('env','DESCRIPTION') }}" 7 | organization: "{{ lookup('env','ORGANIZATION') }}" 8 | credential_type: "{{ lookup('env','TYPE') }}" 9 | inputs: 10 | ssh_key_data: "{{ lookup('env','SSH_SECRET') }}" 11 | username: "{{ lookup('env','SSH_USERNAME') }}" 12 | state: present 13 | register: credentials 14 | 15 | rescue: 16 | - name: Update status if creation resulted in an error 17 | operator_sdk.util.k8s_status: 18 | api_version: tower.ansible.com/v1alpha1 19 | kind: AnsibleCredential 20 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 21 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 22 | status: 23 | isFinished: true 24 | AnsibleCredentialsResult: 25 | status: "error" 26 | - name: End playbook run 27 | meta: end_play 28 | 29 | - name: Update AnsibleCredential status 30 | operator_sdk.util.k8s_status: 31 | api_version: tower.ansible.com/v1alpha1 32 | kind: AnsibleCredential 33 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 34 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 35 | status: 36 | isFinished: true 37 | AnsibleCredentialsResult: 38 | changed: "{{ credentials.changed }}" 39 | failed: "{{ credentials.failed }}" 40 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/credentials/create_token_credential.yml: -------------------------------------------------------------------------------- 1 | - name: Define token credential, if error update AnsibleCredential status then end play 2 | block: 3 | - name: Create Username and Password type Credential 4 | awx.awx.credential: 5 | name: "{{ lookup('env','NAME') }}" 6 | description: "{{ lookup('env','DESCRIPTION') }}" 7 | organization: "{{ lookup('env','ORGANIZATION') }}" 8 | credential_type: "{{ lookup('env','TYPE') }}" 9 | inputs: 10 | token: "{{ lookup('env','TOKEN_SECRET') }}" 11 | state: present 12 | register: credentials 13 | 14 | rescue: 15 | - name: Update status if creation resulted in an error 16 | operator_sdk.util.k8s_status: 17 | api_version: tower.ansible.com/v1alpha1 18 | kind: AnsibleCredential 19 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 20 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 21 | status: 22 | isFinished: true 23 | AnsibleCredentialsResult: 24 | status: "error" 25 | - name: End playbook run 26 | meta: end_play 27 | 28 | - name: Update AnsibleCredential status 29 | operator_sdk.util.k8s_status: 30 | api_version: tower.ansible.com/v1alpha1 31 | kind: AnsibleCredential 32 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 33 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 34 | status: 35 | isFinished: true 36 | AnsibleCredentialsResult: 37 | changed: "{{ credentials.changed }}" 38 | failed: "{{ credentials.failed }}" 39 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/credentials/create_userpass_credential.yml: -------------------------------------------------------------------------------- 1 | - name: Define username and password credential, if error update AnsibleCredential status then end play 2 | block: 3 | - name: Create Username and Password type Credential 4 | awx.awx.credential: 5 | name: "{{ lookup('env','NAME') }}" 6 | description: "{{ lookup('env','DESCRIPTION') }}" 7 | organization: "{{ lookup('env','ORGANIZATION') }}" 8 | credential_type: "{{ lookup('env','TYPE') }}" 9 | inputs: 10 | username: "{{ lookup('env','USERNAME_SECRET') }}" 11 | password: "{{ lookup('env','PASSWORD_SECRET') }}" 12 | state: present 13 | register: credentials 14 | 15 | rescue: 16 | - name: Update status if creation resulted in an error 17 | operator_sdk.util.k8s_status: 18 | api_version: tower.ansible.com/v1alpha1 19 | kind: AnsibleCredential 20 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 21 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 22 | status: 23 | isFinished: true 24 | AnsibleCredentialsResult: 25 | status: "error" 26 | - name: End playbook run 27 | meta: end_play 28 | 29 | - name: Update AnsibleCredential status 30 | operator_sdk.util.k8s_status: 31 | api_version: tower.ansible.com/v1alpha1 32 | kind: AnsibleCredential 33 | name: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAME') }}" 34 | namespace: "{{ lookup('env', 'ANSIBLECREDENTIAL_NAMESPACE') }}" 35 | status: 36 | isFinished: true 37 | AnsibleCredentialsResult: 38 | changed: "{{ credentials.changed }}" 39 | failed: "{{ credentials.failed }}" 40 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/launch_deprecated_job.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Deprecation Warning 3 | debug: 4 | msg: "Using an AnsibleJob to run workflows is deprecated. Please use an AnsibleWorkflow instead." 5 | verbosity: 0 6 | 7 | - name: Launch a job, if error update AnsibleJob status then end play 8 | block: 9 | - name: Launch job 10 | awx.awx.workflow_launch: 11 | name: "{{ lookup('env','TOWER_DEPRECATED_WORKFLOW_TEMPLATE_NAME') }}" 12 | extra_vars: "{{ ansible_job['resources'][0]['spec']['extra_vars'] | default(omit) }}" 13 | inventory: "{{ ansible_job['resources'][0]['spec']['inventory'] | default(omit) }}" 14 | tags: "{{ ansible_job['resources'][0]['spec']['job_tags'] | default(omit) }}" 15 | skip_tags: "{{ ansible_job['resources'][0]['spec']['skip_tags'] | default(omit) }}" 16 | register: job 17 | rescue: 18 | - name: Update status if job resulted in an error 19 | operator_sdk.util.k8s_status: 20 | api_version: tower.ansible.com/v1alpha1 21 | kind: AnsibleJob 22 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 23 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 24 | status: 25 | ansibleJobResult: 26 | status: "error" 27 | error_message: "{{ job.msg | default('Job failed to launch. Verify that the credentials in your connection_secret are correct. If they are, check the job standard output for more details.') }}" 28 | - name: End playbook run 29 | meta: end_play 30 | 31 | - name: Update AnsibleJob definition with Tower job id 32 | k8s: 33 | state: present 34 | definition: 35 | kind: AnsibleJob 36 | apiVersion: tower.ansible.com/v1alpha1 37 | metadata: 38 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 39 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 40 | labels: 41 | tower_job_id: "{{ job.id }}" 42 | 43 | - name: Update AnsibleJob status with Tower job status and url 44 | operator_sdk.util.k8s_status: 45 | api_version: tower.ansible.com/v1alpha1 46 | kind: AnsibleJob 47 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 48 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 49 | status: 50 | changed: "{{ job.changed }}" 51 | failed: "{{ job.failed }}" 52 | status: "{{ job.status }}" 53 | url: "{{ lookup('env', 'TOWER_HOST') + '/#/jobs/workflow/' + (job.id|string) }}" 54 | 55 | - name: Wait for the tower job, if error update AnsibleJob status then end play 56 | block: 57 | - name: Register Job result when complete 58 | awx.awx.job_wait: 59 | job_id: "{{ job.id }}" 60 | job_type: workflow_jobs 61 | request_timeout: "{{ request_timeout }}" 62 | register: job_result 63 | rescue: 64 | - name: Update status if job results in an error 65 | operator_sdk.util.k8s_status: 66 | api_version: tower.ansible.com/v1alpha1 67 | kind: AnsibleJob 68 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 69 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 70 | status: 71 | ansibleJobResult: 72 | status: "error" 73 | error_message: "{{ job_result.msg | default('Job failed, check the job for more information: lookup('env', 'TOWER_HOST') + '/#/jobs/workflow/' + (job.id|string)') }}" 74 | - name: End playbook run 75 | meta: end_play 76 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/launch_job.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Launch a job, if error update AnsibleJob status then end play 3 | block: 4 | - name: Launch job 5 | awx.awx.job_launch: 6 | name: "{{ lookup('env','TOWER_JOB_TEMPLATE_NAME') }}" 7 | extra_vars: "{{ ansible_job['resources'][0]['spec']['extra_vars'] | default(omit) }}" 8 | inventory: "{{ ansible_job['resources'][0]['spec']['inventory'] | default(omit) }}" 9 | tags: "{{ ansible_job['resources'][0]['spec']['job_tags'] | default(omit) }}" 10 | skip_tags: "{{ ansible_job['resources'][0]['spec']['skip_tags'] | default(omit) }}" 11 | register: job 12 | rescue: 13 | - name: Update status if job resulted in an error 14 | operator_sdk.util.k8s_status: 15 | api_version: tower.ansible.com/v1alpha1 16 | kind: AnsibleJob 17 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 18 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 19 | status: 20 | ansibleJobResult: 21 | status: "error" 22 | error_message: "{{ job.msg | default('Job failed to launch. Verify that the credentials in your connection_secret are correct. If they are, check the job standard output for more details.') }}" 23 | - name: End playbook run 24 | meta: end_play 25 | 26 | - name: Update AnsibleJob definition with Tower job id 27 | k8s: 28 | state: present 29 | definition: 30 | kind: AnsibleJob 31 | apiVersion: tower.ansible.com/v1alpha1 32 | metadata: 33 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 34 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 35 | labels: 36 | tower_job_id: "{{ job.id }}" 37 | 38 | - name: Update AnsibleJob status with Tower job status and url 39 | operator_sdk.util.k8s_status: 40 | api_version: tower.ansible.com/v1alpha1 41 | kind: AnsibleJob 42 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 43 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 44 | status: 45 | ansibleJobResult: 46 | changed: "{{ job.changed }}" 47 | failed: "{{ job.failed }}" 48 | status: "{{ job.status }}" 49 | url: "{{ lookup('env', 'TOWER_HOST') + '/#/jobs/playbook/' + (job.id|string) }}" 50 | 51 | - name: Wait for the tower job, if error update AnsibleJob status then end play 52 | block: 53 | - name: Register Job result when complete 54 | awx.awx.job_wait: 55 | job_id: "{{ job.id }}" 56 | request_timeout: "{{ request_timeout }}" 57 | register: job_result 58 | rescue: 59 | - name: Update status if job results in an error 60 | operator_sdk.util.k8s_status: 61 | api_version: tower.ansible.com/v1alpha1 62 | kind: AnsibleJob 63 | name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 64 | namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 65 | status: 66 | ansibleJobResult: 67 | status: "error" 68 | error_message: "{{ job_result.msg | default('Job failed, check the job for more information: lookup('env', 'TOWER_HOST') + '/#/jobs/playbook/' + (job.id|string)') }}" 69 | - name: End playbook run 70 | meta: end_play 71 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/launch_workflow.yml: -------------------------------------------------------------------------------- 1 | - name: Launch a workflow, if error update AnsibleWorkflow status then end play 2 | block: 3 | - name: Launch workflow 4 | awx.awx.workflow_launch: 5 | name: "{{ lookup('env','TOWER_WORKFLOW_TEMPLATE_NAME') }}" 6 | extra_vars: "{{ ansible_workflow['resources'][0]['spec']['extra_vars'] | default(omit) }}" 7 | inventory: "{{ ansible_workflow['resources'][0]['spec']['inventory'] | default(omit) }}" 8 | tags: "{{ ansible_workflow['resources'][0]['spec']['job_tags'] | default(omit) }}" 9 | skip_tags: "{{ ansible_workflow['resources'][0]['spec']['skip_tags'] | default(omit) }}" 10 | register: job 11 | rescue: 12 | - name: Update status if job resulted in an error 13 | operator_sdk.util.k8s_status: 14 | api_version: tower.ansible.com/v1alpha1 15 | kind: AnsibleWorkflow 16 | name: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAME') }}" 17 | namespace: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAMESPACE') }}" 18 | status: 19 | AnsibleWorkflowResult: 20 | status: "error" 21 | error_message: "{{ job.msg | default('Job failed to launch. Verify that the credentials in your connection_secret are correct. If they are, check the job standard output for more details.') }}" 22 | - name: End playbook run 23 | meta: end_play 24 | 25 | - name: Update AnsibleWorkflow definition with Tower workflow id 26 | k8s: 27 | state: present 28 | definition: 29 | kind: AnsibleWorkflow 30 | apiVersion: tower.ansible.com/v1alpha1 31 | metadata: 32 | name: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAME') }}" 33 | namespace: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAMESPACE') }}" 34 | labels: 35 | tower_job_id: "{{ job.id }}" 36 | 37 | - name: Update AnsibleWorkflow status with Tower workflow status and url 38 | operator_sdk.util.k8s_status: 39 | api_version: tower.ansible.com/v1alpha1 40 | kind: AnsibleWorkflow 41 | name: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAME') }}" 42 | namespace: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAMESPACE') }}" 43 | status: 44 | ansibleWorkflowResult: 45 | changed: "{{ job.changed }}" 46 | failed: "{{ job.failed }}" 47 | status: "{{ job.status }}" 48 | url: "{{ lookup('env', 'TOWER_HOST') + '/#/jobs/workflow/' + (job.id|string) }}" 49 | 50 | - name: Wait for the tower workflow, if error update AnsibleWorkflow status then end play 51 | block: 52 | - name: Register Job result when complete 53 | awx.awx.job_wait: 54 | job_id: "{{ job.id }}" 55 | job_type: workflow_jobs 56 | request_timeout: "{{ request_timeout }}" 57 | register: job_result 58 | rescue: 59 | - name: Update status if job results in an error 60 | operator_sdk.util.k8s_status: 61 | api_version: tower.ansible.com/v1alpha1 62 | kind: AnsibleWorkflow 63 | name: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAME') }}" 64 | namespace: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAMESPACE') }}" 65 | status: 66 | ansibleWorkflowesult: 67 | status: "error" 68 | error_message: "{{ job_result.msg | default('Job failed, check the job for more information: lookup('env', 'TOWER_HOST') + '/#/jobs/workflow/' + (job.id|string)') }}" 69 | 70 | - name: End playbook run 71 | meta: end_play 72 | -------------------------------------------------------------------------------- /roles/job_runner/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Launch Project 3 | include_tasks: create_project.yml 4 | when: 5 | - lookup('env','ANSIBLEPROJECT_NAME') is defined 6 | - lookup('env','ANSIBLEPROJECT_NAME') != '' 7 | 8 | - name: Launch Credential 9 | include_tasks: credentials.yml 10 | when: 11 | - lookup('env','ANSIBLECREDENTIAL_NAME') is defined 12 | - lookup('env','ANSIBLECREDENTIAL_NAME') != '' 13 | 14 | - name: Launch Schedule 15 | include_tasks: create_schedule.yml 16 | when: 17 | - lookup('env','ANSIBLESCHEDULE_NAME') is defined 18 | - lookup('env','ANSIBLESCHEDULE_NAME') != '' 19 | 20 | - name: Launch Instance Group 21 | include_tasks: create_instance_group.yml 22 | when: 23 | - lookup('env','ANSIBLEINSTANCEGROUP_NAME') is defined 24 | - lookup('env','ANSIBLEINSTANCEGROUP_NAME') != '' 25 | 26 | - name: Read in Environment Variables 27 | set_fact: 28 | ansible_job_name: "{{ lookup('env', 'ANSIBLEJOB_NAME') }}" 29 | ansible_job_namespace: "{{ lookup('env', 'ANSIBLEJOB_NAMESPACE') }}" 30 | ansible_workflow_name: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAME') }}" 31 | ansible_workflow_namespace: "{{ lookup('env', 'ANSIBLEWORKFLOW_NAMESPACE') }}" 32 | tower_job_template_name: "{{ lookup('env', 'TOWER_JOB_TEMPLATE_NAME') }}" 33 | tower_workflow_template_name: "{{ lookup('env', 'TOWER_WORKFLOW_TEMPLATE_NAME') }}" 34 | tower_deprecated_workflow_template_name: "{{ lookup('env', 'TOWER_DEPRECATED_WORKFLOW_TEMPLATE_NAME') }}" 35 | 36 | - name: Set Conditions as Facts 37 | set_fact: 38 | is_tower_job_template_defined: "{{ tower_job_template_name is defined and tower_job_template_name != '' }}" 39 | is_tower_workflow_template_defined: "{{ tower_workflow_template_name is defined and tower_workflow_template_name != '' }}" 40 | is_tower_deprecated_workflow_template_defined: "{{ tower_deprecated_workflow_template_name is defined and tower_deprecated_workflow_template_name != '' }}" 41 | 42 | - name: Read AnsibleJob Specs 43 | kubernetes.core.k8s_info: 44 | kind: AnsibleJob 45 | api_version: tower.ansible.com/v1alpha1 46 | name: "{{ ansible_job_name }}" 47 | namespace: "{{ ansible_job_namespace }}" 48 | register: ansible_job 49 | when: is_tower_job_template_defined or is_tower_deprecated_workflow_template_defined 50 | 51 | - name: Read AnsibleWorkflow Specs 52 | kubernetes.core.k8s_info: 53 | kind: AnsibleWorkflow 54 | api_version: tower.ansible.com/v1alpha1 55 | name: "{{ ansible_workflow_name }}" 56 | namespace: "{{ ansible_workflow_namespace }}" 57 | register: ansible_workflow 58 | when: is_tower_workflow_template_defined 59 | 60 | - name: Launch a job 61 | include_tasks: launch_job.yml 62 | when: is_tower_job_template_defined 63 | 64 | - name: Launch (Deprecated) AnsibleJob Workflow 65 | include_tasks: launch_deprecated_job.yml 66 | when: is_tower_deprecated_workflow_template_defined 67 | 68 | - name: Launch Workflow 69 | include_tasks: launch_workflow.yml 70 | when: is_tower_workflow_template_defined 71 | 72 | - name: Update AnsibleJob status with Tower job result 73 | operator_sdk.util.k8s_status: 74 | api_version: tower.ansible.com/v1alpha1 75 | kind: AnsibleJob 76 | name: "{{ ansible_job_name }}" 77 | namespace: "{{ ansible_job_namespace }}" 78 | status: 79 | ansibleJobResult: 80 | elapsed: "{{ job_result.elapsed }}" 81 | finished: "{{ job_result.finished }}" 82 | started: "{{ job_result.started }}" 83 | status: "{{ job_result.status }}" 84 | when: >- 85 | is_tower_job_template_defined or 86 | is_tower_deprecated_workflow_template_defined 87 | 88 | - name: Update AnsibleWorkflow status with Tower workflow result 89 | operator_sdk.util.k8s_status: 90 | api_version: tower.ansible.com/v1alpha1 91 | kind: AnsibleWorkflow 92 | name: "{{ ansible_workflow_name }}" 93 | namespace: "{{ ansible_workflow_namespace }}" 94 | status: 95 | ansibleWorkflowResult: 96 | elapsed: "{{ job_result.elapsed }}" 97 | finished: "{{ job_result.finished }}" 98 | started: "{{ job_result.started }}" 99 | status: "{{ job_result.status }}" 100 | when: is_tower_workflow_template_defined 101 | -------------------------------------------------------------------------------- /roles/jobtemplate/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for jobtemplate 3 | -------------------------------------------------------------------------------- /roles/jobtemplate/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for jobtemplate 3 | -------------------------------------------------------------------------------- /roles/jobtemplate/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Ansible 4 | description: Job Template role for creating a job template in AWX from an openshift or k8s cluster. 5 | company: Red Hat, Inc. 6 | 7 | license: MIT 8 | 9 | min_ansible_version: 2.9 10 | 11 | # If this a Container Enabled role, provide the minimum Ansible Container version. 12 | # min_ansible_container_version: 13 | 14 | # Optionally specify the branch Galaxy will use when accessing the GitHub 15 | # repo for this role. During role install, if no tags are available, 16 | # Galaxy will use this branch. During import Galaxy will access files on 17 | # this branch. If Travis integration is configured, only notifications for this 18 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 19 | # (usually master) will be used. 20 | # github_branch: 21 | 22 | # 23 | # Provide a list of supported platforms, and for each platform a list of versions. 24 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 25 | # To view available platforms and versions (or releases), visit: 26 | # https://galaxy.ansible.com/api/v1/platforms/ 27 | # 28 | platforms: 29 | - name: EL 30 | versions: 31 | - all 32 | - name: Fedora 33 | versions: 34 | - all 35 | - name: Debian 36 | versions: 37 | - all 38 | 39 | galaxy_tags: 40 | - tower 41 | - resource 42 | - awx 43 | - ansible 44 | - automation 45 | - ci 46 | - cd 47 | - deployment 48 | 49 | # List tags for your role here, one per line. A tag is a keyword that describes 50 | # and categorizes the role. Users find roles by searching for tags. Be sure to 51 | # remove the '[]' above, if you add tags to this list. 52 | # 53 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 54 | # Maximum 20 tags per role. 55 | 56 | dependencies: [] 57 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 58 | # if you add dependencies to this list. 59 | 60 | collections: 61 | - operator_sdk.util 62 | - kubernetes.core 63 | -------------------------------------------------------------------------------- /roles/jobtemplate/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for jobtemplate 3 | -------------------------------------------------------------------------------- /roles/project/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for AnsibleProject 3 | job_ttl: 60 4 | backoff_limit: 1 5 | -------------------------------------------------------------------------------- /roles/project/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/roles/project/files/.placeholder -------------------------------------------------------------------------------- /roles/project/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for AnsibleProject 3 | -------------------------------------------------------------------------------- /roles/project/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 | -------------------------------------------------------------------------------- /roles/project/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Read AnsibleProject info 3 | kubernetes.core.k8s_info: 4 | api_version: tower.ansible.com/v1alpha1 5 | kind: AnsibleProject 6 | name: "{{ ansible_operator_meta.name }}" 7 | namespace: "{{ ansible_operator_meta.namespace }}" 8 | register: ansibleproj_info 9 | 10 | - name: End play early is AnsibleProject has already finished 11 | meta: end_play 12 | when: 13 | - ansibleproj_info['resources'][0]['status']['isFinished'] is defined 14 | - ansibleproj_info['resources'][0]['status']['isFinished'] 15 | 16 | - block: 17 | - name: Check number of attempts to execute the job have been made 18 | set_fact: 19 | _attempts: "{{ k8s_job['resources'][0]['status']['failed'] | default(0) }}" 20 | 21 | - name: Set the maximum failed attempts allowed based on the backoffLimit 22 | set_fact: 23 | _failures_allowed: "{{ backoff_limit }} + 1" 24 | 25 | - name: Update AnsibleProject status if backoff limit is exceeded 26 | operator_sdk.util.k8s_status: 27 | api_version: tower.ansible.com/v1alpha1 28 | kind: AnsibleProject 29 | name: "{{ ansible_operator_meta.name }}" 30 | namespace: "{{ ansible_operator_meta.namespace }}" 31 | status: 32 | isFinished: true 33 | message: "This job instance reached its backoff limit. Inspect playbook output for more info." 34 | when: 35 | - _attempts >= _failures_allowed 36 | 37 | - name: Update AnsibleProject status with message 38 | operator_sdk.util.k8s_status: 39 | api_version: tower.ansible.com/v1alpha1 40 | kind: AnsibleProject 41 | name: "{{ ansible_operator_meta.name }}" 42 | namespace: "{{ ansible_operator_meta.namespace }}" 43 | status: 44 | message: "This job instance is already running or has reached its end state." 45 | - name: End play early 46 | meta: end_play 47 | when: 48 | - k8s_job['resources'] is defined 49 | - (k8s_job["resources"]|length>0) 50 | 51 | - name: Set user provided runner image 52 | set_fact: 53 | _custom_runner_image: "{{ runner_image }}:{{ runner_version }}" 54 | when: 55 | - runner_image is defined 56 | - runner_version is defined 57 | 58 | - name: Set Runner image URL 59 | set_fact: 60 | _runner_image: "{{ _custom_runner_image | default(lookup('env', 'RELATED_IMAGE_ANSIBLE_JOB_RUNNER_IMAGE')) }}" 61 | 62 | - name: Set Runner Pull Policy 63 | set_fact: 64 | _runner_pull_policy: "{{ runner_pull_policy | default('IfNotPresent') }}" 65 | 66 | - name: Create ServiceAccount to run subsequent jobs 67 | kubernetes.core.k8s: 68 | state: present 69 | definition: "{{ lookup('template', 'service_account.yml.j2') }}" 70 | 71 | - name: Start K8s Runner Job 72 | kubernetes.core.k8s: 73 | state: present 74 | definition: "{{ lookup('template', 'job_definition.yml.j2') }}" 75 | 76 | - name: Set project name 77 | set_fact: 78 | _project_name: "{{ name}}" 79 | 80 | - name: Update AnsibleProject status with K8s job info 81 | operator_sdk.util.k8s_status: 82 | api_version: tower.ansible.com/v1alpha1 83 | kind: AnsibleProject 84 | name: "{{ ansible_operator_meta.name }}" 85 | namespace: "{{ ansible_operator_meta.namespace }}" 86 | status: 87 | k8sJob: 88 | created: true 89 | message: |- 90 | Monitor the job.batch status for more details with the following commands: 91 | 'kubectl -n {{ ansible_operator_meta.namespace }} get job.batch/{{ ansible_operator_meta.name }}' 92 | 'kubectl -n {{ ansible_operator_meta.namespace }} describe job.batch/{{ ansible_operator_meta.name }}' 93 | 'kubectl -n {{ ansible_operator_meta.namespace }} logs -f job.batch/{{ ansible_operator_meta.name }}' 94 | namespacedName: "{{ ansible_operator_meta.namespace+'/'+ansible_operator_meta.name }}" 95 | env: 96 | inventory: "{{ inventory | default(omit) }}" 97 | secretNamespacedName: "{{ ansible_operator_meta.namespace+'/'+(connection_secret | default(tower_auth_secret, true)) }}" 98 | projectName: "{{ _project_name }}" 99 | verifySSL: false 100 | -------------------------------------------------------------------------------- /roles/project/templates/job_definition.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: "{{ ansible_operator_meta.name }}" 6 | namespace: "{{ ansible_operator_meta.namespace }}" 7 | spec: 8 | ttlSecondsAfterFinished: {{ job_ttl }} 9 | template: 10 | spec: 11 | serviceAccountName: resource-operator-controller-manager-job 12 | containers: 13 | - name: "{{ ansible_operator_meta.name }}" 14 | image: "{{ _runner_image }}" 15 | imagePullPolicy: "{{ _runner_pull_policy }}" 16 | env: 17 | - name: TOWER_OAUTH_TOKEN 18 | valueFrom: 19 | secretKeyRef: 20 | name: "{{ connection_secret }}" 21 | key: token 22 | - name: TOWER_HOST 23 | valueFrom: 24 | secretKeyRef: 25 | name: "{{ connection_secret }}" 26 | key: host 27 | - name: NAME 28 | value: "{{ name }}" 29 | - name: ORGANIZATION 30 | value: "{{ organization }}" 31 | {% if description is defined and description != "" %} 32 | - name: DESCRIPTION 33 | value: "{{ description }}" 34 | {% endif %} 35 | - name: SCM_TYPE 36 | value: "{{ scm_type }}" 37 | {% if scm_credential is defined and scm_credential != "" %} 38 | - name: SCM_CREDENTIAL 39 | value: "{{ scm_credential }}" 40 | {% endif %} 41 | {% if repo is defined and repo != "" %} 42 | - name: REPO 43 | value: "{{ repo }}" 44 | {% endif %} 45 | {% if branch is defined and branch != "" %} 46 | - name: BRANCH 47 | value: "{{ branch }}" 48 | {% endif %} 49 | {%if state is defined and state != "" %} 50 | - name: STATE 51 | value: "{{ state }}" 52 | {% else %} 53 | - name: STATE 54 | value: "present" 55 | {% endif %} 56 | - name: TOWER_VERIFY_SSL 57 | value: "False" 58 | - name: ANSIBLEPROJECT_NAME 59 | value: "{{ ansible_operator_meta.name }}" 60 | - name: ANSIBLEPROJECT_NAMESPACE 61 | value: "{{ ansible_operator_meta.namespace }}" 62 | restartPolicy: Never 63 | backoffLimit: {{ backoff_limit }} 64 | -------------------------------------------------------------------------------- /roles/project/templates/service_account.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | creationTimestamp: null 6 | name: resource-operator-controller-manager-job 7 | namespace: "{{ ansible_operator_meta.namespace }}" 8 | rules: 9 | - apiGroups: 10 | - "" 11 | - rbac.authorization.k8s.io 12 | resources: 13 | - pods 14 | - serviceaccounts 15 | - roles 16 | - rolebindings 17 | - services 18 | - services/finalizers 19 | - endpoints 20 | - persistentvolumeclaims 21 | - events 22 | - configmaps 23 | - secrets 24 | - jobs 25 | verbs: 26 | - create 27 | - delete 28 | - get 29 | - list 30 | - patch 31 | - update 32 | - watch 33 | - apiGroups: 34 | - apps 35 | resources: 36 | - deployments 37 | - daemonsets 38 | - replicasets 39 | - statefulsets 40 | - jobs 41 | verbs: 42 | - create 43 | - delete 44 | - get 45 | - list 46 | - patch 47 | - update 48 | - watch 49 | - apiGroups: 50 | - monitoring.coreos.com 51 | resources: 52 | - servicemonitors 53 | verbs: 54 | - get 55 | - create 56 | - apiGroups: 57 | - "" 58 | resources: 59 | - pods 60 | - jobs 61 | verbs: 62 | - get 63 | - apiGroups: 64 | - apps 65 | resources: 66 | - replicasets 67 | - deployments 68 | - jobs 69 | verbs: 70 | - get 71 | - apiGroups: 72 | - tower.ansible.com 73 | resources: 74 | - '*' 75 | verbs: 76 | - create 77 | - delete 78 | - get 79 | - list 80 | - patch 81 | - update 82 | - watch 83 | - apiGroups: 84 | - batch 85 | resources: 86 | - '*' 87 | verbs: 88 | - create 89 | - delete 90 | - get 91 | - list 92 | - patch 93 | - update 94 | - watch 95 | 96 | --- 97 | apiVersion: v1 98 | kind: ServiceAccount 99 | metadata: 100 | name: resource-operator-controller-manager-job 101 | namespace: "{{ ansible_operator_meta.namespace }}" 102 | --- 103 | kind: RoleBinding 104 | apiVersion: rbac.authorization.k8s.io/v1 105 | metadata: 106 | name: resource-operator-controller-manager-job 107 | namespace: "{{ ansible_operator_meta.namespace }}" 108 | subjects: 109 | - kind: ServiceAccount 110 | name: resource-operator-controller-manager-job 111 | namespace: "{{ ansible_operator_meta.namespace }}" 112 | roleRef: 113 | kind: Role 114 | name: resource-operator-controller-manager-job 115 | namespace: "{{ ansible_operator_meta.namespace }}" 116 | apiGroup: rbac.authorization.k8s.io 117 | -------------------------------------------------------------------------------- /roles/project/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for AnsibleProject 3 | -------------------------------------------------------------------------------- /roles/schedule/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for AnsibleSchedule 3 | job_ttl: 60 4 | backoff_limit: 1 5 | -------------------------------------------------------------------------------- /roles/schedule/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/roles/schedule/files/.placeholder -------------------------------------------------------------------------------- /roles/schedule/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for AnsibleSchedule 3 | -------------------------------------------------------------------------------- /roles/schedule/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 | -------------------------------------------------------------------------------- /roles/schedule/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Read AnsibleSchedule info 3 | kubernetes.core.k8s_info: 4 | api_version: tower.ansible.com/v1alpha1 5 | kind: AnsibleSchedule 6 | name: "{{ ansible_operator_meta.name }}" 7 | namespace: "{{ ansible_operator_meta.namespace }}" 8 | register: ansiblesched_info 9 | 10 | - name: End play early is AnsibleSchedule has already finished 11 | meta: end_play 12 | when: 13 | - ansiblesched_info['resources'][0]['status']['isFinished'] is defined 14 | - ansiblesched_info['resources'][0]['status']['isFinished'] 15 | 16 | - block: 17 | - name: Check number of attempts to execute the job have been made 18 | set_fact: 19 | _attempts: "{{ k8s_job['resources'][0]['status']['failed'] | default(0) }}" 20 | 21 | - name: Set the maximum failed attempts allowed based on the backoffLimit 22 | set_fact: 23 | _failures_allowed: "{{ backoff_limit }} + 1" 24 | 25 | - name: Update AnsibleSchedule status if backoff limit is exceeded 26 | operator_sdk.util.k8s_status: 27 | api_version: tower.ansible.com/v1alpha1 28 | kind: AnsibleSchedule 29 | name: "{{ ansible_operator_meta.name }}" 30 | namespace: "{{ ansible_operator_meta.namespace }}" 31 | status: 32 | isFinished: true 33 | message: "This job instance reached its backoff limit. Inspect playbook output for more info." 34 | when: 35 | - _attempts >= _failures_allowed 36 | 37 | - name: Update AnsibleSchedule status with message 38 | operator_sdk.util.k8s_status: 39 | api_version: tower.ansible.com/v1alpha1 40 | kind: AnsibleSchedule 41 | name: "{{ ansible_operator_meta.name }}" 42 | namespace: "{{ ansible_operator_meta.namespace }}" 43 | status: 44 | message: "This job instance is already running or has reached its end state." 45 | - name: End play early 46 | meta: end_play 47 | when: 48 | - k8s_job['resources'] is defined 49 | - (k8s_job["resources"]|length>0) 50 | 51 | - name: Set user provided runner image 52 | set_fact: 53 | _custom_runner_image: "{{ runner_image }}:{{ runner_version }}" 54 | when: 55 | - runner_image is defined 56 | - runner_version is defined 57 | 58 | - name: Set Runner image URL 59 | set_fact: 60 | _runner_image: "{{ _custom_runner_image | default(lookup('env', 'RELATED_IMAGE_ANSIBLE_JOB_RUNNER_IMAGE')) }}" 61 | 62 | - name: Set Runner Pull Policy 63 | set_fact: 64 | _runner_pull_policy: "{{ runner_pull_policy | default('IfNotPresent') }}" 65 | 66 | - name: Create ServiceAccount to run subsequent jobs 67 | kubernetes.core.k8s: 68 | state: present 69 | definition: "{{ lookup('template', 'service_account.yml.j2') }}" 70 | 71 | - name: Start K8s Runner Job 72 | kubernetes.core.k8s: 73 | state: present 74 | definition: "{{ lookup('template', 'job_definition.yml.j2') }}" 75 | 76 | - name: Set schedule name 77 | set_fact: 78 | _schedule_name: "{{ name}}" 79 | 80 | - name: Update AnsibleSchedule status with K8s job info 81 | operator_sdk.util.k8s_status: 82 | api_version: tower.ansible.com/v1alpha1 83 | kind: AnsibleSchedule 84 | name: "{{ ansible_operator_meta.name }}" 85 | namespace: "{{ ansible_operator_meta.namespace }}" 86 | status: 87 | k8sJob: 88 | created: true 89 | message: |- 90 | Monitor the job.batch status for more details with the following commands: 91 | 'kubectl -n {{ ansible_operator_meta.namespace }} get job.batch/{{ ansible_operator_meta.name }}' 92 | 'kubectl -n {{ ansible_operator_meta.namespace }} describe job.batch/{{ ansible_operator_meta.name }}' 93 | 'kubectl -n {{ ansible_operator_meta.namespace }} logs -f job.batch/{{ ansible_operator_meta.name }}' 94 | namespacedName: "{{ ansible_operator_meta.namespace+'/'+ansible_operator_meta.name }}" 95 | env: 96 | inventory: "{{ inventory | default(omit) }}" 97 | secretNamespacedName: "{{ ansible_operator_meta.namespace+'/'+(connection_secret | default(tower_auth_secret, true)) }}" 98 | scheduleName: "{{ _schedule_name }}" 99 | verifySSL: false 100 | -------------------------------------------------------------------------------- /roles/schedule/templates/job_definition.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: "{{ ansible_operator_meta.name }}" 6 | namespace: "{{ ansible_operator_meta.namespace }}" 7 | spec: 8 | ttlSecondsAfterFinished: {{ job_ttl }} 9 | template: 10 | spec: 11 | serviceAccountName: resource-operator-controller-manager-job 12 | containers: 13 | - name: "{{ ansible_operator_meta.name }}" 14 | image: "{{ _runner_image }}" 15 | imagePullPolicy: "{{ _runner_pull_policy }}" 16 | env: 17 | - name: TOWER_OAUTH_TOKEN 18 | valueFrom: 19 | secretKeyRef: 20 | name: "{{ connection_secret }}" 21 | key: token 22 | - name: TOWER_HOST 23 | valueFrom: 24 | secretKeyRef: 25 | name: "{{ connection_secret }}" 26 | key: host 27 | - name: NAME 28 | value: "{{ name }}" 29 | - name: RRULE 30 | value: "{{ rrule }}" 31 | - name: UNIFIED_JOB_TEMPLATE 32 | value: "{{ unified_job_template }}" 33 | - name: TOWER_VERIFY_SSL 34 | value: "False" 35 | {%if state is defined and state != "" %} 36 | - name: STATE 37 | value: "{{ state }}" 38 | {% else %} 39 | - name: STATE 40 | value: "present" 41 | {% endif %} 42 | - name: ANSIBLESCHEDULE_NAME 43 | value: "{{ ansible_operator_meta.name }}" 44 | - name: ANSIBLESCHEDULE_NAMESPACE 45 | value: "{{ ansible_operator_meta.namespace }}" 46 | restartPolicy: Never 47 | backoffLimit: {{ backoff_limit }} 48 | -------------------------------------------------------------------------------- /roles/schedule/templates/service_account.yml.j2: -------------------------------------------------------------------------------- 1 | ../../project/templates/service_account.yml.j2 -------------------------------------------------------------------------------- /roles/schedule/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for AnsibleSchedule 3 | -------------------------------------------------------------------------------- /roles/workflow/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for job 3 | 4 | job_ttl: 3600 5 | backoff_limit: 1 6 | -------------------------------------------------------------------------------- /roles/workflow/files/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/awx-resource-operator/0a31d256d9d1fff07fd74a2cd74e5c6ac9b00590/roles/workflow/files/.placeholder -------------------------------------------------------------------------------- /roles/workflow/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for jobtemplate 3 | -------------------------------------------------------------------------------- /roles/workflow/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Ansible 4 | description: Job role for launching a job in AWX from an openshift or k8s cluster. 5 | company: Red Hat, Inc. 6 | 7 | license: MIT 8 | 9 | min_ansible_version: 2.9 10 | 11 | # If this a Container Enabled role, provide the minimum Ansible Container version. 12 | # min_ansible_container_version: 13 | 14 | # Optionally specify the branch Galaxy will use when accessing the GitHub 15 | # repo for this role. During role install, if no tags are available, 16 | # Galaxy will use this branch. During import Galaxy will access files on 17 | # this branch. If Travis integration is configured, only notifications for this 18 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 19 | # (usually master) will be used. 20 | # github_branch: 21 | 22 | # 23 | # Provide a list of supported platforms, and for each platform a list of versions. 24 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 25 | # To view available platforms and versions (or releases), visit: 26 | # https://galaxy.ansible.com/api/v1/platforms/ 27 | # 28 | platforms: 29 | - name: EL 30 | versions: 31 | - all 32 | - name: Fedora 33 | versions: 34 | - all 35 | - name: Debian 36 | versions: 37 | - all 38 | 39 | galaxy_tags: 40 | - tower 41 | - resource 42 | - awx 43 | - ansible 44 | - automation 45 | - ci 46 | - cd 47 | - deployment 48 | 49 | # List tags for your role here, one per line. A tag is a keyword that describes 50 | # and categorizes the role. Users find roles by searching for tags. Be sure to 51 | # remove the '[]' above, if you add tags to this list. 52 | # 53 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 54 | # Maximum 20 tags per role. 55 | 56 | dependencies: [] 57 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 58 | # if you add dependencies to this list. 59 | 60 | collections: 61 | - operator_sdk.util 62 | - kubernetes.core 63 | -------------------------------------------------------------------------------- /roles/workflow/templates/job_definition.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: "{{ ansible_operator_meta.name }}" 6 | namespace: "{{ ansible_operator_meta.namespace }}" 7 | spec: 8 | ttlSecondsAfterFinished: {{ job_ttl }} 9 | template: 10 | spec: 11 | serviceAccountName: resource-operator-controller-manager-job 12 | containers: 13 | - name: "{{ ansible_operator_meta.name }}" 14 | image: "{{ _runner_image }}" 15 | imagePullPolicy: "{{ _runner_pull_policy }}" 16 | env: 17 | - name: TOWER_OAUTH_TOKEN 18 | valueFrom: 19 | secretKeyRef: 20 | name: "{{ connection_secret }}" 21 | key: token 22 | - name: TOWER_HOST 23 | valueFrom: 24 | secretKeyRef: 25 | name: "{{ connection_secret }}" 26 | key: host 27 | {% if workflow_template_name is defined and workflow_template_name != "" %} 28 | - name: TOWER_WORKFLOW_TEMPLATE_NAME 29 | value: "{{ workflow_template_name }}" 30 | {% endif %} 31 | - name: TOWER_VERIFY_SSL 32 | value: "False" 33 | - name: ANSIBLEWORKFLOW_NAME 34 | value: "{{ ansible_operator_meta.name }}" 35 | - name: ANSIBLEWORKFLOW_NAMESPACE 36 | value: "{{ ansible_operator_meta.namespace }}" 37 | restartPolicy: Never 38 | backoffLimit: {{ backoff_limit }} 39 | -------------------------------------------------------------------------------- /roles/workflow/templates/service_account.yml.j2: -------------------------------------------------------------------------------- 1 | ../../project/templates/service_account.yml.j2 -------------------------------------------------------------------------------- /roles/workflow/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for workflowtemplate 3 | -------------------------------------------------------------------------------- /roles/workflowtemplate/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for workflowtemplate 3 | -------------------------------------------------------------------------------- /roles/workflowtemplate/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for workflowtemplate 3 | -------------------------------------------------------------------------------- /roles/workflowtemplate/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Ansible 4 | description: Workflow Template role for creating a job template in AWX from an openshift or k8s cluster. 5 | company: Red Hat, Inc. 6 | 7 | license: MIT 8 | 9 | min_ansible_version: 2.9 10 | 11 | # If this a Container Enabled role, provide the minimum Ansible Container version. 12 | # min_ansible_container_version: 13 | 14 | # Optionally specify the branch Galaxy will use when accessing the GitHub 15 | # repo for this role. During role install, if no tags are available, 16 | # Galaxy will use this branch. During import Galaxy will access files on 17 | # this branch. If Travis integration is configured, only notifications for this 18 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 19 | # (usually master) will be used. 20 | # github_branch: 21 | 22 | # 23 | # Provide a list of supported platforms, and for each platform a list of versions. 24 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 25 | # To view available platforms and versions (or releases), visit: 26 | # https://galaxy.ansible.com/api/v1/platforms/ 27 | # 28 | platforms: 29 | - name: EL 30 | versions: 31 | - all 32 | - name: Fedora 33 | versions: 34 | - all 35 | - name: Debian 36 | versions: 37 | - all 38 | 39 | galaxy_tags: 40 | - tower 41 | - resource 42 | - awx 43 | - ansible 44 | - automation 45 | - ci 46 | - cd 47 | - deployment 48 | 49 | # List tags for your role here, one per line. A tag is a keyword that describes 50 | # and categorizes the role. Users find roles by searching for tags. Be sure to 51 | # remove the '[]' above, if you add tags to this list. 52 | # 53 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 54 | # Maximum 20 tags per role. 55 | 56 | dependencies: [] 57 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 58 | # if you add dependencies to this list. 59 | 60 | collections: 61 | - operator_sdk.util 62 | - kubernetes.core 63 | -------------------------------------------------------------------------------- /roles/workflowtemplate/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Read Secret Configuration 3 | kubernetes.core.k8s_info: 4 | kind: Secret 5 | namespace: '{{ ansible_operator_meta.namespace }}' 6 | name: "{{ connection_secret }}" 7 | register: tower_config_secret 8 | 9 | - name: Deploy the template 10 | awx.awx.workflow_job_template: 11 | name: "{{ name }}" 12 | description: "{{ description | default(omit) }}" 13 | organization: "{{ organization }}" 14 | extra_vars: "{{ extra_vars | default(omit) }}" 15 | workflow_nodes: "{{ workflow_nodes }}" 16 | allow_simultaneous: "{{ allow_simultaneous | default(omit) }}" 17 | ask_inventory_on_launch: "{{ ask_inventory_on_launch | default(omit) }}" 18 | ask_labels_on_launch: "{{ ask_labels_on_launch | default(omit) }}" 19 | ask_limit_on_launch: "{{ ask_limit_on_launch | default(omit) }}" 20 | ask_scm_branch_on_launch: "{{ ask_scm_branch_on_launch | default(omit) }}" 21 | ask_skip_tags_on_launch: "{{ ask_skip_tags_on_launch | default(omit) }}" 22 | ask_tags_on_launch: "{{ ask_tags_on_launch | default(omit) }}" 23 | ask_variables_on_launch: "{{ ask_variables_on_launch | default(omit) }}" 24 | inventory: "{{ inventory | default(omit) }}" 25 | limit: "{{ limit | default(omit) }}" 26 | job_tags: "{{ job_tags | default(omit) }}" 27 | labels: "{{ labels | default(omit) }}" 28 | skip_tags: "{{ skip_tags | default(omit) }}" 29 | survey_enabled: "{{ survey_enabled | default(omit) }}" 30 | survey_spec: "{{ survey_spec | default(omit) }}" 31 | state: "{{ state | default('present') }}" 32 | environment: 33 | - TOWER_OAUTH_TOKEN: "{{ tower_config_secret['resources'][0]['data']['token'] | b64decode }}" 34 | - TOWER_HOST: "{{ tower_config_secret['resources'][0]['data']['host'] | b64decode }}" 35 | - TOWER_VERIFY_SSL: "False" 36 | register: workflow_template 37 | ignore_errors: true 38 | 39 | - name: Update the k8s status 40 | operator_sdk.util.k8s_status: 41 | api_version: tower.ansible.com/v1alpha1 42 | kind: WorkflowTemplate 43 | name: '{{ ansible_operator_meta.name }}' 44 | namespace: '{{ ansible_operator_meta.namespace }}' 45 | status: 46 | isFinished: true 47 | message: "Workflow Template Created" 48 | when: 49 | - workflow_template.changed 50 | 51 | - name: Update the k8s status 52 | operator_sdk.util.k8s_status: 53 | api_version: tower.ansible.com/v1alpha1 54 | kind: WorkflowTemplate 55 | name: '{{ ansible_operator_meta.name }}' 56 | namespace: '{{ ansible_operator_meta.namespace }}' 57 | status: 58 | isFinished: true 59 | error: true 60 | message: "There was an error in the workflow template" 61 | when: 62 | - workflow_template.failed 63 | -------------------------------------------------------------------------------- /roles/workflowtemplate/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for jobtemplate 3 | -------------------------------------------------------------------------------- /test-e2e/awx-demo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: awx.ansible.com/v1beta1 3 | kind: AWX 4 | metadata: 5 | name: awx-demo 6 | spec: 7 | service_type: clusterip 8 | -------------------------------------------------------------------------------- /test-e2e/awx-deploy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | images: 5 | - name: quay.io/ansible/awx-operator 6 | newTag: TAG 7 | namespace: awx 8 | resources: 9 | - github.com/ansible/awx-operator/config/default?ref=TAG 10 | - awx-demo.yml 11 | -------------------------------------------------------------------------------- /test-e2e/base-operator-install.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - github.com/ansible/awx-operator/config/default?ref=TAG 6 | images: 7 | - name: quay.io/ansible/awx-operator 8 | newTag: TAG 9 | namespace: awx 10 | -------------------------------------------------------------------------------- /test-e2e/tests/bearer.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: admin-user 6 | --- 7 | apiVersion: v1 8 | kind: Secret 9 | metadata: 10 | name: bearer-secret 11 | annotations: 12 | kubernetes.io/service-account.name: admin-user 13 | type: kubernetes.io/service-account-token 14 | -------------------------------------------------------------------------------- /test-e2e/tests/job-deprecated.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tower.ansible.com/v1alpha1 2 | kind: AnsibleJob 3 | metadata: 4 | name: demo-job-deprecated 5 | namespace: awx 6 | spec: 7 | tower_auth_secret: awxaccess 8 | job_template_name: Demo Job Template 9 | runner_pull_policy: IfNotPresent 10 | 11 | -------------------------------------------------------------------------------- /test-e2e/tests/job.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: tower.ansible.com/v1alpha1 3 | kind: AnsibleJob 4 | metadata: 5 | name: demo-job 6 | namespace: awx 7 | spec: 8 | connection_secret: awxaccess 9 | job_template_name: Demo Job Template 10 | runner_pull_policy: IfNotPresent 11 | -------------------------------------------------------------------------------- /test-e2e/token-container/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/ansible/ansible-runner 2 | 3 | ENV ANSIBLE_ROLES_PATH ${HOME}/roles 4 | 5 | COPY requirements.yml ${HOME}/requirements.yml 6 | 7 | RUN ansible-galaxy collection install -r ${HOME}/requirements.yml --force \ 8 | && chmod -R ug+rwx ${HOME}/.ansible && mkdir -p ${HOME}/roles 9 | 10 | RUN pip3 install ansible-tower-cli kubernetes openshift 11 | 12 | ADD playbook.yaml playbook.yaml 13 | 14 | CMD ["/bin/bash"] 15 | -------------------------------------------------------------------------------- /test-e2e/token-container/playbook.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | become: false 4 | gather_facts: false 5 | tasks: 6 | - name: Create a new token using username/password 7 | awx.awx.token: 8 | description: "testing token" 9 | scope: "write" 10 | state: present 11 | controller_username: "{{ lookup('env', 'ADMIN') }}" 12 | controller_password: "{{ lookup('env', 'CREDENTIAL') }}" 13 | controller_host: "http://{{ lookup('env', 'AWX_DEMO_SERVICE_SERVICE_HOST') }}" 14 | register: token 15 | 16 | - name: base64 encode token 17 | shell: echo -n "{{ token.ansible_facts.tower_token.token }}" | base64 18 | register: token 19 | 20 | - name: base64 encoded host 21 | shell: echo -n "http://awx-demo-service.awx.svc.cluster.local:80" | base64 22 | register: host 23 | 24 | - name: Create a Service object from an inline definition 25 | kubernetes.core.k8s: 26 | state: present 27 | definition: 28 | apiVersion: v1 29 | kind: Secret 30 | metadata: 31 | name: awxaccess 32 | namespace: awx 33 | data: 34 | token: "{{ token.stdout }}" 35 | host: "{{ host.stdout }}" 36 | -------------------------------------------------------------------------------- /test-e2e/token-container/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: kubernetes.core 4 | version: "2.4.2" 5 | - name: operator_sdk.util 6 | version: "0.4.0" 7 | - name: awx.awx 8 | version: ">=22.7.0" 9 | -------------------------------------------------------------------------------- /test-e2e/token.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | creationTimestamp: null 6 | name: awx-resource-secret 7 | namespace: awx 8 | --- 9 | apiVersion: rbac.authorization.k8s.io/v1 10 | kind: ClusterRole 11 | metadata: 12 | name: awx-resource-secret 13 | rules: 14 | - apiGroups: 15 | - "" 16 | resources: 17 | - secrets 18 | verbs: 19 | - get 20 | - list 21 | - create 22 | - delete 23 | - patch 24 | - update 25 | --- 26 | apiVersion: rbac.authorization.k8s.io/v1 27 | kind: ClusterRoleBinding 28 | metadata: 29 | annotations: 30 | name: resource-operator-token-binding 31 | namespace: awx 32 | roleRef: 33 | apiGroup: rbac.authorization.k8s.io 34 | kind: ClusterRole 35 | name: awx-resource-secret 36 | subjects: 37 | - kind: ServiceAccount 38 | name: awx-resource-secret 39 | namespace: awx 40 | --- 41 | apiVersion: batch/v1 42 | kind: Job 43 | metadata: 44 | name: create-token 45 | namespace: awx 46 | spec: 47 | backoffLimit: 1 48 | template: 49 | spec: 50 | serviceAccountName: awx-resource-secret 51 | containers: 52 | - name: token 53 | imagePullPolicy: IfNotPresent 54 | image: quay.io/ansible/token-playbook:latest 55 | command: ["/usr/local/bin/ansible-playbook", "/runner/playbook.yaml"] 56 | env: 57 | - name: ADMIN 58 | value: admin 59 | - name: CREDENTIAL 60 | valueFrom: 61 | secretKeyRef: 62 | name: awx-demo-admin-password 63 | key: password 64 | restartPolicy: Never 65 | -------------------------------------------------------------------------------- /watches.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Use the 'create api' subcommand to add watches to this file. 3 | - version: v1alpha1 4 | group: tower.ansible.com 5 | kind: AnsibleJob 6 | role: job 7 | watchDependentResources: True 8 | # finalizer: 9 | # name: finalizer.tower.ansible.com 10 | # vars: 11 | # tower_resource_state: absent 12 | 13 | - version: v1alpha1 14 | group: tower.ansible.com 15 | kind: JobTemplate 16 | role: jobtemplate 17 | - version: v1alpha1 18 | group: tower.ansible.com 19 | kind: AnsibleProject 20 | role: project 21 | - version: v1alpha1 22 | group: tower.ansible.com 23 | kind: AnsibleWorkflow 24 | role: workflow 25 | - version: v1alpha1 26 | group: tower.ansible.com 27 | kind: AnsibleCredential 28 | role: credential 29 | - version: v1alpha1 30 | group: tower.ansible.com 31 | kind: AnsibleSchedule 32 | role: schedule 33 | - version: v1alpha1 34 | group: tower.ansible.com 35 | kind: AnsibleInstanceGroup 36 | role: instancegroup 37 | - version: v1alpha1 38 | group: tower.ansible.com 39 | kind: WorkflowTemplate 40 | role: workflowtemplate 41 | - version: v1alpha1 42 | group: tower.ansible.com 43 | kind: AnsibleInventory 44 | role: inventory 45 | #+kubebuilder:scaffold:watch 46 | --------------------------------------------------------------------------------