Compare commits

..

287 Commits

Author SHA1 Message Date
Shane McDonald
555dc8516a Merge pull request #436 from shanemcd/bump-0.12.0
Bump versions for next release
2021-06-28 18:31:19 -04:00
Shane McDonald
34958282d2 Merge pull request #435 from rooftopcellist/keep-spec-newlines
Preserve newlines in AWX spec
2021-06-28 17:50:54 -04:00
Christian M. Adams
6b01ada12b preserve newlines in AWX spec 2021-06-28 17:39:01 -04:00
Shane McDonald
e28d114d78 Bump versions for next release 2021-06-28 17:26:06 -04:00
Julen Landa Alustiza
cd312c6d70 Merge pull request #431 from Zokormazo/ca-fields-to-advanced
olm-catalog: Add missing custom trusted CA related fields
2021-06-28 11:02:20 +02:00
Shane McDonald
82422b8510 Merge pull request #412 from tchellomello/enhanhce_docs_ee
Enhances ee* documentation
2021-06-25 13:19:07 -04:00
Christian Adams
c7c97da68e Merge pull request #430 from rooftopcellist/backup-ee-pull-secret
Backup ingress, bundle & ee pull secrets
2021-06-25 12:00:12 -04:00
Shane McDonald
657b5b67db Merge pull request #432 from shanemcd/fix-extra-settings
Allow for types other than strings to be passed to extra_settings
2021-06-25 09:56:50 -04:00
Shane McDonald
b664b920dc Allow for types other than strings to be passed to extra_settings
This feature was not working as intended
2021-06-25 09:47:08 -04:00
Julen Landa Alustiza
7ea60efe3e olm-catalog: Add missing custom trusted CA related fields
Signed-off-by: Julen Landa Alustiza <jlanda@redhat.com>
2021-06-25 11:36:36 +02:00
Christian M. Adams
f5c8b33b40 Backup ingress, bundle & ee pull secrets 2021-06-24 13:50:49 -04:00
Julen Landa Alustiza
a28a744f00 Merge pull request #429 from Zokormazo/explicitly-nullify-ownerreference
Explicitly nullify ownerReference on operator created backup pvc
2021-06-24 15:39:47 +02:00
Julen Landa Alustiza
68aaf1db79 Explicitly nullify ownerReference on operator created backup pvc
Signed-off-by: Julen Landa Alustiza <jlanda@redhat.com>
2021-06-24 14:58:18 +02:00
Shane McDonald
b8d6dcfbf2 Merge pull request #427 from shanemcd/fix-secrets-with-newlines
Preserve newlines when restored secrets contain newlines
2021-06-23 20:09:08 -04:00
Shane McDonald
0ea9a04028 Preserve newlines when restored secrets contain newlines 2021-06-23 19:57:44 -04:00
Shane McDonald
e448d0ec8e Merge pull request #425 from rooftopcellist/downgrade-kubernetes-module
Downgrade kubernetes module to 1.1.1 because of template bug
2021-06-23 17:20:40 -04:00
Shane McDonald
cb14c9a1fc Pin to different version of kubernetes.core for CI usage
Bugs everywhere!
2021-06-23 17:07:27 -04:00
Shane McDonald
ca52b6c1c7 Merge pull request #423 from dolgovas/devel
Update README.md
2021-06-23 16:09:49 -04:00
Christian M. Adams
d3cfc55944 Downgrade kubernetes module to 1.1.1 because of template bug 2021-06-23 14:38:48 -04:00
dolgovas
00fd08e731 Update README.md
Add additional information about `image_pull_secret`
2021-06-23 20:06:41 +03:00
Yanis Guenane
e0c865a9f7 Merge pull request #419 from Spredzy/update_vendored
vendor: update dir with kubernetes.core
2021-06-23 00:49:50 +02:00
Yanis Guenane
53ffc8fdae vendor: update dir with kubernetes.core 2021-06-23 00:37:37 +02:00
Shane McDonald
6c1f251558 Merge pull request #417 from shanemcd/fix-uuid
Fix SYSTEM_UUID
2021-06-22 15:02:06 -04:00
Shane McDonald
7310b43a5c Use kubernetes.core 2021-06-22 14:52:54 -04:00
Shane McDonald
9a54ae2937 Delete test-local, run test-minikube in CI
bsycorp/kind is broken. See https://github.com/bsycorp/kind/issues/44
2021-06-22 14:35:39 -04:00
Shane McDonald
64c55c8824 Fix SYSTEM_UUID 2021-06-21 09:49:36 -04:00
Marcelo Moreira de Mello
9cc8aeeb4b Enhance ee documentation 2021-06-18 13:53:22 -04:00
Marcelo Moreira de Mello
d6d39889c4 Merge pull request #401 from tchellomello/custom-ca
Added ability to trust a custom bundle CA
2021-06-18 12:07:51 -04:00
Yanis Guenane
68a6a55cfc Merge pull request #411 from Spredzy/remove_extra_space
awx-cro.yml: Remove extra space
2021-06-18 10:23:58 +02:00
Yanis Guenane
ad036c2e65 awx-cro.yml: Remove extra space
Fixes: https://github.com/ansible/awx-operator/issues/410
2021-06-18 09:54:49 +02:00
Marcelo Moreira de Mello
f2e43db37c Added ability to trust a custom bundle CA 2021-06-18 01:48:50 -04:00
Shane McDonald
1fb429b1ed Merge pull request #409 from shanemcd/bump-0.11.0
AWX Operator 0.11.0
2021-06-17 17:10:04 -04:00
Shane McDonald
4d027c7d22 Update README 2021-06-17 16:28:45 -04:00
Shane McDonald
785b9ef70f Bump versions 2021-06-17 16:28:30 -04:00
Yanis Guenane
d834701612 Merge pull request #407 from Spredzy/ee_resource_requirements
EE: Allow one to specify resource requirements
2021-06-17 15:00:06 +02:00
Yanis Guenane
0f4cc52e71 EE: Allow one to specify resource requirements 2021-06-17 12:44:12 +02:00
Yanis Guenane
135ee98146 Merge pull request #406 from Spredzy/tower_ee_extra_env
EE: Allow one to specify extra environment variable
2021-06-17 11:19:20 +02:00
Yanis Guenane
3899365da7 EE: Allow one to specify extra environment variable 2021-06-17 10:43:52 +02:00
Shane McDonald
12f9fff6d5 Merge pull request #405 from shanemcd/community.docker
Update build-and-push.yml to use community.docker
2021-06-16 12:51:04 -04:00
Shane McDonald
f565befdb0 Update build-and-push.yml to use community.docker 2021-06-16 12:41:57 -04:00
Yanis Guenane
7c02eabbdf Merge pull request #404 from Spredzy/restore_colon
backup: Ensure colon are preserved in awx spec
2021-06-16 15:26:02 +02:00
Yanis Guenane
3398cc2f01 backup: Ensure colon are preserved in awx spec
Due to the way the command is run, the field with a colon in it will
generate a broken yaml serialization. This commit aims to keep it
accurate.
2021-06-16 14:17:11 +02:00
Yanis Guenane
5bbe7b6e3e Merge pull request #397 from rooftopcellist/dynamic_secrets
Dynamic secret backup & restore
2021-06-16 10:41:04 +02:00
Yanis Guenane
da1e7674f6 Merge pull request #400 from rooftopcellist/rm_pvc_ownerref
Do not clean up pvc when awxbackup cr is deleted
2021-06-16 10:40:34 +02:00
Marcelo Moreira de Mello
d46fdbc3c9 Merge pull request #396 from tchellomello/extra_config
Documenting extra_settings usage
2021-06-15 15:09:03 -04:00
Christian M. Adams
bfec61ad8d Dynamically collect secrets for backup & restore roles
- This prevents us from overwriting vars unintentionally at restore time
  - This will make it easier to add secrets to be backed up in the future
  - Add generated secret names to awx spec backup
  - Fail early if secret status doesn't exist
  - Skip if secret is not in spec for non-generated secrets
  - Secret values must be b64 decoded before secret is created
  - Cleanup temp files
2021-06-15 14:17:02 -04:00
Christian M. Adams
42141cd159 Do not clean up pvc when awxbackup cr is deleted
- This is accomplished by explicitly setting ownerRefs to null
2021-06-15 12:23:04 -04:00
Yanis Guenane
1bb6ada3a2 Merge pull request #398 from Spredzy/control_plane_ee
olm-catalog: Add missing control_plane_ee_image
2021-06-15 10:31:08 +02:00
Yanis Guenane
baeb822c39 olm-catalog: Add missing control_plane_ee_image 2021-06-15 09:57:26 +02:00
Marcelo Moreira de Mello
e22720dc82 Fixed typo 2021-06-14 16:29:10 -04:00
Marcelo Moreira de Mello
dd70d0e4ec Fixed typo 2021-06-14 16:27:42 -04:00
Marcelo Moreira de Mello
804e6c3de7 Documenting extra_settings usage 2021-06-14 13:42:52 -04:00
Yanis Guenane
5d597d1e19 Merge pull request #393 from Spredzy/remove_uneeded_default
Do not specify unneeded default
2021-06-14 16:43:25 +02:00
Yanis Guenane
ebb3d7b6a5 Merge pull request #392 from Spredzy/favico
favicon: update path to favicon.ico
2021-06-14 16:43:14 +02:00
Yanis Guenane
754ad98d3c Do not specify unneeded default 2021-06-14 09:33:39 +02:00
Yanis Guenane
d47d25b584 favicon: update path to favicon.ico
Relates: https://github.com/ansible/awx/pull/10388
2021-06-14 09:31:04 +02:00
Yanis Guenane
ef1c57c932 Merge pull request #388 from Spredzy/fix_label_selector2
olm-catalog: Add missing postgres_olm_selector
2021-06-11 13:45:14 +02:00
Yanis Guenane
da912f1189 Merge pull request #387 from Spredzy/remove_unecessary_default
olm-catalog: Remove unecessary defaults at the crd level
2021-06-11 13:34:43 +02:00
Yanis Guenane
bb0039c70b Merge pull request #386 from Spredzy/make_ee_pull_credentials_secret_advanced
Make ee pull credentials secret advanced
2021-06-11 13:34:33 +02:00
Yanis Guenane
5833b06c5b olm-catalog: Add missing postgres_olm_selector 2021-06-11 13:31:30 +02:00
Yanis Guenane
955a15786e olm-catalog: Remove unecessary defaults at the crd level 2021-06-11 13:07:25 +02:00
Yanis Guenane
e37afab2cd ee_pull_credentials_secret: Ensure its advanced and a secret type 2021-06-11 12:03:40 +02:00
Christian Adams
c4162752bc Merge pull request #384 from rooftopcellist/add-generate-files-script
Add script to generate files after crd.yml.j2 changes
2021-06-09 14:29:01 -04:00
Christian M. Adams
a30f3f658e Add script to generate files after crd.yml.j2 changes 2021-06-09 11:49:39 -04:00
Christian Adams
f1b1293f5f Merge pull request #372 from rooftopcellist/fail-loud
Fail task if pg_dump fails in backup role
2021-06-09 10:58:15 -04:00
Yanis Guenane
7891e88131 Merge pull request #377 from aperigault/aperigault-patch-1
Fix service annotations
2021-06-09 09:53:01 +02:00
Shane McDonald
5d7cd9ab1c Merge pull request #379 from kdelee/register_ees
Register ees
2021-06-08 17:21:19 -04:00
Shane McDonald
2777c5e00a Dont register instance in operator
This happens in the app
2021-06-08 17:05:56 -04:00
Shane McDonald
6b57caeb92 Fix quoting issue
This was causing Ansible to always report changed=2
2021-06-08 16:56:19 -04:00
Shane McDonald
156788c56e Add missing quotes 2021-06-08 16:56:19 -04:00
Elijah DeLee
c4d197f5ce add type to control_plane_ee_image 2021-06-08 16:56:19 -04:00
Elijah DeLee
f53354d20d update the README for the changes to execution environments vars 2021-06-08 16:56:19 -04:00
Elijah DeLee
075969f25d Use new setting for control plan ee
Now this is consumed by the awx-manage register_default_execution_environments to
make the EE that is used for project updates
2021-06-08 16:56:19 -04:00
Julen Landa Alustiza
1fc22749a5 Use awx-manage register_default_execution_environments
Signed-off-by: Julen Landa Alustiza <jlanda@redhat.com>
2021-06-08 16:56:17 -04:00
Shane McDonald
46f5b3dcb0 Merge pull request #378 from Spredzy/default_queue_name
Use new awx default queue name
2021-06-08 15:19:01 -04:00
Shane McDonald
2622e0e111 Merge pull request #361 from Zokormazo/control-plane-ee
Use own attribute for control_plane_ee
2021-06-07 15:43:30 -04:00
Yanis Guenane
e96298b5a8 Use new awx default queue name
Relates: https://github.com/ansible/awx/pull/10324
2021-06-07 17:36:23 +02:00
aperigault
626b8acaa9 Fix service 2021-06-07 11:41:54 +02:00
Christian M. Adams
69b3f43414 Make postgres image and version separately configurable for backup/restore
- Update templated and generated manifest files
2021-06-04 11:00:50 -04:00
Christian M. Adams
e857902dcc Fail task if pg_dump command fails 2021-06-04 10:31:57 -04:00
Christian Adams
af5983cb68 Merge pull request #362 from rooftopcellist/update-catalog-statuses
olm-catalog: Add statuses to schemas for awxbackup and awxrestore objects
2021-06-03 14:37:56 -04:00
Christian M. Adams
ead7532c3c Add statuses to schemas for awxbackup and awxrestore objects
- Fix small docstring typos
2021-06-03 09:22:04 -04:00
Christian Adams
b37bf06800 Merge pull request #366 from rooftopcellist/release-docs
Update Release Process docs
2021-06-02 17:45:51 -04:00
Christian M. Adams
d0523b9eb3 Update Release Process docs 2021-06-02 17:31:19 -04:00
Shane McDonald
543bf3e156 Merge pull request #365 from tchellomello/changelog-0.10.0
Changelog for 0.10.0
2021-06-02 17:20:46 -04:00
Marcelo Moreira de Mello
d8f864c88f Changelog for 0.10.0 2021-06-02 17:07:10 -04:00
Shane McDonald
53e0f1455e Merge pull request #364 from shanemcd/update-olm
Update OLM metadata
2021-06-02 17:04:41 -04:00
Shane McDonald
6347ceb976 Update OLM metadata 2021-06-02 16:42:45 -04:00
Yanis Guenane
a923ee112c Merge pull request #358 from Spredzy/improve_nginx_conf
nginx: Improve security configuration
2021-06-02 20:28:47 +02:00
Julen Landa Alustiza
83e46ee84b Use own attribute for control_plane_ee
Signed-off-by: Julen Landa Alustiza <jlanda@redhat.com>
2021-06-02 14:55:53 +02:00
Yanis Guenane
bc66f8e4bb Merge pull request #354 from rooftopcellist/fix-postgres-pod-label
Update name of default postgres label selector for backup role
2021-06-02 11:36:15 +02:00
Yanis Guenane
f1fe7d8fc5 nginx: Improve security configuration 2021-06-02 11:07:46 +02:00
Yanis Guenane
21df85cbf4 Merge pull request #353 from Spredzy/missing_statuss
olm-catalog: Add missing statuses
2021-06-02 09:59:17 +02:00
Shane McDonald
25bdc23d45 Merge pull request #355 from shanemcd/bump-0.10.0
Bump versions for 0.10.0
2021-06-01 19:31:13 -04:00
Yanis Guenane
bc2f1bfde9 olm-catalog: Add missing statuses 2021-06-01 23:27:56 +02:00
Christian M. Adams
da75e4b400 update name of default postgres label selector for backup role 2021-06-01 17:12:23 -04:00
Shane McDonald
b74d6a582e Bump versions for 0.10.0 2021-06-01 17:07:52 -04:00
Shane McDonald
679af90d71 Merge pull request #352 from tchellomello/ingress_readme_fixup
Updated README.md to point to released version
2021-06-01 16:46:29 -04:00
Marcelo Moreira de Mello
5e58da7c7e Updated README.md to point to released version 2021-06-01 16:35:59 -04:00
Shane McDonald
9555a04870 Merge pull request #330 from tchellomello/ingress_minikube
Introducing service type definition and reworking Ingress rules
2021-06-01 16:10:32 -04:00
Marcelo Moreira de Mello
e37c091d17 Make tower_ingress_type to respect ClusterIP definition 2021-06-01 15:42:39 -04:00
Shane McDonald
d6c9ebf35c Merge pull request #324 from Zokormazo/extra_settings_quote
Add quotes to string type extra_settings
2021-05-26 12:06:02 -04:00
Julen Landa Alustiza
899a8e7bf5 Add quotes to string type extra_settings
Signed-off-by: Julen Landa Alustiza <jlanda@redhat.com>
2021-05-26 09:19:00 +02:00
Shane McDonald
a8399c5ec0 Merge pull request #333 from tchellomello/sa_annotations
Added ability to specify annotations to ServiceAccount
2021-05-25 20:50:25 -04:00
Shane McDonald
cb3451e8dc Merge pull request #334 from rooftopcellist/extend-service-account-perm
Add ability to get/create/delete secrets for the awx service account
2021-05-25 16:02:46 -04:00
Christian M. Adams
61b3cb4c7f Add ability to get/create/delete secrets for the awx service account 2021-05-25 15:38:05 -04:00
Marcelo Moreira de Mello
446ac0b190 Added ability to specify annotations to ServiceAccount 2021-05-25 12:16:16 -04:00
Yanis Guenane
8c6ccfbca2 Merge pull request #331 from Spredzy/remove_variable_prefix
Do not prepend variables name with tower_
2021-05-25 15:58:46 +02:00
Yanis Guenane
223fe988aa Do not shadow other variables 2021-05-25 15:38:35 +02:00
Yanis Guenane
75458d0678 Do not prepend variables name with tower_ 2021-05-25 09:52:13 +02:00
Christian Adams
d0a74edd34 Merge pull request #323 from rooftopcellist/remove_finalizer
Fully remove finalizer
2021-05-19 11:39:27 -04:00
Shane McDonald
f6b0fb62b8 Merge pull request #200 from tchellomello/okd_console
Added OKD console deployment
2021-05-18 14:15:08 -04:00
Christian M. Adams
fd9205070e Fully remove finalizer 2021-05-18 11:34:29 -04:00
Christian Adams
e18ce59ea9 Merge pull request #297 from rooftopcellist/pg-labels
Make postgres sts labels consistent with k8s recommendations & pulp-operator
2021-05-18 10:37:46 -04:00
Christian Adams
5fd86e07ce Merge pull request #319 from rooftopcellist/custom_format_backup
Use custom pg_dump format for faster restores
2021-05-18 10:33:23 -04:00
Christian M. Adams
406bbf90fa Make postgres sts labels consistent with k8s recommendations & pulp-operator
- k8s recommended labels: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/
2021-05-18 10:02:15 -04:00
Marcelo Moreira de Mello
b887315c8d Merge pull request #317 from tchellomello/operator_labels_complementary
Extended labels to AWX Backup/Restore
2021-05-17 21:58:14 -04:00
Marcelo Moreira de Mello
08776ca2b6 Extended labels to AWX Backup/Restore 2021-05-17 21:40:37 -04:00
Christian Adams
8a34188854 Merge pull request #273 from tchellomello/contributing
Adding contributing guidelines
2021-05-17 18:12:37 -04:00
Marcelo Moreira de Mello
68e0de4d9e Adding contributing guidelines 2021-05-17 17:54:35 -04:00
Christian M. Adams
f16d9ac55f Use custom pg_dump format for faster restores 2021-05-17 16:54:49 -04:00
Christian Adams
0239062fa4 Merge pull request #318 from rooftopcellist/storage_class_empty
Default to storage class being undefined
2021-05-17 16:52:09 -04:00
Christian M. Adams
82ed9d6d56 Default to storage class being undefined
* This is so that users can intentially set it to an empty string if they want to use the default storage class
  * conversely, now users can manually create a pvc that does not utilize the default storage class
2021-05-17 16:41:53 -04:00
Christian Adams
1ce36572c4 Merge pull request #302 from rooftopcellist/upgrade_note
Add note about how to upgrade AWX and the operator
2021-05-17 16:25:34 -04:00
Christian Adams
708f5d49e8 Merge pull request #315 from rooftopcellist/allow_manual_pvc
Allow user to specify empty string for storage class on PVC
2021-05-17 12:27:26 -04:00
Christian M. Adams
818b837fb2 Allow user to specify empty string for storage class on PVC 2021-05-17 12:15:03 -04:00
Marcelo Moreira de Mello
7b7965d506 Merge pull request #308 from tchellomello/operator_version
Adds operator-version to k8s resources
2021-05-13 10:00:26 -04:00
Marcelo Moreira de Mello
5266cc23a9 Adds operator-version to k8s resources 2021-05-12 22:17:36 -04:00
Marcelo Moreira de Mello
fd9532ee3f Merge pull request #303 from tchellomello/tower_loadbalancer_annotations
Set initial value for tower_loadbalancer_annotations
2021-05-11 11:15:29 -04:00
Marcelo Moreira de Mello
b2b1e07e45 Set initial value for tower_loadbalancer_annotations 2021-05-10 23:31:01 -04:00
Christian Adams
8519ff93b2 Merge pull request #272 from kimbernator/devel
Add support for custom service labels
2021-05-10 15:18:31 -04:00
Christian Adams
123d6e4c29 Merge pull request #299 from rooftopcellist/stuck-finalizer
Unset ownerRefs in the installer instead of the finalizer
2021-05-10 13:21:46 -04:00
Christian M. Adams
c16e53da46 Add note about how to upgrade AWX and the operator 2021-05-10 11:54:18 -04:00
Christian M. Adams
c12a1f02ab Unset ownerRefs in the installer instead of the finalizer 2021-05-07 17:55:01 -04:00
Christian Adams
13e114afc1 Merge pull request #296 from rooftopcellist/pg_custom_archive
Use custom archive format when migrating data
2021-05-07 15:20:00 -04:00
Christian M. Adams
9145b32d11 Use custom archive format when migrating data
- this approach is compatible with the RH postgresql container
2021-05-07 15:04:20 -04:00
Christian Adams
aed4d07cf1 Merge pull request #295 from rooftopcellist/scale_down_restore
Scale down the new deployment before restoring
2021-05-07 15:03:48 -04:00
Christian M. Adams
ca8127448e Scale down the new deployment before restoring 2021-05-07 11:18:40 -04:00
Christian Adams
e082180cf9 Merge pull request #293 from Zokormazo/restore-kind
Restore: set proper kind var after deploying AWX CR
2021-05-07 09:23:02 -04:00
Christian Adams
df2522fa8d Merge pull request #283 from rooftopcellist/fix-lint-errors
Fix file permissions for tmp spec vars file
2021-05-07 09:10:25 -04:00
Julen Landa Alustiza
fc4687ff77 Restore: set proper kind var after deploying AWX CR
Signed-off-by: Julen Landa Alustiza <jlanda@redhat.com>
2021-05-07 13:31:29 +02:00
Shane McDonald
9cca0d0520 Merge pull request #287 from AlanCoding/include_playbook
Make awx-operator compatible with Ansible 2.12
2021-05-06 11:05:19 -04:00
Alan Rominger
521648925c Make awx-operator compatible with Ansible 2.12 2021-05-06 10:49:01 -04:00
Yanis Guenane
bc1814ce95 Merge pull request #282 from Spredzy/olm_backup_and_restore
olm-catalog: Update with latest content from AWXBackup and AWXRestore
2021-05-05 17:26:20 +02:00
Christian M. Adams
c551d05182 Fix file permissions for tmp spec vars file 2021-05-05 09:35:03 -04:00
Yanis Guenane
ce0a251c1c olm-catalog: Update with latest content from AWXBackup and AWXRestore 2021-05-05 10:37:23 +02:00
Christian Adams
51dd524579 Merge pull request #279 from rooftopcellist/persist-secrets
Persist secret names from old deployment & add them to the spec
2021-05-04 14:59:28 -04:00
Christian M. Adams
9532cc754e Use copy module, not shell 2021-05-04 14:28:59 -04:00
Christian M. Adams
15bc12b7f6 Remove ownerReferences based on secret name from backup 2021-05-04 11:46:09 -04:00
Christian M. Adams
a46938e1be Retrieve pg secret values consistently, do not hardcode secret names 2021-05-04 10:06:39 -04:00
Christian M. Adams
8af0681373 Persist secret names from old deployment & add them to the spec
- renamed some more variables to be consistent with the pulp-operator
  - removed unneeded vars from backup & restore crds
  - added a way to parse spec at restore time by including vars to
    get around the issue of triply nested quotes when using to_json
2021-05-04 10:06:29 -04:00
Christian Adams
bd6a5c3156 Merge pull request #133 from rooftopcellist/backup-role
Backup role for awx-operator
2021-05-03 15:36:04 -04:00
Jeremy Kimber
51435e3c2b fix example to use correct label 2021-05-03 13:14:49 -05:00
Jeremy Kimber
b204c91baa set tower_service_labels field to hidden 2021-05-03 13:12:37 -05:00
Marcelo Moreira de Mello
e7fd1e265f Merge pull request #271 from tchellomello/changelog
Added initial CHANGELOG.md
2021-05-03 13:18:42 -04:00
Marcelo Moreira de Mello
42b39eda40 Merge pull request #264 from ansible/tchellomello-bugreport-template
Updated bug report template
2021-05-03 13:18:25 -04:00
Marcelo Moreira de Mello
b50cf82639 Added initial CHANGELOG.md 2021-05-03 11:44:47 -04:00
Jeremy Kimber
fd42802512 Add support for custom service labels 2021-05-03 10:20:56 -05:00
Shane McDonald
8772d0eec5 Merge pull request #266 from shanemcd/bump-19.1.0
Bump 19.1.0
2021-05-01 10:27:39 -04:00
Shane McDonald
ca20dcf053 Use 'admin' username in tests 2021-05-01 09:39:50 -04:00
Shane McDonald
67a650ce38 Remove isolated logger from configmap
Isolated nodes have been removed in upstream AWX
2021-05-01 09:32:09 -04:00
Shane McDonald
acb443432e Bump version 2021-05-01 08:18:30 -04:00
Shane McDonald
3f2bb3e5db Regenerate files 2021-05-01 08:18:13 -04:00
Shane McDonald
c318611561 Bump AWX version 2021-05-01 07:45:18 -04:00
Shane McDonald
77e7039a2e Update playbook to allow for deploying custom image version/tag 2021-05-01 07:44:53 -04:00
Marcelo Moreira de Mello
b7e043eca8 Update bug_report.md 2021-04-30 13:53:59 -04:00
Marcelo Moreira de Mello
78d03e03bb Updated bug report template 2021-04-30 13:52:09 -04:00
Christian M. Adams
5e2d11835e Fix rebase issue & remove dynamic kind/version var setting 2021-04-30 13:51:48 -04:00
Marcelo Moreira de Mello
8656ee1a1d Merge pull request #263 from tchellomello/projects
Mounts /var/lib/awx/projects on awx-web container
2021-04-30 13:46:17 -04:00
Marcelo Moreira de Mello
f21ec4de61 Mounts /var/lib/awx/projects on awx-web container 2021-04-30 13:31:31 -04:00
Christian M. Adams
cdbaf9460e Remove unnecessary intermediate awx_spec var 2021-04-30 10:49:32 -04:00
Christian M. Adams
5439681a39 Fix rebase issue due to order or pg config tasks 2021-04-30 10:49:32 -04:00
Christian M. Adams
9cfb7921bc update templated files with new var names 2021-04-30 10:49:32 -04:00
Christian M. Adams
36852cd5f5 remove unused variables in restore role 2021-04-30 10:49:32 -04:00
Christian M. Adams
b5c5a1722d revert unneccesary admin password update 2021-04-30 10:49:31 -04:00
Christian M. Adams
5ae36367a4 Rename product specific variable names 2021-04-30 10:49:31 -04:00
Christian M. Adams
d743936ee4 Update admin user password with value in provided/generated secret 2021-04-30 10:49:31 -04:00
Christian M. Adams
c817a2234d Simplify vars needed for restore CR & do not garbage collect secrets 2021-04-30 10:49:31 -04:00
Christian M. Adams
57f9530198 Simplify pvc naming scheme, one pvc per deployment 2021-04-30 10:49:31 -04:00
Christian M. Adams
3e444da7bc Set ownerRef to null for restore created AWX object to avoid garbage collection
- Set defaults for pg type to satisfy conditional
2021-04-30 10:49:30 -04:00
Christian M. Adams
867bc258b9 Allow custom postgres pod label to support user managed pg pods
- Only set resolvable pg host path for pg container when managed
2021-04-30 10:49:30 -04:00
Christian M. Adams
ff9248e971 create pvc in namespace of old awx by default, update docs, fix bug with secret statuses 2021-04-30 10:49:30 -04:00
Christian M. Adams
38a6a02f85 Add secret names as statuses on the AWX object
- set migrate data status even if custom name for old postgres config is not used
 - Allow users to change pg name, pw & db name for a managed postgres
 - set default value for postgres-configuration type as unmanaged if secret is created
 - Make pg port configurable for managed deployments
2021-04-30 10:49:27 -04:00
Christian M. Adams
90f4d71606 Make pg port configurable for managed deployments 2021-04-30 10:32:07 -04:00
Christian M. Adams
8f760e2842 Allow users to change pg name, pw & db name for a managed postgres
- set default value for postgres-configuration type as unmanaged if secret is created
2021-04-30 10:32:05 -04:00
Christian M. Adams
5b32c41277 Fix retry for checking postgres pod & fix secrets template
- fixed a lot of typos & updated the README.md files
2021-04-30 10:24:37 -04:00
Christian M. Adams
fb612c24df Only write values for spec section of awx object in backup 2021-04-30 10:24:37 -04:00
Christian M. Adams
8ed0b1fe61 Template only what is needed from secrets and awx cro 2021-04-30 10:24:37 -04:00
Christian M. Adams
82efe05343 store secrets & definitions in a tempfile dir, fix postgres label 2021-04-30 10:24:36 -04:00
Christian M. Adams
2cbf60fa17 Remove unneeded fqcn for modules & fix CI 2021-04-30 10:24:36 -04:00
Christian M. Adams
ce8c58f542 added secrets logic, fixed permissions issues 2021-04-30 10:24:36 -04:00
Christian M. Adams
b9d0852c83 Fix small namespace issue 2021-04-30 10:24:36 -04:00
Christian M. Adams
5669747bbf Scope pvc and management pod to default namespace
- make this configurable via tower_backup_pvc_namespace var
  - remove redundant k8s task info
2021-04-30 10:24:36 -04:00
Christian M. Adams
0580398c90 Finish db restore logic
- rename _backup_dir to backup_dir
  - add towerBackupClaim status to make the pvc name easier to find for users
2021-04-30 10:24:36 -04:00
Christian M. Adams
8422f6fbd9 rename db task vars with awx instead of tower for consistency 2021-04-30 10:24:35 -04:00
Christian M. Adams
8467209d35 init restore 2021-04-30 10:24:35 -04:00
Christian M. Adams
80c8d87f71 Create an event when pvc is not set to alert the user 2021-04-30 10:24:35 -04:00
Christian M. Adams
6bc149bae2 template awxbackup crd into awx-operator.yml for easy deployment 2021-04-30 10:24:35 -04:00
Christian M. Adams
250ff960bd Add awxbackup CRD creation to molecule to get tests passing 2021-04-30 10:24:35 -04:00
Christian M. Adams
e1dca00f46 Fix backup reconciliation loop, add error status 2021-04-30 10:24:35 -04:00
Christian M. Adams
f17dcdc3e9 Swap vars and defaults, rename to awxbackups 2021-04-30 10:24:35 -04:00
Christian M. Adams
4839bdcaad Rename Backup CR to AWXBackup to be more unique
- we could alternatively direct users to use the full GVK.  Issue is potential conflict with AH operator CRs
2021-04-30 10:24:34 -04:00
Christian M. Adams
91dda5cb16 backup secrets to YAML files 2021-04-30 10:24:34 -04:00
Christian M. Adams
0a82fec359 Refactor backup role & store secrets as well 2021-04-30 10:24:34 -04:00
Christian M. Adams
13397f41ad use meta.data to keep pods and pvcs unique in the same namespace 2021-04-30 10:24:34 -04:00
Christian M. Adams
9e44e21a66 Rename pvc name var to be consistent with other backup variables 2021-04-30 10:24:34 -04:00
Christian M. Adams
54efda1a25 Use default cluster storage class if none is provided 2021-04-30 10:24:34 -04:00
Christian M. Adams
bcd1410438 init backup CR files 2021-04-30 10:24:33 -04:00
Christian M. Adams
fdcc745f11 Add watcher for backup CR 2021-04-30 10:24:33 -04:00
Christian M. Adams
4a5ca184c0 Use storage class to dynamically create volume for backups 2021-04-30 10:24:33 -04:00
Christian M. Adams
e037feafbf Create management pod and pvc for backup 2021-04-30 10:24:33 -04:00
Christian M. Adams
0220c75884 wip deployment podspec or sts 2021-04-30 10:24:33 -04:00
Shane McDonald
5f668d76f0 Merge pull request #262 from Spredzy/extra_settings
Extra Settings: Allow one to pass extra API configuration settings.
2021-04-30 10:01:47 -04:00
Yanis Guenane
1d14ebccad Extra Settings: Allow one to pass extra API configuration settings.
For more advanced usage, a user can do the
extra_volumes/extra_volume_mounts dance. But for simple need adding this
parameter make it easy to just specify an extra parameter.
2021-04-30 11:06:40 +02:00
Yanis Guenane
06ab6d2dad Merge pull request #257 from Spredzy/rename_postgres_parameters
PostgreSQL: Properly handle variable name difference when using Red Hat containers
2021-04-30 09:35:35 +02:00
Yanis Guenane
6b0ecacc63 Merge pull request #258 from Spredzy/fix_tower_ee_images
Properly hide tower_ee_images
2021-04-30 09:35:20 +02:00
Yanis Guenane
2965a9091e PostgreSQL: Properly handle variable name difference when using Red Hat containers 2021-04-29 18:16:20 +02:00
Yanis Guenane
160209698c Properly hide tower_ee_images 2021-04-29 17:39:57 +02:00
Marcelo Moreira de Mello
7361defa17 Merge pull request #198 from tchellomello/ssl_pg
Added support to override PosgreSQL sslmode
2021-04-28 15:51:01 -04:00
Shane McDonald
68774a3ccc Merge pull request #250 from rooftopcellist/ee-vars
Add templated EE volume mount var to operator config
2021-04-28 11:33:13 -04:00
Shane McDonald
70b7991cdf Merge pull request #253 from Spredzy/base_component_on_deployment_type
Deployment type: Make more fields dynamic based on that field
2021-04-28 11:32:37 -04:00
Yanis Guenane
4706aa9a1e Deployment type: Make more fields dynamic based on that field 2021-04-28 12:12:06 +02:00
Marcelo Moreira de Mello
fb183f4eab Merge pull request #251 from tchellomello/redeploy-it
Handle statefulset updates
2021-04-27 23:29:19 -04:00
Marcelo Moreira de Mello
3d5a9eae31 Handle statefulset updates 2021-04-27 17:16:57 -04:00
Christian M. Adams
e55d83ffa0 Add templated EE volume mount var to operator config 2021-04-27 15:54:37 -04:00
Yanis Guenane
fd9ce8f0cb Merge pull request #249 from Spredzy/fix_wrong_indentation
olm manifests: fix wrong identation making file incorrect
2021-04-27 14:19:30 +02:00
Yanis Guenane
126228774c olm manifests: fix wrong identation making file incorrect
Currently the file is inacurrate and yaml parsing would fail on line 166
with

>  syntax error: expected <block end>, but found '<block mapping start>'
(syntax)
2021-04-27 13:24:52 +02:00
Marcelo Moreira de Mello
3c26af0cd7 Merge pull request #217 from tchellomello/crashing
Updated logic to validate changes on configmaps, deployments and statefulsets
2021-04-26 17:04:20 -04:00
Shane McDonald
b781300977 Merge pull request #248 from shanemcd/devel
Fix service type logic
2021-04-26 14:10:43 -04:00
Shane McDonald
c0e164d763 Fix service type logic 2021-04-26 13:58:44 -04:00
Marcelo Moreira de Mello
2fd737fbc2 Merge pull request #204 from TheStally/devel
Set Service to use type ClusterIP instead of NodePort when tower_ingress_type is Ingress
2021-04-25 21:59:25 -04:00
Shane McDonald
ee9800c258 Merge pull request #244 from ilijamt/ee-conf-wrong
added missing comma, to AWX execution_environments.py file
2021-04-24 11:58:41 -04:00
stal
5b38c85f8a Extra changes for new tower_ingress_type NodePort 2021-04-24 15:16:49 +01:00
Ilija Matoski
72c122dff9 added missing comma, to AWX execution_environets.py file 2021-04-24 14:34:19 +02:00
Shane McDonald
3e8834e057 Merge pull request #243 from ansible/shanemcd-patch-3
Update default ee version
2021-04-23 14:24:28 -04:00
Shane McDonald
5779afd858 Update default ee version 2021-04-23 13:58:01 -04:00
Shane McDonald
da43c5ba7d Merge pull request #226 from fust/fix_postgres_resources
Fix postgres resources
2021-04-22 13:33:11 -04:00
Marcelo Moreira de Mello
cd181bc1fd Merge pull request #235 from tchellomello/split_image_expr
Split container image and version in 2 variables
2021-04-22 13:31:46 -04:00
Marcelo Moreira de Mello
01f1321bd4 Merge branch 'devel' into split_image_expr 2021-04-22 10:28:32 -04:00
Marcelo Moreira de Mello
52768c9a65 updated coumentation 2021-04-22 10:18:46 -04:00
TheStally
96b878f049 Add NodePort to tower_ingress_type enum 2021-04-22 08:39:28 +01:00
TheStally
a00052a8ca Fix template logic 2021-04-22 08:37:31 +01:00
Thom Wijtenburg
4596c30e9d Make displayName for PostgreSQL parameters single line 2021-04-22 07:07:51 +02:00
Marcelo Moreira de Mello
051500fff1 updated documentation 2021-04-21 17:51:40 -04:00
Marcelo Moreira de Mello
bc34758c91 Split container image and version in 2 variables 2021-04-21 17:18:02 -04:00
Shane McDonald
e3f027d625 Merge pull request #212 from tchellomello/change_pull_policy_redis
Inherit imagePullPolicy to redis container
2021-04-21 16:44:07 -04:00
Marcelo Moreira de Mello
46fca2af5a updated 2021-04-21 15:41:18 -04:00
Marcelo Moreira de Mello
dc073c85ed updated 2021-04-21 15:02:33 -04:00
Marcelo Moreira de Mello
597356f317 Handles deleting and recreating statefulset and deployment when needed 2021-04-21 14:58:21 -04:00
Shane McDonald
0655122a57 Merge pull request #234 from shanemcd/stop-using-devel
Stop telling folks to use devel
2021-04-21 13:32:06 -04:00
Shane McDonald
51ea411a79 Stop telling folks to use devel 2021-04-21 13:19:43 -04:00
Shane McDonald
776dba5e23 Merge pull request #216 from gamuniz/document_env_config
added documentation around environment variables
2021-04-21 10:21:59 -04:00
Shane McDonald
6858dcfa7a Merge pull request #231 from daenney/migration-docs
migration: Clarify you can migrate in-place
2021-04-21 09:15:29 -04:00
Daniele Sluijters
ea018be298 migration: Clarify you can migrate in-place
Closes #213
2021-04-21 15:01:39 +02:00
Thom Wijtenburg
841d1f94f2 Change default resource requirement to object 2021-04-20 11:52:56 +02:00
Thom Wijtenburg
262b1cca34 Update variable table for PostgreSQL service 2021-04-20 11:33:24 +02:00
Thom Wijtenburg
378a33aaee Fix PostgreSQL resource requests 2021-04-20 11:14:48 +02:00
Marcelo Moreira de Mello
09652056b7 Added initial upgrade documentation 2021-04-20 00:23:10 -04:00
Marcelo Moreira de Mello
39ef816f5e Updated logic to avoid crash during upgrades 2021-04-19 23:19:13 -04:00
Gabe Muniz
f68dc77ea3 added documentation around environment variables 2021-04-15 17:33:31 -04:00
Shane McDonald
51b2a211cb Merge pull request #214 from gamuniz/expose_extra_volume_config
Expose extra volume config
2021-04-15 16:08:11 -04:00
Gabe Muniz
9de67ad898 added default value for ee extra mounts 2021-04-15 15:25:45 -04:00
Gabe Muniz
8922e9fe7d added warning about kubernetes api naming 2021-04-15 11:09:32 -04:00
Gabe Muniz
90f25ab20c added ability to mount to Execution container with example 2021-04-15 10:01:46 -04:00
Gabe Muniz
6c476a994e added ability to mount conf.d and fixed underscore api issue 2021-04-14 16:18:44 -04:00
stal
1b87616a11 Add tower_ingress_type NodePort 2021-04-14 20:15:15 +01:00
Gabe Muniz
8d65b84b89 expose settings to use custom volumes and volume mounts 2021-04-14 14:49:42 -04:00
Marcelo Moreira de Mello
13f7b2ae30 Fixed indentation lint 2021-04-14 12:00:26 -04:00
Marcelo Moreira de Mello
bdcd95ab55 Fixing lint 2021-04-14 11:45:46 -04:00
Marcelo Moreira de Mello
032d6b790a Added OKD console deployment 2021-04-14 11:41:54 -04:00
Shane McDonald
125b6fbe58 Merge pull request #208 from a-eperez/devel
Include support for nodeSelector and tolerations in AWX Postgres pod
2021-04-14 11:25:34 -04:00
Ernesto Pérez
d4d9d2a982 Correction, replace tower_tolerations by tower_postgres_tolerations 2021-04-14 09:59:50 +02:00
Ernesto Pérez
1cc47f7570 Correction, replace tower_node_selector by tower_postgres_selector 2021-04-14 09:56:06 +02:00
Marcelo Moreira de Mello
83a85d15c0 Inherit imagePullPolicy to redis container 2021-04-13 21:28:55 -04:00
Ernesto Pérez
0ab33a17df Fix yaml missing starting space in comment 2021-04-13 14:33:47 +02:00
Ernesto Pérez
30e4ad0d3d Postgres selector and tolerations description included in README.md 2021-04-13 14:00:15 +02:00
Ernesto Pérez
151ff11745 Add nodeSelector and tolerations for Postgres pod 2021-04-13 13:50:14 +02:00
Shane McDonald
b942794179 Merge pull request #206 from tchellomello/pwd_quotes
Removed jinja2 filter 'quote' for db password
2021-04-12 16:36:53 -04:00
Marcelo Moreira de Mello
57071129bf Removed jinja2 filter 'quote' for db password 2021-04-12 16:23:21 -04:00
stal
0f90847c07 Add Service types to docs based on Ingress used 2021-04-12 21:14:54 +01:00
stal
e091b32c4b use ClusterIP service when ingress type is Ingress 2021-04-12 19:35:29 +01:00
Marcelo Moreira de Mello
298d39c57b Added support to override pg_sslmode 2021-04-12 12:48:00 -04:00
Shane McDonald
9503d3cf48 Merge pull request #197 from RylandDeGregory/rylanddegregory-patch-1
Update docs and service Template for LoadBalancer ingress type
2021-04-08 12:45:05 -04:00
Ryland DeGregory
95f04abdfd Added conditional to validate that tower_loadbalancer_annotations is defined 2021-04-08 12:24:56 -04:00
Ryland DeGregory
7e3f5047a1 Updated protocol var in LoadBalancer ingress spec 2021-04-08 12:20:08 -04:00
Shane McDonald
5c77cf004b Merge pull request #192 from shanemcd/gha-release-workflow
Add GHA workflow for pushing releases to Quay
2021-04-08 09:10:08 -04:00
Shane McDonald
295ed47c43 Add GHA workflow for pushing releases to Quay 2021-04-08 07:26:45 -04:00
114 changed files with 5080 additions and 1598 deletions

39
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,39 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
##### ISSUE TYPE
- Bug Report
##### SUMMARY
<!-- Briefly describe the problem. -->
##### ENVIRONMENT
* AWX version: X.Y.Z
* Operator version: X.Y.Z
* Kubernetes version:
* AWX install method: openshift, minishift, docker on linux, docker for mac, boot2docker
##### STEPS TO REPRODUCE
<!-- Please describe exactly how to reproduce the problem. -->
##### EXPECTED RESULTS
<!-- What did you expect to happen when running the steps above? -->
##### ACTUAL RESULTS
<!-- What actually happened? -->
##### ADDITIONAL INFORMATION
<!-- Include any links to sosreport, database dumps, screenshots or other
information. -->
##### AWX-OPERATOR LOGS

View File

@@ -31,14 +31,21 @@ jobs:
ansible-lint \
openshift \
jmespath \
ansible
ansible-core
- name: Install Collections
run: |
ansible-galaxy collection install community.kubernetes operator_sdk.util
ansible-galaxy collection install community.general kubernetes.core:1.2.1 operator_sdk.util
- name: Setup Minikube
uses: manusa/actions-setup-minikube@v2.4.2
with:
minikube version: 'v1.16.0'
kubernetes version: 'v1.19.2'
github token: ${{ secrets.GITHUB_TOKEN }}
- name: Run Molecule
env:
MOLECULE_VERBOSITY: 3
run: |
molecule test -s test-local
molecule test -s test-minikube

34
.github/workflows/devel.yaml vendored Normal file
View File

@@ -0,0 +1,34 @@
---
name: Devel
on:
push:
branches: [devel]
jobs:
release:
runs-on: ubuntu-18.04
name: Push devel image
steps:
- uses: actions/checkout@v2
- name: Install Operator-SDK
run: |
mkdir -p $GITHUB_WORKSPACE/bin
wget -O $GITHUB_WORKSPACE/bin/operator-sdk https://github.com/operator-framework/operator-sdk/releases/download/v0.19.4/operator-sdk-v0.19.4-x86_64-linux-gnu
chmod +x $GITHUB_WORKSPACE/bin/operator-sdk
echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
- name: Build Image
run: |
operator-sdk build awx-operator:devel
- name: Push To Quay
uses: redhat-actions/push-to-registry@v2.1.1
with:
image: awx-operator
tags: devel
registry: quay.io/ansible/
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}

View File

@@ -3,13 +3,14 @@
name: Release
on:
push:
branches: [devel]
release:
types:
- created
jobs:
release:
runs-on: ubuntu-18.04
name: release
name: Push tagged image to Quay
steps:
- uses: actions/checkout@v2
@@ -22,13 +23,13 @@ jobs:
- name: Build Image
run: |
operator-sdk build awx-operator:devel
operator-sdk build awx-operator:${{ github.event.release.tag_name }}
- name: Push To Quay
uses: redhat-actions/push-to-registry@v2.1.1
with:
image: awx-operator
tags: devel
tags: ${{ github.event.release.tag_name }}
registry: quay.io/ansible/
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}

37
CHANGELOG.md Normal file
View File

@@ -0,0 +1,37 @@
# Changelog
This is a list of high-level changes for each release of `awx-operator`. A full list of commits can be found at `https://github.com/ansible/awx-operator/releases/tag/<version>`.
# 0.10.0 (Jun 1, 2021)
- Make tower_ingress_type to respect ClusterIP definition (Marcelo Moreira de Mello) - e37c091 (breaking_change)
- Add ability to get/create/delete secrets for the awx service account (Christian M. Adams) - 61b3cb4
- Added ability to specify annotations to ServiceAccount (Marcelo Moreira de Mello) - 446ac0b
- Do not shadow other variables (Yanis Guenane) - 223fe98
- Do not prepend variables name with tower_ (Yanis Guenane) - 75458d0 (breaking_change)
- Fully remove finalizer (Christian M. Adams) - fd92050
- Use custom pg_dump format for faster restores (Christian M. Adams) - f16d9ac
- Allow user to specify empty string for storage class on PVC (Christian M. Adams) - 818b837
- Unset ownerRefs in the installer instead of the finalizer (Christian M. Adams) - c12a1f0
- Make awx-operator compatible with Ansible 2.12 (Alan Rominger) - 5216489
- Restore: set proper kind var after deploying AWX CR (Julen Landa Alustiza) - fc4687f
- Add support for custom service labels (Jeremy Kimber) - fd42802
- Rename product specific variable names (Christian M. Adams) - 5ae3636 (breaking_change)
- Add watcher for backup CR (Christian M. Adams) - fdcc745
# 0.9.0 (May 1, 2021)
- Update playbook to allow for deploying custom image version/tag (Shane McDonald) - 77e7039
- Mounts /var/lib/awx/projects on awx-web container (Marcelo Moreira de Mello) - f21ec4d
- Extra Settings: Allow one to pass extra API configuration settings. (Yanis Guenane) - 1d14ebc
- PostgreSQL: Properly handle variable name difference when using Red Hat containers (Yanis Guenane) - 2965a90
- Deployment type: Make more fields dynamic based on that field (Yanis Guenane) - 4706aa9
- Add templated EE volume mount var to operator config (Christian M. Adams) - e55d83f
- Add NodePort to tower_ingress_type enum (TheStally) - 96b878f
- Split container image and version in 2 variables (Marcelo Moreira de Mello) - bc34758 (breaking_change)
- Handles deleting and recreating statefulset and deployment when needed (Marcelo Moreira de Mello) - 597356f
- Add tower_ingress_type NodePort (stal) - 1b87616
- expose settings to use custom volumes and volume mounts (Gabe Muniz) - 8d65b84
- Inherit imagePullPolicy to redis container (Marcelo Moreira de Mello) - 83a85d1
- Add nodeSelector and tolerations for Postgres pod (Ernesto Pérez) - 151ff11
- Added support to override pg_sslmode (Marcelo Moreira de Mello) - 298d39c

140
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,140 @@
# AWX-Operator Contributing Guidelines
Hi there! We're excited to have you as a contributor.
Have questions about this document or anything not covered here? Please file a new at [https://github.com/ansible/awx-operator/issues](https://github.com/ansible/awx-operator/issues).
## Table of contents
* [Things to know prior to submitting code](#things-to-know-prior-to-submitting-code)
* [Submmiting your Work](#submitting-your-work)
* [Testing](#testing)
* [Testing in Docker](#testing-in-docker)
* [Testing in Minikube](#testing-in-minikube)
* [Generating a bundle](#generating-a-bundle)
* [Reporting Issues](#reporting-issues)
## Things to know prior to submitting code
- All code submissions are done through pull requests against the `devel` branch.
- All PRs must have a single commit. Make sure to `squash` any changes into a single commit.
- Take care to make sure no merge commits are in the submission, and use `git rebase` vs `git merge` for this reason.
- If collaborating with someone else on the same branch, consider using `--force-with-lease` instead of `--force`. This will prevent you from accidentally overwriting commits pushed by someone else. For more information, see https://git-scm.com/docs/git-push#git-push---force-with-leaseltrefnamegt
- We ask all of our community members and contributors to adhere to the [Ansible code of conduct](http://docs.ansible.com/ansible/latest/community/code_of_conduct.html). If you have questions, or need assistance, please reach out to our community team at [codeofconduct@ansible.com](mailto:codeofconduct@ansible.com)
## Submmiting your work
1. From your fork `devel` branch, create a new brach to stage your changes.
```sh
#> git checkout -b <branch-name>
```
2. Make your changes.
3. Test your changes according described on the Testing section.
4. If everylooks looks correct, commit your changes.
```sh
#> git add <FILES>
#> git commit -m "My message here"
```
5. Create your [pull request](https://github.com/ansible/awx-operator/pulls)
**Note**: If you have multiple commits, make sure to `squash` your commits into a single commit which will facilitate our release process.
## Testing
This Operator includes a [Molecule](https://molecule.readthedocs.io/en/stable/)-based test environment, which can be executed standalone in Docker (e.g. in CI or in a single Docker container anywhere), or inside any kind of Kubernetes cluster (e.g. Minikube).
You need to make sure you have Molecule installed before running the following commands. You can install Molecule with:
```sh
#> pip install 'molecule[docker]'
```
Running `molecule test` sets up a clean environment, builds the operator, runs all configured tests on an example operator instance, then tears down the environment (at least in the case of Docker).
If you want to actively develop the operator, use `molecule converge`, which does everything but tear down the environment at the end.
#### Testing in Docker
```sh
#> molecule test -s test-local
```
This environment is meant for headless testing (e.g. in a CI environment, or when making smaller changes which don't need to be verified through a web interface). It is difficult to test things like AWX's web UI or to connect other applications on your local machine to the services running inside the cluster, since it is inside a Docker container with no static IP address.
#### Testing in Minikube
```sh
#> minikube start --memory 8g --cpus 4
#> minikube addons enable ingress
#> molecule test -s test-minikube
```
[Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) is a more full-featured test environment running inside a full VM on your computer, with an assigned IP address. This makes it easier to test things like NodePort services and Ingress from outside the Kubernetes cluster (e.g. in a browser on your computer).
Once the operator is deployed, you can visit the AWX UI in your browser by following these steps:
1. Make sure you have an entry like `IP_ADDRESS example-awx.test` in your `/etc/hosts` file. (Get the IP address with `minikube ip`.)
2. Visit `http://example-awx.test/` in your browser. (Default admin login is `test`/`changeme`.)
Alternatively, you can also update the service `awx-service` in your namespace to use the type `NodePort` and use following command to get the URL to access your AWX instance:
```sh
#> minikube service <serviceName> -n <namespaceName> --url
```
## Generating a bundle
> :warning: operator-sdk version 0.19.4 is needed to run the following commands
If one has the Operator Lifecycle Manager (OLM) installed, the following steps is the process to generate the bundle that would nicely display in the OLM interface.
At the root of this directory:
1. Build and publish the operator
```
#> operator-sdk build registry.example.com/ansible/awx-operator:mytag
#> podman push registry.example.com/ansible/awx-operator:mytag
```
2. Build and publish the bundle
```
#> podman build . -f bundle.Dockerfile -t registry.example.com/ansible/awx-operator-bundle:mytag
#> podman push registry.example.com/ansible/awx-operator-bundle:mytag
```
3. Build and publish an index with your bundle in it
```
#> opm index add --bundles registry.example.com/ansible/awx-operator-bundle:mytag --tag registry.example.com/ansible/awx-operator-catalog:mytag
#> podman push registry.example.com/ansible/awx-operator-catalog:mytag
```
4. In your Kubernetes create a new CatalogSource pointing to `registry.example.com/ansible/awx-operator-catalog:mytag`
```
---
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: <catalogsource-name>
namespace: <namespace>
spec:
displayName: 'myoperatorhub'
image: registry.example.com/ansible/awx-operator-catalog:mytag
publisher: 'myoperatorhub'
sourceType: grpc
```
Applying this template will do it. Once the CatalogSource is in a READY state, the bundle should be available on the OperatorHub tab (as part of the custom CatalogSource that just got added)
5. Enjoy
## Reporting Issues
We welcome your feedback, and encourage you to file an issue when you run into a problem.

730
README.md
View File

@@ -14,8 +14,8 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
* [Basic Install](#basic-install)
* [Admin user account configuration](#admin-user-account-configuration)
* [Network and TLS Configuration](#network-and-tls-configuration)
* [Service Type](#service-type)
* [Ingress Type](#ingress-type)
* [TLS Termination](#tls-termination)
* [Database Configuration](#database-configuration)
* [External PostgreSQL Service](#external-postgresql-service)
* [Migrating data from an old AWX instance](#migrating-data-from-an-old-awx-instance)
@@ -24,16 +24,18 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
* [Deploying a specific version of AWX](#deploying-a-specific-version-of-awx)
* [Privileged Tasks](#privileged-tasks)
* [Containers Resource Requirements](#containers-resource-requirements)
* [LDAP Certificate Authority](#ldap-certificate-authority)
* [Trusting a Custom Certificate Authority](#trusting-a-custom-certificate-authority)
* [Persisting Projects Directory](#persisting-projects-directory)
* [Development](#development)
* [Testing](#testing)
* [Testing in Docker](#testing-in-docker)
* [Testing in Minikube](#testing-in-minikube)
* [Generating a bundle](#generating-a-bundle)
* [Custom Volume and Volume Mount Options](#custom-volume-and-volume-mount-options)
* [Exporting Environment Variables to Containers](#exporting-environment-variables-to-containers)
* [Extra Settings](#extra-settings)
* [Service Account](#service-account)
* [Upgrading](#upgrading)
* [Contributing](#contributing)
* [Release Process](#release-process)
* [Build a new release](#build-a-new-release)
* [Build a new version of the operator yaml file](#build-a-new-version-of-the-operator-yaml-file)
* [Verifiy Functionality](#verify-functionality)
* [Update Version](#update-version)
* [Commit / Create Release](#commit--create-release)
* [Author](#author)
<!--te-->
@@ -41,7 +43,7 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
This operator is meant to provide a more Kubernetes-native installation method for AWX via an AWX Custom Resource Definition (CRD).
Note that the operator is not supported by Red Hat, and is in **alpha** status. For now, use it at your own risk!
> :warning: The operator is not supported by Red Hat, and is in **alpha** status. For now, use it at your own risk!
## Usage
@@ -49,38 +51,117 @@ Note that the operator is not supported by Red Hat, and is in **alpha** status.
This Kubernetes Operator is meant to be deployed in your Kubernetes cluster(s) and can manage one or more AWX instances in any namespace.
First you need to deploy AWX Operator into your cluster:
For testing purposes, the `awx-operator` can be deployed on a [Minikube](https://minikube.sigs.k8s.io/docs/) cluster. Due to different OS and hardware environments, please refer to the official Minikube documentation for further information.
```bash
#> kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml
$ minikube start --addons=ingress --cpus=4 --cni=flannel --install-addons=true \
--kubernetes-version=stable --memory=6g
😄 minikube v1.20.0 on Fedora 34
✨ Using the kvm2 driver based on user configuration
👍 Starting control plane node minikube in cluster minikube
🔥 Creating kvm2 VM (CPUs=4, Memory=6144MB, Disk=20000MB) ...
🐳 Preparing Kubernetes v1.20.2 on Docker 20.10.6 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔗 Configuring Flannel (Container Networking Interface) ...
🔎 Verifying Kubernetes components...
▪ Using image docker.io/jettech/kube-webhook-certgen:v1.5.1
▪ Using image k8s.gcr.io/ingress-nginx/controller:v0.44.0
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
▪ Using image docker.io/jettech/kube-webhook-certgen:v1.5.1
🔎 Verifying ingress addon...
🌟 Enabled addons: storage-provisioner, default-storageclass, ingress
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
```
Then create a file named `my-awx.yml` with the following contents:
Once Minikube is deployed, check if the node(s) and `kube-apiserver` communication is working as expected.
```bash
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 6m28s v1.20.2
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
ingress-nginx ingress-nginx-admission-create-tjk94 0/1 Completed 0 6m4s
ingress-nginx ingress-nginx-admission-patch-r4pl6 0/1 Completed 0 6m4s
ingress-nginx ingress-nginx-controller-5d88495688-sbtp9 1/1 Running 0 6m4s
kube-system coredns-74ff55c5b-2wz6n 1/1 Running 0 6m4s
kube-system etcd-minikube 1/1 Running 0 6m13s
kube-system kube-apiserver-minikube 1/1 Running 0 6m13s
kube-system kube-controller-manager-minikube 1/1 Running 0 6m13s
kube-system kube-flannel-ds-amd64-lw7lv 1/1 Running 0 6m3s
kube-system kube-proxy-lcxx7 1/1 Running 0 6m3s
kube-system kube-scheduler-minikube 1/1 Running 0 6m13s
kube-system storage-provisioner 1/1 Running 1 6m17s
```
Now you need to deploy AWX Operator into your cluster. Start by going to https://github.com/ansible/awx-operator/releases and making note of the latest release. Replace `<TAG>` in the URL `https://raw.githubusercontent.com/ansible/awx-operator/<TAG>/deploy/awx-operator.yaml` with the version you are deploying.
```bash
$ kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/<TAG>/deploy/awx-operator.yaml
customresourcedefinition.apiextensions.k8s.io/awxs.awx.ansible.com created
customresourcedefinition.apiextensions.k8s.io/awxbackups.awx.ansible.com created
customresourcedefinition.apiextensions.k8s.io/awxrestores.awx.ansible.com created
clusterrole.rbac.authorization.k8s.io/awx-operator created
clusterrolebinding.rbac.authorization.k8s.io/awx-operator created
serviceaccount/awx-operator created
deployment.apps/awx-operator created
```
Wait a few minutes and you should have the `awx-operator` running.
```bash
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
awx-operator-7dbf9db9d7-z9hqx 1/1 Running 0 50s
```
Then create a file named `awx-demo.yml` with the suggested content. The `metadata.name` you provide, will be the name of the resulting AWX deployment. If you deploy more than one AWX instance to the same namespace, be sure to use unique names.
```yaml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
name: awx-demo
spec:
service_type: nodeport
ingress_type: none
hostname: awx-demo.example.com
```
> The metadata.name you provide, will be the name of the resulting AWX deployment. If you deploy more than one to the same namespace, be sure to use unique names.
Finally, use `kubectl` to create the awx instance in your cluster:
```bash
#> kubectl apply -f my-awx.yml
$ kubectl apply -f awx-demo.yml
awx.awx.ansible.com/awx-demo created
```
After a few minutes, the new AWX instance will be deployed. One can look at the operator pod logs in order to know where the installation process is at. This can be done by running the following command: `kubectl logs -f deployments/awx-operator`.
Once deployed, the AWX instance will be accessible at `http://awx.mycompany.com/` (assuming your cluster has an Ingress controller configured).
```bash
$ kubectl get pods -l "app.kubernetes.io/managed-by=awx-operator"
NAME READY STATUS RESTARTS AGE
awx-demo-77d96f88d5-pnhr8 4/4 Running 0 3m24s
awx-demo-postgres-0 1/1 Running 0 3m34s
$ kubectl get svc -l "app.kubernetes.io/managed-by=awx-operator"
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
awx-demo-postgres ClusterIP None <none> 5432/TCP 4m4s
awx-demo-service NodePort 10.109.40.38 <none> 80:31006/TCP 3m56s
```
Once deployed, the AWX instance will be accessible by the command `minikube service awx-demo-service --url`.
By default, the admin user is `admin` and the password is available in the `<resourcename>-admin-password` secret. To retrieve the admin password, run `kubectl get secret <resourcename>-admin-password -o jsonpath="{.data.password}" | base64 --decode`
You just completed the most basic install of an AWX instance via this operator. Congratulations!!!!
You just completed the most basic install of an AWX instance via this operator. Congratulations !
For an example using the Nginx Controller in Minukube, don't miss our [demo video](https://asciinema.org/a/416946).
[![asciicast](https://raw.githubusercontent.com/ansible/awx-operator/devel/docs/awx-demo.svg)](https://asciinema.org/a/416946)
### Admin user account configuration
@@ -88,14 +169,14 @@ There are three variables that are customizable for the admin user account creat
| Name | Description | Default |
| --------------------------- | -------------------------------------------- | ---------------- |
| tower_admin_user | Name of the admin user | admin |
| tower_admin_email | Email of the admin user | test@example.com |
| tower_admin_password_secret | Secret that contains the admin user password | Empty string |
| admin_user | Name of the admin user | admin |
| admin_email | Email of the admin user | test@example.com |
| admin_password_secret | Secret that contains the admin user password | Empty string |
> :warning: **tower_admin_password_secret must be a Kubernetes secret and not your text clear password**.
> :warning: **admin_password_secret must be a Kubernetes secret and not your text clear password**.
If `tower_admin_password_secret` is not provided, the operator will look for a secret named `<resourcename>-admin-password` for the admin password. If it is not present, the operator will generate a password and create a Secret from it named `<resourcename>-admin-password`.
If `admin_password_secret` is not provided, the operator will look for a secret named `<resourcename>-admin-password` for the admin password. If it is not present, the operator will generate a password and create a Secret from it named `<resourcename>-admin-password`.
To retrieve the admin password, run `kubectl get secret <resourcename>-admin-password -o jsonpath="{.data.password}" | base64 --decode`
@@ -115,81 +196,114 @@ stringData:
### Network and TLS Configuration
#### Ingress Type
#### Service Type
By default, the AWX operator is not opinionated and won't force a specific ingress type on you. So, if `tower_ingress_type` is not specified as part of the Custom Resource specification, it will default to `none` and nothing ingress-wise will be created.
If the `service_type` is not specified, the `ClusterIP` service will be used for your AWX Tower service.
The AWX operator provides support for three kinds of `Ingress` to access AWX: `Ingress`, `Route` and `LoadBalancer`, To toggle between these options, you can add the following to your AWX CR:
The `service_type` supported options are: `ClusterIP`, `LoadBalancer` and `NodePort`.
* Route
```yaml
---
spec:
...
tower_ingress_type: Route
```
* Ingress
```yaml
---
spec:
...
tower_ingress_type: Ingress
tower_hostname: awx.mycompany.com
```
* LoadBalancer
```yaml
---
spec:
...
tower_ingress_type: LoadBalancer
tower_ingress_protocol: http
```
#### TLS Termination
* Route
The following variables are customizable to specify the TLS termination procedure when `Route` is picked as an Ingress
The following variables are customizable for any `service_type`
| Name | Description | Default |
| ------------------------------------- | --------------------------------------------- | --------------------------------- |
| tower_route_host | Common name the route answers for | Empty string |
| tower_route_tls_termination_mechanism | TLS Termination mechanism (Edge, Passthrough) | Edge |
| tower_route_tls_secret | Secret that contains the TLS information | Empty string |
| service_labels | Add custom labels | Empty string |
* Ingress
The following variables are customizable to specify the TLS termination procedure when `Ingress` is picked as an Ingress
| Name | Description | Default |
| -------------------------- | ---------------------------------------- | ------------- |
| tower_ingress_annotations | Ingress annotations | Empty string |
| tower_ingress_tls_secret | Secret that contains the TLS information | Empty string |
```yaml
---
spec:
...
service_type: ClusterIP
service_labels: |
environment: testing
```
* LoadBalancer
The following variables are customizable to specify the TLS termination procedure when `LoadBalancer` is picked as an Ingress
The following variables are customizable only when `service_type=LoadBalancer`
| Name | Description | Default |
| ------------------------------ | ---------------------------------------- | ------------- |
| tower_loadbalancer_annotations | LoadBalancer annotations | Empty string |
| tower_loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
| tower_loadbalancer_port | Port used for Loadbalancer ingress | 80 |
| loadbalancer_annotations | LoadBalancer annotations | Empty string |
| loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
| loadbalancer_port | Port used for Loadbalancer ingress | 80 |
When setting up a Load Balancer for HTTPS you will be required to set the `tower_loadbalancer_port` to move the port away from `80`.
```yaml
---
spec:
...
service_type: LoadBalancer
loadbalancer_protocol: https
loadbalancer_port: 443
loadbalancer_annotations: |
environment: testing
service_labels: |
environment: testing
```
When setting up a Load Balancer for HTTPS you will be required to set the `loadbalancer_port` to move the port away from `80`.
The HTTPS Load Balancer also uses SSL termination at the Load Balancer level and will offload traffic to AWX over HTTP.
#### Ingress Type
By default, the AWX operator is not opinionated and won't force a specific ingress type on you. So, when the `ingress_type` is not specified, it will default to `none` and nothing ingress-wise will be created.
The `ingress_type` supported options are: `none`, `ingress` and `route`. To toggle between these options, you can add the following to your AWX CRD:
* None
```yaml
---
spec:
...
ingress_type: none
```
* Generic Ingress Controller
The following variables are customizable when `ingress_type=ingress`. The `ingress` type creates an Ingress resource as [documented](https://kubernetes.io/docs/concepts/services-networking/ingress/) which can be shared with many other Ingress Controllers as [listed](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/).
| Name | Description | Default |
| -------------------------- | ---------------------------------------- | ---------------------------- |
| ingress_annotations | Ingress annotations | Empty string |
| ingress_tls_secret | Secret that contains the TLS information | Empty string |
| hostname | Define the FQDN | {{ meta.name }}.example.com |
```yaml
---
spec:
...
ingress_type: ingress
hostname: awx-demo.example.com
ingress_annotations: |
environment: testing
```
* Route
The following variables are customizable when `ingress_type=route`
| Name | Description | Default |
| ------------------------------------- | --------------------------------------------- | --------------------------------------------------------|
| route_host | Common name the route answers for | `<instance-name>-<namespace>-<routerCanonicalHostname>` |
| route_tls_termination_mechanism | TLS Termination mechanism (Edge, Passthrough) | Edge |
| route_tls_secret | Secret that contains the TLS information | Empty string |
```yaml
---
spec:
...
ingress_type: route
route_host: awx-demo.example.com
route_tls_termination_mechanism: Passthrough
route_tls_secret: custom-route-tls-secret-name
```
### Database Configuration
#### External PostgreSQL Service
In order for the AWX instance to rely on an external database, the Custom Resource needs to know about the connection details. Those connection details should be stored as a secret and either specified as `tower_postgres_configuration_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-postgres-configuration`.
In order for the AWX instance to rely on an external database, the Custom Resource needs to know about the connection details. Those connection details should be stored as a secret and either specified as `postgres_configuration_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-postgres-configuration`.
The secret should be formatted as follows:
@@ -207,9 +321,15 @@ stringData:
database: <desired database name>
username: <username to connect as>
password: <password to connect with>
sslmode: prefer
type: unmanaged
type: Opaque
```
> It is possible to set a specific username, password, port, or database, but still have the database managed by the operator. In this case, when creating the postgres-configuration secret, the `type: managed` field should be added.
**Note**: The variable `sslmode` is valid for `external` databases only. The allowed values are: `prefer`, `disable`, `allow`, `require`, `verify-ca`, `verify-full`.
#### Migrating data from an old AWX instance
For instructions on how to migrate from an older version of AWX, see [migration.md](./docs/migration.md).
@@ -222,10 +342,11 @@ The following variables are customizable for the managed PostgreSQL service
| Name | Description | Default |
| ------------------------------------ | ------------------------------------------ | --------------------------------- |
| tower_postgres_image | Path of the image to pull | postgres:12 |
| tower_postgres_resource_requirements | PostgreSQL container resource requirements | requests: {storage: 8Gi} |
| tower_postgres_storage_class | PostgreSQL PV storage class | Empty string |
| tower_postgres_data_path | PostgreSQL data path | `/var/lib/postgresql/data/pgdata` |
| postgres_image | Path of the image to pull | postgres:12 |
| postgres_resource_requirements | PostgreSQL container resource requirements | Empty object |
| postgres_storage_requirements | PostgreSQL container storage requirements | requests: {storage: 8Gi} |
| postgres_storage_class | PostgreSQL PV storage class | Empty string |
| postgres_data_path | PostgreSQL data path | `/var/lib/postgresql/data/pgdata` |
Example of customization could be:
@@ -233,17 +354,22 @@ Example of customization could be:
---
spec:
...
tower_postgres_resource_requirements:
postgres_resource_requirements:
requests:
cpu: 500m
memory: 2Gi
limits:
cpu: 1
memory: 4Gi
postgres_storage_requirements:
requests:
storage: 8Gi
limits:
memory: 4Gi
storage: 50Gi
tower_postgres_storage_class: fast-ssd
postgres_storage_class: fast-ssd
```
**Note**: If `tower_postgres_storage_class` is not defined, Postgres will store it's data on a volume using the default storage class for your cluster.
**Note**: If `postgres_storage_class` is not defined, Postgres will store it's data on a volume using the default storage class for your cluster.
### Advanced Configuration
@@ -251,12 +377,15 @@ spec:
There are a few variables that are customizable for awx the image management.
| Name | Description |
| ----------------------- | -------------------------- |
| tower_image | Path of the image to pull |
| tower_image_pull_policy | The pull policy to adopt |
| tower_image_pull_secret | The pull secret to use |
| tower_ee_images | A list of EEs to register |
| Name | Description |
| --------------------------| -------------------------- |
| image | Path of the image to pull |
| image_version | Image version to pull |
| image_pull_policy | The pull policy to adopt |
| image_pull_secret | The pull secret to use |
| ee_images | A list of EEs to register |
| redis_image | Path of the image to pull |
| redis_image_version | Image version to pull |
Example of customization could be:
@@ -264,14 +393,17 @@ Example of customization could be:
---
spec:
...
tower_image: myorg/my-custom-awx
tower_image_pull_policy: Always
tower_image_pull_secret: pull_secret_name
tower_ee_images:
image: myorg/my-custom-awx
image_version: latest
image_pull_policy: Always
image_pull_secret: pull_secret_name
ee_images:
- name: my-custom-awx-ee
image: myorg/my-custom-awx-ee
```
**Note**: The `image` and `image_version` are intended for local mirroring scenarios. Please note that using a version of AWX other than the one bundled with the `awx-operator` is **not** supported. For the default values, check the [main.yml](https://github.com/ansible/awx-operator/blob/devel/roles/installer/defaults/main.yml) file.
#### Privileged Tasks
Depending on the type of tasks that you'll be running, you may find that you need the task pod to run as `privileged`. This can open yourself up to a variety of security concerns, so you should be aware (and verify that you have the privileges) to do this if necessary. In order to toggle this feature, you can add the following to your custom resource:
@@ -280,7 +412,7 @@ Depending on the type of tasks that you'll be running, you may find that you nee
---
spec:
...
tower_task_privileged: true
task_privileged: true
```
If you are attempting to do this on an OpenShift cluster, you will need to grant the `awx` ServiceAccount the `privileged` SCC, which can be done with:
@@ -296,10 +428,11 @@ Again, this is the most relaxed SCC that is provided by OpenShift, so be sure to
The resource requirements for both, the task and the web containers are configurable - both the lower end (requests) and the upper end (limits).
| Name | Description | Default |
| -------------------------------- | ------------------------------------ | ----------------------------------- |
| tower_web_resource_requirements | Web container resource requirements | requests: {cpu: 1000m, memory: 2Gi} |
| tower_task_resource_requirements | Task container resource requirements | requests: {cpu: 500m, memory: 1Gi} |
| Name | Description | Default |
| -------------------------------- | ------------------------------------------------ | ----------------------------------- |
| web_resource_requirements | Web container resource requirements | requests: {cpu: 1000m, memory: 2Gi} |
| task_resource_requirements | Task container resource requirements | requests: {cpu: 500m, memory: 1Gi} |
| ee_resource_requirements | EE control plane container resource requirements | requests: {cpu: 500m, memory: 1Gi} |
Example of customization could be:
@@ -307,14 +440,21 @@ Example of customization could be:
---
spec:
...
tower_web_resource_requirements:
web_resource_requirements:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
tower_task_resource_requirements:
task_resource_requirements:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
ee_resource_requirements:
requests:
cpu: 500m
memory: 1Gi
@@ -325,15 +465,19 @@ spec:
#### Assigning AWX pods to specific nodes
You can constrain the AWX pods created by the operator to run on a certain subset of nodes. `tower_node_selector` constrains
the AWX pods to run only on the nodes that match all the specified key/value pairs. `tower_tolerations` allow the AWX
You can constrain the AWX pods created by the operator to run on a certain subset of nodes. `node_selector` and `postgres_selector` constrains
the AWX pods to run only on the nodes that match all the specified key/value pairs. `tolerations` and `postgres_tolerations` allow the AWX
pods to be scheduled onto nodes with matching taints.
| Name | Description | Default |
| ------------------- | ---------------------- | ------- |
| tower_node_selector | AWX pods' nodeSelector | '' |
| tower_tolerations | AWX pods' tolerations | '' |
| Name | Description | Default |
| -------------------------------| --------------------------- | ------- |
| postgres_image | Path of the image to pull | 12 |
| postgres_image_version | Image version to pull | 12 |
| node_selector | AWX pods' nodeSelector | '' |
| tolerations | AWX pods' tolerations | '' |
| postgres_selector | Postgres pods' nodeSelector | '' |
| postgres_tolerations | Postgres pods' tolerations | '' |
Example of customization could be:
@@ -341,39 +485,56 @@ Example of customization could be:
---
spec:
...
tower_node_selector: |
node_selector: |
disktype: ssd
kubernetes.io/arch: amd64
kubernetes.io/os: linux
tower_tolerations: |
tolerations: |
- key: "dedicated"
operator: "Equal"
value: "AWX"
effect: "NoSchedule"
postgres_selector: |
disktype: ssd
kubernetes.io/arch: amd64
kubernetes.io/os: linux
postgres_tolerations: |
- key: "dedicated"
operator: "Equal"
value: "AWX"
effect: "NoSchedule"
```
#### LDAP Certificate Authority
#### Trusting a Custom Certificate Authority
If the variable `ldap_cacert_secret` is provided, the operator will look for a the data field `ldap-ca.crt` in the specified secret.
In cases which you need to trust a custom Certificate Authority, there are few variables you can customize for the `awx-operator`.
| Name | Description | Default |
| -------------------------------- | --------------------------------------- | --------|
| ldap_cacert_secret | LDAP Certificate Authority secret name | '' |
Trusting a custom Certificate Authority allows the AWX to access network services configured with SSL certificates issued locally, such as cloning a project from from an internal Git server via HTTPS. It is common for these scenarios, experiencing the error [unable to verify the first certificate](https://github.com/ansible/awx-operator/issues/376).
| Name | Description | Default |
| -------------------------------- | ---------------------------------------- | --------|
| ldap_cacert_secret | LDAP Certificate Authority secret name | '' |
| bundle_cacert_secret | Certificate Authority secret name | '' |
Please note the `awx-operator` will look for the data field `ldap-ca.crt` in the specified secret when using the `ldap_cacert_secret`, whereas the data field `bundle-ca.crt` is required for `bundle_cacert_secret` parameter.
Example of customization could be:
```yaml
---
spec:
...
ldap_cacert_secret: <resourcename>-ldap-ca-cert
ldap_cacert_secret: <resourcename>-custom-certs
bundle_cacert_secret: <resourcename>-custom-certs
```
To create the secret, you can use the command below:
```sh
# kubectl create secret generic <resourcename>-ldap-ca-cert --from-file=ldap-ca.crt=<PATH/TO/YOUR/CA/PEM/FILE>
# kubectl create secret generic <resourcename>-custom-certs \
--from-file=ldap-ca.crt=<PATH/TO/YOUR/CA/PEM/FILE> \
--from-fle=bundle-ca.crt=<PATH/TO/YOUR/CA/PEM/FILE>
```
#### Persisting Projects Directory
@@ -382,11 +543,11 @@ In cases which you want to persist the `/var/lib/projects` directory, there are
| Name | Description | Default |
| -----------------------------------| ---------------------------------------------------------------------------------------------------- | ---------------|
| tower_projects_persistence | Whether or not the /var/lib/projects directory will be persistent | false |
| tower_projects_storage_class | Define the PersistentVolume storage class | '' |
| tower_projects_storage_size | Define the PersistentVolume size | 8Gi |
| tower_projects_storage_access_mode | Define the PersistentVolume access mode | ReadWriteMany |
| tower_projects_existing_claim | Define an existing PersistentVolumeClaim to use (cannot be combined with `tower_projects_storage_*`) | '' |
| projects_persistence | Whether or not the /var/lib/projects directory will be persistent | false |
| projects_storage_class | Define the PersistentVolume storage class | '' |
| projects_storage_size | Define the PersistentVolume size | 8Gi |
| projects_storage_access_mode | Define the PersistentVolume access mode | ReadWriteMany |
| projects_existing_claim | Define an existing PersistentVolumeClaim to use (cannot be combined with `projects_storage_*`) | '' |
Example of customization when the `awx-operator` automatically handles the persistent volume could be:
@@ -394,129 +555,208 @@ Example of customization when the `awx-operator` automatically handles the persi
---
spec:
...
tower_projects_persistence: true
tower_projects_storage_class: rook-ceph
tower_projects_storage_size: 20Gi
projects_persistence: true
projects_storage_class: rook-ceph
projects_storage_size: 20Gi
```
## Development
#### Custom Volume and Volume Mount Options
### Testing
In a scenario where custom volumes and volume mounts are required to either overwrite defaults or mount configuration files.
This Operator includes a [Molecule](https://molecule.readthedocs.io/en/stable/)-based test environment, which can be executed standalone in Docker (e.g. in CI or in a single Docker container anywhere), or inside any kind of Kubernetes cluster (e.g. Minikube).
| Name | Description | Default |
| ------------------------------ | -------------------------------------------------------- | ------- |
| extra_volumes | Specify extra volumes to add to the application pod | '' |
| web_extra_volume_mounts | Specify volume mounts to be added to Web container | '' |
| task_extra_volume_mounts | Specify volume mounts to be added to Task container | '' |
| ee_extra_volume_mounts | Specify volume mounts to be added to Execution container | '' |
You need to make sure you have Molecule installed before running the following commands. You can install Molecule with:
> :warning: The `ee_extra_volume_mounts` and `extra_volumes` will only take effect to the globally available Execution Environments. For custom `ee`, please [customize the Pod spec](https://docs.ansible.com/ansible-tower/latest/html/administration/external_execution_envs.html#customize-the-pod-spec).
```sh
#> pip install 'molecule[docker]'
```
Example configuration for ConfigMap
Running `molecule test` sets up a clean environment, builds the operator, runs all configured tests on an example operator instance, then tears down the environment (at least in the case of Docker).
#### Default execution environments from private registries
If you want to actively develop the operator, use `molecule converge`, which does everything but tear down the environment at the end.
In order to register default execution environments from private registries, the Custom Resource needs to know about the pull credentials. Those credentials should be stored as a secret and either specified as `ee_pull_credentials_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-ee-pull-credentials` . Instance initialization will register a `Container registry` type credential on the deployed instance and assign it to the registered default execution environments.
#### Testing in Docker
The secret should be formated as follows:
```sh
#> molecule test -s test-local
```
This environment is meant for headless testing (e.g. in a CI environment, or when making smaller changes which don't need to be verified through a web interface). It is difficult to test things like AWX's web UI or to connect other applications on your local machine to the services running inside the cluster, since it is inside a Docker container with no static IP address.
#### Testing in Minikube
```sh
#> minikube start --memory 8g --cpus 4
#> minikube addons enable ingress
#> molecule test -s test-minikube
```
[Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) is a more full-featured test environment running inside a full VM on your computer, with an assigned IP address. This makes it easier to test things like NodePort services and Ingress from outside the Kubernetes cluster (e.g. in a browser on your computer).
Once the operator is deployed, you can visit the AWX UI in your browser by following these steps:
1. Make sure you have an entry like `IP_ADDRESS example-awx.test` in your `/etc/hosts` file. (Get the IP address with `minikube ip`.)
2. Visit `http://example-awx.test/` in your browser. (Default admin login is `test`/`changeme`.)
Alternatively, you can also update the service `awx-service` in your namespace to use the type `NodePort` and use following command to get the URL to access your AWX instance:
```sh
#> minikube service <serviceName> -n <namespaceName> --url
```
### Generating a bundle
> :warning: operator-sdk version 0.19.4 is needed to run the following commands
If one has the Operator Lifecycle Manager (OLM) installed, the following steps is the process to generate the bundle that would nicely display in the OLM interface.
At the root of this directory:
1. Build and publish the operator
```
#> operator-sdk build registry.example.com/ansible/awx-operator:mytag
#> podman push registry.example.com/ansible/awx-operator:mytag
```
2. Build and publish the bundle
```
#> podman build . -f bundle.Dockerfile -t registry.example.com/ansible/awx-operator-bundle:mytag
#> podman push registry.example.com/ansible/awx-operator-bundle:mytag
```
3. Build and publish an index with your bundle in it
```
#> opm index add --bundles registry.example.com/ansible/awx-operator-bundle:mytag --tag registry.example.com/ansible/awx-operator-catalog:mytag
#> podman push registry.example.com/ansible/awx-operator-catalog:mytag
```
4. In your Kubernetes create a new CatalogSource pointing to `registry.example.com/ansible/awx-operator-catalog:mytag`
```
```yaml
---
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
apiVersion: v1
kind: Secret
metadata:
name: <catalogsource-name>
namespace: <namespace>
spec:
displayName: 'myoperatorhub'
image: registry.example.com/ansible/awx-operator-catalog:mytag
publisher: 'myoperatorhub'
sourceType: grpc
name: <resourcename>-ee-pull-credentials
namespace: <target namespace>
stringData:
url: <registry url. i.e. quay.io>
username: <username to connect as>
password: <password to connect with>
ssl_verify: <Optional attribute. Whether verify ssl connection or not. Accepted values "True" (default), "False" >
type: Opaque
```
Applying this template will do it. Once the CatalogSource is in a READY state, the bundle should be available on the OperatorHub tab (as part of the custom CatalogSource that just got added)
##### Control plane ee from private registry
The images listed in "ee_images" will be added as globally available Execution Environments. The "control_plane_ee_image" will be used to run project updates. In order to use a private image for any of these you'll need to use `image_pull_secret` to provide a k8s pull secret to access it. Currently the same secret is used for any of these images supplied at install time.
You can create `image_pull_secret`
```
kubectl create secret <resoucename>-cp-pull-credentials regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
```
If you need more control (for example, to set a namespace or a label on the new secret) then you can customise the Secret before storing it
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: <resoucename>-cp-pull-credentials
namespace: <target namespace>
data:
.dockerconfigjson: <base64 docker config>
type: kubernetes.io/dockerconfigjson
```
Example spec file extra-config
```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: <resourcename>-extra-config
namespace: <target namespace>
data:
ansible.cfg: |
[defaults]
remote_tmp = /tmp
[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
custom.py: |
INSIGHTS_URL_BASE = "example.org"
AWX_CLEANUP_PATHS = True
```
Example spec file for volumes and volume mounts
```yaml
---
spec:
...
ee_extra_volume_mounts: |
- name: ansible-cfg
mountPath: /etc/ansible/ansible.cfg
subPath: ansible.cfg
task_extra_volume_mounts: |
- name: custom-py
mountPath: /etc/tower/conf.d/custom.py
subPath: custom.py
extra_volumes: |
- name: ansible-cfg
configMap:
defaultMode: 420
items:
- key: ansible.cfg
path: ansible.cfg
name: <resourcename>-extra-config
- name: custom-py
configMap:
defaultMode: 420
items:
- key: custom.py
path: custom.py
name: <resourcename>-extra-config
```
> :warning: **Volume and VolumeMount names cannot contain underscores(_)**
#### Exporting Environment Variables to Containers
If you need to export custom environment variables to your containers.
| Name | Description | Default |
| ----------------------------- | -------------------------------------------------------- | ------- |
| task_extra_env | Environment variables to be added to Task container | '' |
| web_extra_env | Environment variables to be added to Web container | '' |
| ee_extra_env | Environment variables to be added to EE container | '' |
> :warning: The `ee_extra_env` will only take effect to the globally available Execution Environments. For custom `ee`, please [customize the Pod spec](https://docs.ansible.com/ansible-tower/latest/html/administration/external_execution_envs.html#customize-the-pod-spec).
Example configuration of environment variables
```yaml
spec:
task_extra_env: |
- name: MYCUSTOMVAR
value: foo
web_extra_env: |
- name: MYCUSTOMVAR
value: foo
ee_extra_env: |
- name: MYCUSTOMVAR
value: foo
```
#### Extra Settings
With`extra_settings`, you can pass multiple custom settings via the `awx-operator`. The parameter `extra_settings` will be appended to the `/etc/tower/settings.py` and can be an alternative to the `extra_volumes` parameter.
| Name | Description | Default |
| ----------------------------- | -------------------------------------------------------- | ------- |
| extra_settings | Extra settings | '' |
Example configuration of `extra_settings` parameter
```yaml
spec:
extra_settings:
- setting: MAX_PAGE_SIZE
value: "500"
- setting: AUTH_LDAP_BIND_DN
value: "cn=admin,dc=example,dc=com"
```
#### Service Account
If you need to modify some `ServiceAccount` proprieties
| Name | Description | Default |
| ----------------------------- | -------------------------------------------------------- | ------- |
| service_account_annotations | Annotations to the ServiceAccount | '' |
Example configuration of environment variables
```yaml
spec:
service_account_annotations: |
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME>
```
### Upgrading
To upgrade AWX, it is recommended to upgrade the awx-operator to the version that maps to the desired version of AWX. To find the version of AWX that will be installed by the awx-operator by default, check the version specified in the `image_version` variable in `roles/installer/defaults/main.yml` for that particular release.
Apply the awx-operator.yml for that release to upgrade the operator, and in turn also upgrade your AWX deployment.
## Contributing
Please visit [our contributing guidelines](https://github.com/ansible/awx-operator/blob/devel/CONTRIBUTING.md).
5. Enjoy
## Release Process
There are a few moving parts to this project:
1. The Docker image which powers AWX Operator.
2. The `awx-operator.yaml` Kubernetes manifest file which initially deploys the Operator into a cluster.
* The `awx-operator` container image which powers AWX Operator
* The `awx-operator.yaml` file, which initially deploys the Operator
* The ClusterServiceVersion (CSV), which is generated as part of the bundle and needed for the olm-catalog
Each of these must be appropriately built in preparation for a new tag:
### Build a new release
Run the following command inside this directory:
```sh
#> operator-sdk build quay.io/ansible/awx-operator:$VERSION
```
Then push the generated image to Docker Hub:
```sh
#> docker push quay.io/ansible/awx-operator:$VERSION
```
### Build a new version of the operator yaml file
### Update version and files
Update the awx-operator version:
@@ -528,20 +768,56 @@ Once the version has been updated, run from the root of the repo:
#> ansible-playbook ansible/chain-operator-files.yml
```
Generate the olm-catalog bundle.
```bash
$ operator-sdk generate bundle --operator-name awx-operator --version <new_tag>
```
> This should be done with operator-sdk v0.19.4.
> It is a good idea to use the [build script](./build.sh) at this point to build the catalog and test out installing it in Operator Hub.
### Verify Functionality
Run the following command inside this directory:
```sh
#> operator-sdk build quay.io/<user>/awx-operator:<new-version>
```
Then push the generated image to Docker Hub:
```sh
#> docker push quay.io/<user>/awx-operator:<new-version>
```
After it is built, test it on a local cluster:
```sh
#> minikube start --memory 6g --cpus 4
#> minikube addons enable ingress
#> ansible-playbook ansible/deploy-operator.yml
#> ansible-playbook ansible/deploy-operator.yml -e operator_image=quay.io/<user>/awx-operator -e operator_version=<new-version> -e pull_policy=Always
#> kubectl create namespace example-awx
#> ansible-playbook ansible/instantiate-awx-deployment.yml -e tower_namespace=example-awx
#> <test everything>
#> ansible-playbook ansible/instantiate-awx-deployment.yml -e namespace=example-awx -e image=quay.io/<user>/awx -e service_type=nodeport
#> # Verify that the awx-task and awx-web containers are launched
#> # with the right version of the awx image
#> minikube delete
```
If everything works, commit the updated version, then tag a new repository release with the same tag as the Docker image pushed earlier.
### Update changelog
Generate a list of commits between the versions and add it to the [changelog](./CHANGELOG.md).
```sh
#> git log --no-merges --pretty="- %s (%an) - %h " <old_tag>..<new_tag>
```
### Commit / Create Release
If everything works, commit the updated version, then [publish a new release](https://github.com/ansible/awx-operator/releases/new) using the same version you used in `ansible/group_vars/all`.
After creating the release, [this GitHub Workflow](https://github.com/ansible/awx-operator/blob/devel/.github/workflows/release.yaml) will run and publish the new image to quay.io.
## Author

View File

@@ -3,15 +3,15 @@
hosts: localhost
collections:
- community.general
- community.docker
tasks:
- name: Build and (optionally) push operator image
docker_image:
name: "{{ operator_image }}:{{ operator_version }}"
pull: no
push: "{{ push_image | bool }}"
source: "build"
push: "{{ push_image }}"
build:
dockerfile: "build/Dockerfile"
path: "../"
force: yes
force_source: "yes"

View File

@@ -6,12 +6,24 @@
gather_facts: false
tasks:
- name: Template CRD
- name: Template AWX CRD
template:
src: crd.yml.j2
dest: "{{ playbook_dir }}/../deploy/crds/awx_v1beta1_crd.yaml"
mode: '0644'
- name: Template AWXBackup CRD
template:
src: awxbackup_crd.yml.j2
dest: "{{ playbook_dir }}/../deploy/crds/awxbackup_v1beta1_crd.yaml"
mode: '0644'
- name: Template AWXRestore CRD
template:
src: awxrestore_crd.yml.j2
dest: "{{ playbook_dir }}/../deploy/crds/awxrestore_v1beta1_crd.yaml"
mode: '0644'
- name: Template awx-operator.yaml
template:
src: awx-operator.yaml.j2

View File

@@ -1,6 +1,6 @@
---
- name: Reconstruct awx-operator.yaml
include: chain-operator-files.yml
import_playbook: chain-operator-files.yml
- name: Deploy Operator
hosts: localhost
@@ -9,7 +9,7 @@
obliterate: no
collections:
- community.kubernetes
- kubernetes.core
tasks:
- name: Obliterate Operator

View File

@@ -1,3 +1,4 @@
operator_image: quay.io/ansible/awx-operator
operator_version: 0.8.0
operator_version: 0.12.0
pull_policy: Always
ansible_debug_logs: "false"

View File

@@ -3,13 +3,13 @@
hosts: localhost
collections:
- community.kubernetes
- kubernetes.core
tasks:
- name: Deploy AWX
k8s:
state: "{{ state | default('present') }}"
namespace: "{{ tower_namespace | default('default') }}"
namespace: "{{ namespace | default('default') }}"
apply: yes
wait: yes
definition:
@@ -18,12 +18,14 @@
metadata:
name: awx
spec:
tower_admin_user: test
tower_admin_email: test@example.com
tower_ingress_type: "{{ tower_ingress_type | default(omit) }}" # Either Route, Ingress or LoadBalancer
tower_image: "{{ tower_image | default(omit) }}"
admin_user: admin
admin_email: admin@localhost
service_type: "{{ service_type | default(omit) }}" # Either clusterIP, Loadbalancer or NodePort
ingress_type: "{{ ingress_type | default(omit) }}" # Either none, Ingress, Route
image: "{{ image | default(omit) }}"
image_version: "{{ image_version | default(omit) }}"
development_mode: "{{ development_mode | default(omit) | bool }}"
tower_image_pull_policy: "{{ tower_image_pull_policy | default(omit) }}"
# tower_ee_images:
image_pull_policy: "{{ image_pull_policy | default(omit) }}"
# ee_images:
# - name: test-ee
# image: quay.io/<user>/awx-ee

View File

@@ -3,6 +3,10 @@
# Update templates under ansible/templates/
{% include 'crd.yml.j2' %}
{% include 'awxbackup_crd.yml.j2' %}
{% include 'awxrestore_crd.yml.j2' %}
{% include 'role.yml.j2' %}
{% include 'role_binding.yml.j2' %}

View File

@@ -0,0 +1,78 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxbackups.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXBackup
listKind: AWXBackupList
plural: awxbackups
singular: awxbackup
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
description: Schema validation for the AWXBackup CRD
properties:
spec:
type: object
required:
- deployment_name
properties:
deployment_name:
description: Name of the deployment to be backed up
type: string
backup_pvc:
description: Name of the PVC to be used for storing the backup
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_storage_requirements:
description: Storage requirements for the PostgreSQL container
type: string
backup_storage_class:
description: Storage class to use when creating PVC for backup
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
status:
type: object
properties:
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
backupDirectory:
description: Backup directory name on the specified pvc
type: string
backupClaim:
description: Backup persistent volume claim
type: string

View File

@@ -0,0 +1,79 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxrestores.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXRestore
listKind: AWXRestoreList
plural: awxrestores
singular: awxrestore
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
description: Schema validation for the AWXRestore CRD
properties:
spec:
type: object
properties:
backup_source:
description: Backup source
type: string
enum:
- CR
- PVC
deployment_name:
description: Name of the deployment to be restored to
type: string
backup_name:
description: AWXBackup object name
type: string
backup_pvc:
description: Name of the PVC to be restored from, set as a status found on the awxbackup object (backupClaim)
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_dir:
description: Backup directory name, set as a status found on the awxbackup object (backupDirectory)
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
status:
type: object
properties:
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
restoreComplete:
description: Restore process complete
type: boolean

View File

@@ -26,39 +26,58 @@ spec:
deployment_type:
description: Name of the deployment type
type: string
tower_task_privileged:
kind:
description: Kind of the deployment type
type: string
api_version:
description: apiVersion of the deployment type
type: string
task_privileged:
description: If a privileged security context should be enabled
type: boolean
default: false
tower_admin_user:
admin_user:
description: Username to use for the admin account
type: string
default: admin
tower_hostname:
hostname:
description: The hostname of the instance
type: string
tower_admin_email:
admin_email:
description: The admin user email
type: string
tower_admin_password_secret:
admin_password_secret:
description: Secret where the admin password can be found
type: string
tower_postgres_configuration_secret:
postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
tower_old_postgres_configuration_secret:
old_postgres_configuration_secret:
description: Secret where the old database configuration can be found for data migration
type: string
tower_secret_key_secret:
postgres_label_selector:
description: Label selector used to identify postgres pod for data migration
type: string
secret_key_secret:
description: Secret where the secret key can be found
type: string
tower_broadcast_websocket_secret:
broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
tower_extra_volumes:
extra_volumes:
description: Specify extra volumes to add to the application pod
type: string
tower_ingress_type:
service_type:
description: The service type to be used on the deployed instance
type: string
enum:
- LoadBalancer
- loadbalancer
- ClusterIP
- clusterip
- NodePort
- nodeport
ingress_type:
description: The ingress type to use to reach the deployed instance
type: string
enum:
@@ -67,32 +86,30 @@ spec:
- ingress
- Route
- route
- LoadBalancer
- loadbalancer
tower_ingress_annotations:
description: Annotations to add to the ingress
ingress_annotations:
description: Annotations to add to the Ingress Controller
type: string
tower_ingress_tls_secret:
description: Secret where the ingress TLS secret can be found
ingress_tls_secret:
description: Secret where the Ingress TLS secret can be found
type: string
tower_loadbalancer_annotations:
loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
tower_loadbalancer_protocol:
loadbalancer_protocol:
description: Protocol to use for the loadbalancer
type: string
default: http
enum:
- http
- https
tower_loadbalancer_port:
loadbalancer_port:
description: Port to use for the loadbalancer
type: integer
default: 80
tower_route_host:
route_host:
description: The DNS to use to points to the instance
type: string
tower_route_tls_termination_mechanism:
route_tls_termination_mechanism:
description: The secure TLS termination mechanism to use
type: string
default: Edge
@@ -101,19 +118,25 @@ spec:
- edge
- Passthrough
- passthrough
tower_route_tls_secret:
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
tower_node_selector:
description: nodeSelector for the AWX pods
node_selector:
description: nodeSelector for the pods
type: string
tower_tolerations:
description: node tolerations for the AWX pods
service_labels:
description: Additional labels to apply to the service
type: string
tower_image:
tolerations:
description: node tolerations for the pods
type: string
image:
description: Registry path to the application container to use
type: string
tower_ee_images:
image_version:
description: Application container image version to use
type: string
ee_images:
description: Registry path to the Execution Environment container to use
type: array
items:
@@ -123,7 +146,13 @@ spec:
type: string
image:
type: string
tower_image_pull_policy:
control_plane_ee_image:
description: Registry path to the Execution Environment container image to use on control plane pods
type: string
ee_pull_credentials_secret:
description: Secret where pull credentials for registered ees can be found
type: string
image_pull_policy:
description: The image pull policy
type: string
default: IfNotPresent
@@ -134,10 +163,10 @@ spec:
- never
- IfNotPresent
- ifnotpresent
tower_image_pull_secret:
image_pull_secret:
description: The image pull secret
type: string
tower_task_resource_requirements:
task_resource_requirements:
description: Resource requirements for the task container
properties:
requests:
@@ -159,7 +188,7 @@ spec:
type: string
type: object
type: object
tower_web_resource_requirements:
web_resource_requirements:
description: Resource requirements for the web container
properties:
requests:
@@ -181,51 +210,8 @@ spec:
type: string
type: object
type: object
tower_replicas:
description: Number of instance replicas
type: integer
default: 1
format: int32
tower_garbage_collect_secrets:
description: Whether or not to remove secrets upon instance removal
default: false
type: boolean
tower_create_preload_data:
description: Whether or not to preload data upon Tower instance creation
default: true
type: boolean
tower_task_args:
type: array
items:
type: string
tower_task_command:
type: array
items:
type: string
tower_web_args:
type: array
items:
type: string
tower_web_command:
type: array
items:
type: string
tower_task_extra_env:
type: string
tower_web_extra_env:
type: string
tower_task_extra_volume_mounts:
type: string
tower_web_extra_volume_mounts:
type: string
tower_redis_image:
description: Registry path to the redis container to use
type: string
tower_postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
tower_postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
requests:
properties:
@@ -246,10 +232,113 @@ spec:
type: string
type: object
type: object
tower_postgres_storage_class:
service_account_annotations:
description: ServiceAccount annotations
type: string
replicas:
description: Number of instance replicas
type: integer
default: 1
format: int32
garbage_collect_secrets:
description: Whether or not to remove secrets upon instance removal
default: false
type: boolean
create_preload_data:
description: Whether or not to preload data upon instance creation
default: true
type: boolean
task_args:
type: array
items:
type: string
task_command:
type: array
items:
type: string
web_args:
type: array
items:
type: string
web_command:
type: array
items:
type: string
task_extra_env:
type: string
web_extra_env:
type: string
ee_extra_env:
type: string
ee_extra_volume_mounts:
description: Specify volume mounts to be added to Execution container
type: string
task_extra_volume_mounts:
description: Specify volume mounts to be added to Task container
type: string
web_extra_volume_mounts:
description: Specify volume mounts to be added to the Web container
type: string
redis_image:
description: Registry path to the redis container to use
type: string
redis_image_version:
description: Redis container image version to use
type: string
init_container_image:
description: Registry path to the init container to use
type: string
init_container_image_version:
description: Init container image version to use
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
postgres_selector:
description: nodeSelector for the Postgres pods
type: string
postgres_tolerations:
description: node tolerations for the Postgres pods
type: string
postgres_storage_requirements:
description: Storage requirements for the PostgreSQL container
properties:
requests:
properties:
storage:
type: string
type: object
limits:
properties:
storage:
type: string
type: object
type: object
postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
type: object
type: object
postgres_storage_class:
description: Storage class to use for the PostgreSQL PVC
type: string
tower_postgres_data_path:
postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
ca_trust_bundle:
@@ -261,49 +350,71 @@ spec:
ldap_cacert_secret:
description: Secret where can be found the LDAP trusted Certificate Authority Bundle
type: string
tower_projects_persistence:
bundle_cacert_secret:
description: Secret where can be found the trusted Certificate Authority Bundle
type: string
projects_persistence:
description: Whether or not the /var/lib/projects directory will be persistent
default: false
type: boolean
tower_projects_use_existing_claim:
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
type: string
enum:
- _Yes_
- _No_
tower_projects_existing_claim:
projects_existing_claim:
description: PersistentVolumeClaim to mount /var/lib/projects directory
type: string
tower_projects_storage_class:
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
tower_projects_storage_size:
projects_storage_size:
description: Size for the /var/lib/projects PersistentVolumeClaim
default: 8Gi
type: string
tower_projects_storage_access_mode:
projects_storage_access_mode:
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
default: ReadWriteMany
type: string
extra_settings:
description: Extra settings to specify for the API
items:
properties:
setting:
type: string
value:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
type: object
status:
properties:
towerURL:
URL:
description: URL to access the deployed instance
type: string
towerAdminUser:
adminUser:
description: Admin user of the deployed instance
type: string
towerAdminPasswordSecret:
description: Admin password of the deployed instance
adminPasswordSecret:
description: Admin password secret name of the deployed instance
type: string
towerMigratedFromSecret:
description: The secret used for migrating an old Tower.
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
towerVersion:
broadcastWebsocketSecret:
description: Broadcast websocket secret name of the deployed instance
type: string
secretKeySecret:
description: Secret key secret name of the deployed instance
type: string
migratedFromSecret:
description: The secret used for migrating an old instance.
type: string
version:
description: Version of the deployed instance
type: string
towerImage:
image:
description: URL of the image used for the deployed instance
type: string
conditions:

View File

@@ -33,6 +33,10 @@ spec:
value: awx-operator
- name: ANSIBLE_GATHERING
value: explicit
- name: OPERATOR_VERSION
value: "{{ operator_version }}"
- name: ANSIBLE_DEBUG_LOGS
value: "{{ ansible_debug_logs|lower | default('false'|lower) }}"
livenessProbe:
httpGet:
path: /healthz

View File

@@ -59,6 +59,7 @@ rules:
- apps
resources:
- deployments/scale
- statefulsets/scale
verbs:
- patch
- apiGroups:
@@ -78,5 +79,7 @@ rules:
- awx.ansible.com
resources:
- '*'
- awxbackups
- awxrestores
verbs:
- '*'

View File

@@ -28,39 +28,58 @@ spec:
deployment_type:
description: Name of the deployment type
type: string
tower_task_privileged:
kind:
description: Kind of the deployment type
type: string
api_version:
description: apiVersion of the deployment type
type: string
task_privileged:
description: If a privileged security context should be enabled
type: boolean
default: false
tower_admin_user:
admin_user:
description: Username to use for the admin account
type: string
default: admin
tower_hostname:
hostname:
description: The hostname of the instance
type: string
tower_admin_email:
admin_email:
description: The admin user email
type: string
tower_admin_password_secret:
admin_password_secret:
description: Secret where the admin password can be found
type: string
tower_postgres_configuration_secret:
postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
tower_old_postgres_configuration_secret:
old_postgres_configuration_secret:
description: Secret where the old database configuration can be found for data migration
type: string
tower_secret_key_secret:
postgres_label_selector:
description: Label selector used to identify postgres pod for data migration
type: string
secret_key_secret:
description: Secret where the secret key can be found
type: string
tower_broadcast_websocket_secret:
broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
tower_extra_volumes:
extra_volumes:
description: Specify extra volumes to add to the application pod
type: string
tower_ingress_type:
service_type:
description: The service type to be used on the deployed instance
type: string
enum:
- LoadBalancer
- loadbalancer
- ClusterIP
- clusterip
- NodePort
- nodeport
ingress_type:
description: The ingress type to use to reach the deployed instance
type: string
enum:
@@ -69,32 +88,30 @@ spec:
- ingress
- Route
- route
- LoadBalancer
- loadbalancer
tower_ingress_annotations:
description: Annotations to add to the ingress
ingress_annotations:
description: Annotations to add to the Ingress Controller
type: string
tower_ingress_tls_secret:
description: Secret where the ingress TLS secret can be found
ingress_tls_secret:
description: Secret where the Ingress TLS secret can be found
type: string
tower_loadbalancer_annotations:
loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
tower_loadbalancer_protocol:
loadbalancer_protocol:
description: Protocol to use for the loadbalancer
type: string
default: http
enum:
- http
- https
tower_loadbalancer_port:
loadbalancer_port:
description: Port to use for the loadbalancer
type: integer
default: 80
tower_route_host:
route_host:
description: The DNS to use to points to the instance
type: string
tower_route_tls_termination_mechanism:
route_tls_termination_mechanism:
description: The secure TLS termination mechanism to use
type: string
default: Edge
@@ -103,19 +120,25 @@ spec:
- edge
- Passthrough
- passthrough
tower_route_tls_secret:
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
tower_node_selector:
description: nodeSelector for the AWX pods
node_selector:
description: nodeSelector for the pods
type: string
tower_tolerations:
description: node tolerations for the AWX pods
service_labels:
description: Additional labels to apply to the service
type: string
tower_image:
tolerations:
description: node tolerations for the pods
type: string
image:
description: Registry path to the application container to use
type: string
tower_ee_images:
image_version:
description: Application container image version to use
type: string
ee_images:
description: Registry path to the Execution Environment container to use
type: array
items:
@@ -125,7 +148,13 @@ spec:
type: string
image:
type: string
tower_image_pull_policy:
control_plane_ee_image:
description: Registry path to the Execution Environment container image to use on control plane pods
type: string
ee_pull_credentials_secret:
description: Secret where pull credentials for registered ees can be found
type: string
image_pull_policy:
description: The image pull policy
type: string
default: IfNotPresent
@@ -136,10 +165,10 @@ spec:
- never
- IfNotPresent
- ifnotpresent
tower_image_pull_secret:
image_pull_secret:
description: The image pull secret
type: string
tower_task_resource_requirements:
task_resource_requirements:
description: Resource requirements for the task container
properties:
requests:
@@ -161,7 +190,7 @@ spec:
type: string
type: object
type: object
tower_web_resource_requirements:
web_resource_requirements:
description: Resource requirements for the web container
properties:
requests:
@@ -183,51 +212,8 @@ spec:
type: string
type: object
type: object
tower_replicas:
description: Number of instance replicas
type: integer
default: 1
format: int32
tower_garbage_collect_secrets:
description: Whether or not to remove secrets upon instance removal
default: false
type: boolean
tower_create_preload_data:
description: Whether or not to preload data upon Tower instance creation
default: true
type: boolean
tower_task_args:
type: array
items:
type: string
tower_task_command:
type: array
items:
type: string
tower_web_args:
type: array
items:
type: string
tower_web_command:
type: array
items:
type: string
tower_task_extra_env:
type: string
tower_web_extra_env:
type: string
tower_task_extra_volume_mounts:
type: string
tower_web_extra_volume_mounts:
type: string
tower_redis_image:
description: Registry path to the redis container to use
type: string
tower_postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
tower_postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
requests:
properties:
@@ -248,10 +234,113 @@ spec:
type: string
type: object
type: object
tower_postgres_storage_class:
service_account_annotations:
description: ServiceAccount annotations
type: string
replicas:
description: Number of instance replicas
type: integer
default: 1
format: int32
garbage_collect_secrets:
description: Whether or not to remove secrets upon instance removal
default: false
type: boolean
create_preload_data:
description: Whether or not to preload data upon instance creation
default: true
type: boolean
task_args:
type: array
items:
type: string
task_command:
type: array
items:
type: string
web_args:
type: array
items:
type: string
web_command:
type: array
items:
type: string
task_extra_env:
type: string
web_extra_env:
type: string
ee_extra_env:
type: string
ee_extra_volume_mounts:
description: Specify volume mounts to be added to Execution container
type: string
task_extra_volume_mounts:
description: Specify volume mounts to be added to Task container
type: string
web_extra_volume_mounts:
description: Specify volume mounts to be added to the Web container
type: string
redis_image:
description: Registry path to the redis container to use
type: string
redis_image_version:
description: Redis container image version to use
type: string
init_container_image:
description: Registry path to the init container to use
type: string
init_container_image_version:
description: Init container image version to use
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
postgres_selector:
description: nodeSelector for the Postgres pods
type: string
postgres_tolerations:
description: node tolerations for the Postgres pods
type: string
postgres_storage_requirements:
description: Storage requirements for the PostgreSQL container
properties:
requests:
properties:
storage:
type: string
type: object
limits:
properties:
storage:
type: string
type: object
type: object
postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
type: object
type: object
postgres_storage_class:
description: Storage class to use for the PostgreSQL PVC
type: string
tower_postgres_data_path:
postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
ca_trust_bundle:
@@ -263,49 +352,71 @@ spec:
ldap_cacert_secret:
description: Secret where can be found the LDAP trusted Certificate Authority Bundle
type: string
tower_projects_persistence:
bundle_cacert_secret:
description: Secret where can be found the trusted Certificate Authority Bundle
type: string
projects_persistence:
description: Whether or not the /var/lib/projects directory will be persistent
default: false
type: boolean
tower_projects_use_existing_claim:
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
type: string
enum:
- _Yes_
- _No_
tower_projects_existing_claim:
projects_existing_claim:
description: PersistentVolumeClaim to mount /var/lib/projects directory
type: string
tower_projects_storage_class:
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
tower_projects_storage_size:
projects_storage_size:
description: Size for the /var/lib/projects PersistentVolumeClaim
default: 8Gi
type: string
tower_projects_storage_access_mode:
projects_storage_access_mode:
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
default: ReadWriteMany
type: string
extra_settings:
description: Extra settings to specify for the API
items:
properties:
setting:
type: string
value:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
type: object
status:
properties:
towerURL:
URL:
description: URL to access the deployed instance
type: string
towerAdminUser:
adminUser:
description: Admin user of the deployed instance
type: string
towerAdminPasswordSecret:
description: Admin password of the deployed instance
adminPasswordSecret:
description: Admin password secret name of the deployed instance
type: string
towerMigratedFromSecret:
description: The secret used for migrating an old Tower.
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
towerVersion:
broadcastWebsocketSecret:
description: Broadcast websocket secret name of the deployed instance
type: string
secretKeySecret:
description: Secret key secret name of the deployed instance
type: string
migratedFromSecret:
description: The secret used for migrating an old instance.
type: string
version:
description: Version of the deployed instance
type: string
towerImage:
image:
description: URL of the image used for the deployed instance
type: string
conditions:
@@ -325,6 +436,165 @@ spec:
type: object
type: object
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxbackups.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXBackup
listKind: AWXBackupList
plural: awxbackups
singular: awxbackup
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
description: Schema validation for the AWXBackup CRD
properties:
spec:
type: object
required:
- deployment_name
properties:
deployment_name:
description: Name of the deployment to be backed up
type: string
backup_pvc:
description: Name of the PVC to be used for storing the backup
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_storage_requirements:
description: Storage requirements for the PostgreSQL container
type: string
backup_storage_class:
description: Storage class to use when creating PVC for backup
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
status:
type: object
properties:
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
backupDirectory:
description: Backup directory name on the specified pvc
type: string
backupClaim:
description: Backup persistent volume claim
type: string
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxrestores.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXRestore
listKind: AWXRestoreList
plural: awxrestores
singular: awxrestore
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
description: Schema validation for the AWXRestore CRD
properties:
spec:
type: object
properties:
backup_source:
description: Backup source
type: string
enum:
- CR
- PVC
deployment_name:
description: Name of the deployment to be restored to
type: string
backup_name:
description: AWXBackup object name
type: string
backup_pvc:
description: Name of the PVC to be restored from, set as a status found on the awxbackup object (backupClaim)
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_dir:
description: Backup directory name, set as a status found on the awxbackup object (backupDirectory)
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
status:
type: object
properties:
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
restoreComplete:
description: Restore process complete
type: boolean
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
@@ -386,6 +656,7 @@ rules:
- apps
resources:
- deployments/scale
- statefulsets/scale
verbs:
- patch
- apiGroups:
@@ -405,6 +676,8 @@ rules:
- awx.ansible.com
resources:
- '*'
- awxbackups
- awxrestores
verbs:
- '*'
@@ -447,7 +720,7 @@ spec:
serviceAccountName: awx-operator
containers:
- name: awx-operator
image: "quay.io/ansible/awx-operator:0.8.0"
image: "quay.io/ansible/awx-operator:0.12.0"
imagePullPolicy: "Always"
volumeMounts:
- mountPath: /tmp/ansible-operator/runner
@@ -464,6 +737,10 @@ spec:
value: awx-operator
- name: ANSIBLE_GATHERING
value: explicit
- name: OPERATOR_VERSION
value: "0.12.0"
- name: ANSIBLE_DEBUG_LOGS
value: "false"
livenessProbe:
httpGet:
path: /healthz

View File

@@ -26,39 +26,58 @@ spec:
deployment_type:
description: Name of the deployment type
type: string
tower_task_privileged:
kind:
description: Kind of the deployment type
type: string
api_version:
description: apiVersion of the deployment type
type: string
task_privileged:
description: If a privileged security context should be enabled
type: boolean
default: false
tower_admin_user:
admin_user:
description: Username to use for the admin account
type: string
default: admin
tower_hostname:
hostname:
description: The hostname of the instance
type: string
tower_admin_email:
admin_email:
description: The admin user email
type: string
tower_admin_password_secret:
admin_password_secret:
description: Secret where the admin password can be found
type: string
tower_postgres_configuration_secret:
postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
tower_old_postgres_configuration_secret:
old_postgres_configuration_secret:
description: Secret where the old database configuration can be found for data migration
type: string
tower_secret_key_secret:
postgres_label_selector:
description: Label selector used to identify postgres pod for data migration
type: string
secret_key_secret:
description: Secret where the secret key can be found
type: string
tower_broadcast_websocket_secret:
broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
tower_extra_volumes:
extra_volumes:
description: Specify extra volumes to add to the application pod
type: string
tower_ingress_type:
service_type:
description: The service type to be used on the deployed instance
type: string
enum:
- LoadBalancer
- loadbalancer
- ClusterIP
- clusterip
- NodePort
- nodeport
ingress_type:
description: The ingress type to use to reach the deployed instance
type: string
enum:
@@ -67,32 +86,30 @@ spec:
- ingress
- Route
- route
- LoadBalancer
- loadbalancer
tower_ingress_annotations:
description: Annotations to add to the ingress
ingress_annotations:
description: Annotations to add to the Ingress Controller
type: string
tower_ingress_tls_secret:
description: Secret where the ingress TLS secret can be found
ingress_tls_secret:
description: Secret where the Ingress TLS secret can be found
type: string
tower_loadbalancer_annotations:
loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
tower_loadbalancer_protocol:
loadbalancer_protocol:
description: Protocol to use for the loadbalancer
type: string
default: http
enum:
- http
- https
tower_loadbalancer_port:
loadbalancer_port:
description: Port to use for the loadbalancer
type: integer
default: 80
tower_route_host:
route_host:
description: The DNS to use to points to the instance
type: string
tower_route_tls_termination_mechanism:
route_tls_termination_mechanism:
description: The secure TLS termination mechanism to use
type: string
default: Edge
@@ -101,19 +118,25 @@ spec:
- edge
- Passthrough
- passthrough
tower_route_tls_secret:
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
tower_node_selector:
description: nodeSelector for the AWX pods
node_selector:
description: nodeSelector for the pods
type: string
tower_tolerations:
description: node tolerations for the AWX pods
service_labels:
description: Additional labels to apply to the service
type: string
tower_image:
tolerations:
description: node tolerations for the pods
type: string
image:
description: Registry path to the application container to use
type: string
tower_ee_images:
image_version:
description: Application container image version to use
type: string
ee_images:
description: Registry path to the Execution Environment container to use
type: array
items:
@@ -123,7 +146,13 @@ spec:
type: string
image:
type: string
tower_image_pull_policy:
control_plane_ee_image:
description: Registry path to the Execution Environment container image to use on control plane pods
type: string
ee_pull_credentials_secret:
description: Secret where pull credentials for registered ees can be found
type: string
image_pull_policy:
description: The image pull policy
type: string
default: IfNotPresent
@@ -134,10 +163,10 @@ spec:
- never
- IfNotPresent
- ifnotpresent
tower_image_pull_secret:
image_pull_secret:
description: The image pull secret
type: string
tower_task_resource_requirements:
task_resource_requirements:
description: Resource requirements for the task container
properties:
requests:
@@ -159,7 +188,7 @@ spec:
type: string
type: object
type: object
tower_web_resource_requirements:
web_resource_requirements:
description: Resource requirements for the web container
properties:
requests:
@@ -181,51 +210,8 @@ spec:
type: string
type: object
type: object
tower_replicas:
description: Number of instance replicas
type: integer
default: 1
format: int32
tower_garbage_collect_secrets:
description: Whether or not to remove secrets upon instance removal
default: false
type: boolean
tower_create_preload_data:
description: Whether or not to preload data upon Tower instance creation
default: true
type: boolean
tower_task_args:
type: array
items:
type: string
tower_task_command:
type: array
items:
type: string
tower_web_args:
type: array
items:
type: string
tower_web_command:
type: array
items:
type: string
tower_task_extra_env:
type: string
tower_web_extra_env:
type: string
tower_task_extra_volume_mounts:
type: string
tower_web_extra_volume_mounts:
type: string
tower_redis_image:
description: Registry path to the redis container to use
type: string
tower_postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
tower_postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
requests:
properties:
@@ -246,10 +232,113 @@ spec:
type: string
type: object
type: object
tower_postgres_storage_class:
service_account_annotations:
description: ServiceAccount annotations
type: string
replicas:
description: Number of instance replicas
type: integer
default: 1
format: int32
garbage_collect_secrets:
description: Whether or not to remove secrets upon instance removal
default: false
type: boolean
create_preload_data:
description: Whether or not to preload data upon instance creation
default: true
type: boolean
task_args:
type: array
items:
type: string
task_command:
type: array
items:
type: string
web_args:
type: array
items:
type: string
web_command:
type: array
items:
type: string
task_extra_env:
type: string
web_extra_env:
type: string
ee_extra_env:
type: string
ee_extra_volume_mounts:
description: Specify volume mounts to be added to Execution container
type: string
task_extra_volume_mounts:
description: Specify volume mounts to be added to Task container
type: string
web_extra_volume_mounts:
description: Specify volume mounts to be added to the Web container
type: string
redis_image:
description: Registry path to the redis container to use
type: string
redis_image_version:
description: Redis container image version to use
type: string
init_container_image:
description: Registry path to the init container to use
type: string
init_container_image_version:
description: Init container image version to use
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
postgres_selector:
description: nodeSelector for the Postgres pods
type: string
postgres_tolerations:
description: node tolerations for the Postgres pods
type: string
postgres_storage_requirements:
description: Storage requirements for the PostgreSQL container
properties:
requests:
properties:
storage:
type: string
type: object
limits:
properties:
storage:
type: string
type: object
type: object
postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
type: object
type: object
postgres_storage_class:
description: Storage class to use for the PostgreSQL PVC
type: string
tower_postgres_data_path:
postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
ca_trust_bundle:
@@ -261,49 +350,71 @@ spec:
ldap_cacert_secret:
description: Secret where can be found the LDAP trusted Certificate Authority Bundle
type: string
tower_projects_persistence:
bundle_cacert_secret:
description: Secret where can be found the trusted Certificate Authority Bundle
type: string
projects_persistence:
description: Whether or not the /var/lib/projects directory will be persistent
default: false
type: boolean
tower_projects_use_existing_claim:
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
type: string
enum:
- _Yes_
- _No_
tower_projects_existing_claim:
projects_existing_claim:
description: PersistentVolumeClaim to mount /var/lib/projects directory
type: string
tower_projects_storage_class:
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
tower_projects_storage_size:
projects_storage_size:
description: Size for the /var/lib/projects PersistentVolumeClaim
default: 8Gi
type: string
tower_projects_storage_access_mode:
projects_storage_access_mode:
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
default: ReadWriteMany
type: string
extra_settings:
description: Extra settings to specify for the API
items:
properties:
setting:
type: string
value:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
type: object
status:
properties:
towerURL:
URL:
description: URL to access the deployed instance
type: string
towerAdminUser:
adminUser:
description: Admin user of the deployed instance
type: string
towerAdminPasswordSecret:
description: Admin password of the deployed instance
adminPasswordSecret:
description: Admin password secret name of the deployed instance
type: string
towerMigratedFromSecret:
description: The secret used for migrating an old Tower.
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
towerVersion:
broadcastWebsocketSecret:
description: Broadcast websocket secret name of the deployed instance
type: string
secretKeySecret:
description: Secret key secret name of the deployed instance
type: string
migratedFromSecret:
description: The secret used for migrating an old instance.
type: string
version:
description: Version of the deployed instance
type: string
towerImage:
image:
description: URL of the image used for the deployed instance
type: string
conditions:

View File

@@ -5,13 +5,19 @@ metadata:
name: example-awx
namespace: example-awx
spec:
service_account_annotations: |
foo: bar
deployment_type: awx
tower_ingress_type: ingress
tower_web_resource_requirements:
ingress_type: ingress
web_resource_requirements:
requests:
cpu: 500m
memory: 128M
tower_task_resource_requirements:
task_resource_requirements:
requests:
cpu: 500m
memory: 128M
ee_resource_requirements:
requests:
cpu: 200m
memory: 64M

View File

@@ -0,0 +1,78 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxbackups.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXBackup
listKind: AWXBackupList
plural: awxbackups
singular: awxbackup
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
description: Schema validation for the AWXBackup CRD
properties:
spec:
type: object
required:
- deployment_name
properties:
deployment_name:
description: Name of the deployment to be backed up
type: string
backup_pvc:
description: Name of the PVC to be used for storing the backup
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_storage_requirements:
description: Storage requirements for the PostgreSQL container
type: string
backup_storage_class:
description: Storage class to use when creating PVC for backup
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
status:
type: object
properties:
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
backupDirectory:
description: Backup directory name on the specified pvc
type: string
backupClaim:
description: Backup persistent volume claim
type: string

View File

@@ -0,0 +1,79 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxrestores.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXRestore
listKind: AWXRestoreList
plural: awxrestores
singular: awxrestore
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
description: Schema validation for the AWXRestore CRD
properties:
spec:
type: object
properties:
backup_source:
description: Backup source
type: string
enum:
- CR
- PVC
deployment_name:
description: Name of the deployment to be restored to
type: string
backup_name:
description: AWXBackup object name
type: string
backup_pvc:
description: Name of the PVC to be restored from, set as a status found on the awxbackup object (backupClaim)
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_dir:
description: Backup directory name, set as a status found on the awxbackup object (backupDirectory)
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
status:
type: object
properties:
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
restoreComplete:
description: Restore process complete
type: boolean

View File

@@ -13,14 +13,21 @@ metadata:
},
"spec": {
"deployment_type": "awx",
"tower_ingress_type": "ingress",
"tower_task_resource_requirements": {
"ee_resource_requirements": {
"requests": {
"cpu": "200m",
"memory": "64M"
}
},
"ingress_type": "ingress",
"service_account_annotations": "foo: bar\n",
"task_resource_requirements": {
"requests": {
"cpu": "500m",
"memory": "128M"
}
},
"tower_web_resource_requirements": {
"web_resource_requirements": {
"requests": {
"cpu": "500m",
"memory": "128M"
@@ -32,153 +39,265 @@ metadata:
capabilities: Basic Install
operators.operatorframework.io/builder: operator-sdk-v0.19.4
operators.operatorframework.io/project_layout: ansible
name: awx-operator.v0.0.1
name: awx-operator.v0.12.0
namespace: placeholder
spec:
apiservicedefinitions: {}
customresourcedefinitions:
owned:
- displayName: AWX Backup
kind: AWXBackup
name: awxbackups.awx.ansible.com
specDescriptors:
- displayName: Deployment name
path: deployment_name
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Backup persistent volume claim
path: backup_pvc
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- displayName: Backup persistent volume claim namespace
path: backup_pvc_namespace
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- displayName: Backup PVC storage requirements
path: backup_storage_requirements
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- displayName: Backup PVC storage class
path: backup_storage_class
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- displayName: Database backup label selector
path: postgres_label_selector
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
statusDescriptors:
- description: The persistent volume claim name used during backup
displayName: Backup claim
path: backupClaim
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: The directory data is backed up to on the PVC
displayName: Backup directory
path: backupDirectory
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
version: v1beta1
- displayName: AWX Restore
kind: AWXRestore
name: awxrestores.awx.ansible.com
specDescriptors:
- displayName: Backup source to restore ?
path: backup_source
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:select:CR
- urn:alm:descriptor:com.tectonic.ui:select:PVC
- displayName: Backup name
path: backup_name
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:CR
- displayName: Deployment name
path: deployment_name
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:PVC
- displayName: Backup persistent volume claim
path: backup_pvc
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:PVC
- displayName: Backup persistent volume claim namespace
path: backup_pvc_namespace
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:PVC
- displayName: Backup directory in the persistent volume claim
path: backup_dir
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:PVC
- displayName: Database restore label selector
path: postgres_label_selector
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:hidden
statusDescriptors:
- description: The state of the restore
displayName: Restore status
path: restoreComplete
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
version: v1beta1
- description: A AWX Instance
displayName: AWX
kind: AWX
name: awxs.awx.ansible.com
specDescriptors:
- displayName: Hostname
path: tower_hostname
path: hostname
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Admin account username
path: tower_admin_user
path: admin_user
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Admin email address
path: tower_admin_email
path: admin_email
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Admin password secret
path: tower_admin_password_secret
path: admin_password_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Database configuration secret
path: tower_postgres_configuration_secret
path: postgres_configuration_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Old Database configuration secret
path: tower_old_postgres_configuration_secret
path: old_postgres_configuration_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Secret key secret
path: tower_secret_key_secret
path: secret_key_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Broadcast Websocket Secret
path: tower_broadcast_websocket_secret
path: broadcast_websocket_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Ingress Type
path: tower_ingress_type
- displayName: Service Account Annotations
path: service_account_annotations
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Tower Service Type
path: service_type
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:select:ClusterIP
- urn:alm:descriptor:com.tectonic.ui:select:LoadBalancer
- urn:alm:descriptor:com.tectonic.ui:select:NodePort
- displayName: Tower Ingress Type
path: ingress_type
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:select:none
- urn:alm:descriptor:com.tectonic.ui:select:Ingress
- urn:alm:descriptor:com.tectonic.ui:select:Route
- urn:alm:descriptor:com.tectonic.ui:select:LoadBalancer
- displayName: Tower Ingress Annotations
path: tower_ingress_annotations
path: ingress_annotations
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Ingress
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
- displayName: Tower Ingress TLS Secret
path: tower_ingress_tls_secret
path: ingress_tls_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Ingress
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
- displayName: Tower LoadBalancer Annotations
path: tower_loadbalancer_annotations
path: loadbalancer_annotations
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:LoadBalancer
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:service_type:LoadBalancer
- displayName: Tower LoadBalancer Protocol
path: tower_loadbalancer_protocol
path: loadbalancer_protocol
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:select:http
- urn:alm:descriptor:com.tectonic.ui:select:https
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:LoadBalancer
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:service_type:LoadBalancer
- displayName: Tower LoadBalancer Port
path: tower_loadbalancer_port
path: loadbalancer_port
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:number
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:LoadBalancer
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:service_type:LoadBalancer
- displayName: Route DNS host
path: tower_route_host
path: route_host
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Route
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Route
- displayName: Route TLS termination mechanism
path: tower_route_tls_termination_mechanism
path: route_tls_termination_mechanism
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:select:Edge
- urn:alm:descriptor:com.tectonic.ui:select:Passthrough
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Route
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Route
- displayName: Route TLS credential secret
path: tower_route_tls_secret
path: route_tls_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Route
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Route
- displayName: Image Pull Policy
path: tower_image_pull_policy
path: image_pull_policy
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:imagePullPolicy
- displayName: Image Pull Secret
path: tower_image_pull_secret
path: image_pull_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:imagePullSecret
- displayName: Web container resource requirements
path: tower_web_resource_requirements
path: web_resource_requirements
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
- displayName: Task container resource requirements
path: tower_task_resource_requirements
path: task_resource_requirements
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
- displayName: EE Control Plane container resource requirements
path: ee_resource_requirements
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
- displayName: PostgreSQL container resource requirements (when using a managed
instance)
path: tower_postgres_resource_requirements
path: postgres_resource_requirements
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
- displayName: PostgreSQL container storage requirements (when using a managed
instance)
path: postgres_storage_requirements
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
- displayName: Replicas
path: tower_replicas
path: replicas
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:number
- displayName: Remove used secrets on instance removal ?
path: tower_garbage_collect_secrets
path: garbage_collect_secrets
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- displayName: Preload instance with data upon creation ?
path: tower_create_preload_data
path: create_preload_data
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
@@ -188,8 +307,8 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Should Tower Task container deployed with privileged level ?
path: tower_task_privileged
- displayName: Should the task container deployed with privileged level ?
path: task_privileged
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
@@ -199,28 +318,68 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Image
path: tower_image
- displayName: Deployment Kind
path: kind
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Deployment apiVersion
path: api_version
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Image
path: image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Image Version
path: image_version
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Redis Image
path: tower_redis_image
path: redis_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Redis Image Version
path: redis_image_version
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: PostgreSQL Image
path: tower_postgres_image
path: postgres_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Postgres Storage Class
path: tower_postgres_storage_class
- displayName: PostgreSQL Image Version
path: postgres_image_version
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Postgres Datapath
path: tower_postgres_data_path
- displayName: Postgres Selector
path: postgres_selector
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Postgres Label Selector
path: postgres_label_selector
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Postgres Tolerations
path: postgres_tolerations
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Postgres Storage Class
path: postgres_storage_class
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Postgres Datapath
path: postgres_data_path
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
@@ -234,125 +393,189 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Tower Task Args
path: tower_task_args
- displayName: Task Args
path: task_args
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Enable persistence for /var/lib/projects directory?
path: tower_projects_persistence
path: projects_persistence
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- displayName: Use existing Persistent Claim?
path: tower_projects_use_existing_claim
path: projects_use_existing_claim
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:select:_Yes_
- urn:alm:descriptor:com.tectonic.ui:select:_No_
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_persistence:true
- displayName: Tower Projects Existing Persistent Claim
path: tower_projects_existing_claim
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_persistence:true
- displayName: Projects Existing Persistent Claim
path: projects_existing_claim
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_Yes_
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_Yes_
- urn:alm:descriptor:io.kubernetes:PersistentVolumeClaim
- description: Tower Projects Storage Class Name. If not present, the default
storage class will be used.
displayName: Tower Projects Storage Class Name
path: tower_projects_storage_class
- description: Projects Storage Class Name. If not present, the default storage
class will be used.
displayName: Projects Storage Class Name
path: projects_storage_class
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:text
- description: Tower Projects Storage Size
displayName: Tower Projects Storage Size
path: tower_projects_storage_size
- description: Projects Storage Size
displayName: Projects Storage Size
path: projects_storage_size
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:text
- description: Tower Projects Storage Access Mode
displayName: Tower Projects Storage Access Mode
path: tower_projects_storage_access_mode
- description: Projects Storage Access Mode
displayName: Projects Storage Access Mode
path: projects_storage_access_mode
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Tower Task Command
path: tower_task_command
- displayName: Task Command
path: task_command
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Task Extra Env
path: tower_task_extra_env
- description: Environment variables to be added to Task container
displayName: Task Extra Env
path: task_extra_env
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Task Extra Volume Mounts
path: tower_task_extra_volume_mounts
- description: Specify volume mounts to be added to Execution container
displayName: EE Extra Volume Mounts
path: ee_extra_volume_mounts
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Web Args
path: tower_web_args
- description: Registry path to the Execution Environment container to use
displayName: EE Images
path: ee_images
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Web Command
path: tower_web_command
- description: Environment variables to be added to EE container
displayName: EE Extra Env
path: ee_extra_env
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Web Extra Env
path: tower_web_extra_env
- description: Registry path to the Execution Environment container to use on
control plane pods
displayName: Control Plane EE Image
path: control_plane_ee_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Web Extra Volume Mounts
path: tower_web_extra_volume_mounts
- description: EE Images Pull Credentials Secret
displayName: EE Images Pull Credentials Secret
path: ee_pull_credentials_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- description: Specify volume mounts to be added to Task container
displayName: Task Extra Volume Mounts
path: task_extra_volume_mounts
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Extra Volumes
path: tower_extra_volumes
- displayName: Web Args
path: web_args
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Node Selector
path: tower_node_selector
- displayName: Web Command
path: web_command
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tower Tolerations
path: tower_tolerations
- description: Environment variables to be added to Web container
displayName: Web Extra Env
path: web_extra_env
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Specify volume mounts to be added to Web container
displayName: Web Extra Volume Mounts
path: web_extra_volume_mounts
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Specify extra volumes to add to the application pod
displayName: Extra Volumes
path: extra_volumes
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Node Selector
path: node_selector
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Service Labels
path: service_labels
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Tolerations
path: tolerations
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: API Extra Settings
path: extra_settings
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Registry path to the init container to use
displayName: Init Container Image
path: init_container_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Init container image version to use
displayName: Init Container Image Version
path: init_container_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Secret where can be found the trusted Certificate Authority Bundle
path: bundle_cacert_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
statusDescriptors:
- description: Route to access the instance deployed
displayName: URL
path: towerURL
path: URL
x-descriptors:
- urn:alm:descriptor:org.w3:link
- description: Admin user for the instance deployed
displayName: Admin User
path: towerAdminUser
path: adminUser
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Admin password for the instance deployed
displayName: Admin Password
path: towerAdminPasswordSecret
path: adminPasswordSecret
x-descriptors:
- urn:alm:descriptor:io.kubernetes:Secret
- description: Version of the instance deployed
displayName: Version
path: towerVersion
path: version
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Image of the instance deployed
displayName: Image
path: towerImage
path: image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
version: v1beta1
@@ -419,6 +642,7 @@ spec:
- apps
resources:
- deployments/scale
- statefulsets/scale
verbs:
- patch
- apiGroups:
@@ -438,6 +662,8 @@ spec:
- awx.ansible.com
resources:
- '*'
- awxbackups
- awxrestores
verbs:
- '*'
serviceAccountName: awx-operator
@@ -468,7 +694,11 @@ spec:
value: awx-operator
- name: ANSIBLE_GATHERING
value: explicit
image: quay.io/ansible/awx-operator:0.8.0
- name: OPERATOR_VERSION
value: 0.12.0
- name: ANSIBLE_DEBUG_LOGS
value: "false"
image: quay.io/ansible/awx-operator:0.12.0
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -507,4 +737,5 @@ spec:
provider:
name: AWX Community
url: https://github.com/ansible/awx-operator
version: 0.0.1
replaces: awx-operator.v0.11.0
version: 0.12.0

View File

@@ -0,0 +1,85 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
name: awxbackups.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXBackup
listKind: AWXBackupList
plural: awxbackups
singular: awxbackup
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: Schema validation for the AWXBackup CRD
properties:
spec:
properties:
backup_pvc:
description: Name of the PVC to be used for storing the backup
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_storage_class:
description: Storage class to use when creating PVC for backup
type: string
backup_storage_requirements:
description: Storage requirements for the PostgreSQL container
type: string
deployment_name:
description: Name of the deployment to be backed up
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing
up data
type: string
required:
- deployment_name
type: object
status:
properties:
backupClaim:
description: Backup persistent volume claim
type: string
backupDirectory:
description: Backup directory name on the specified pvc
type: string
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
type: object
type: object
x-kubernetes-preserve-unknown-fields: true
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null

View File

@@ -0,0 +1,88 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
name: awxrestores.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWXRestore
listKind: AWXRestoreList
plural: awxrestores
singular: awxrestore
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: Schema validation for the AWXRestore CRD
properties:
spec:
properties:
backup_dir:
description: Backup directory name, set as a status found on the awxbackup
object (backupDirectory)
type: string
backup_name:
description: AWXBackup object name
type: string
backup_pvc:
description: Name of the PVC to be restored from, set as a status
found on the awxbackup object (backupClaim)
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
type: string
backup_source:
description: Backup source
enum:
- CR
- PVC
type: string
deployment_name:
description: Name of the deployment to be restored to
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for backing
up data
type: string
type: object
status:
properties:
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
restoreComplete:
description: Restore process complete
type: boolean
type: object
type: object
x-kubernetes-preserve-unknown-fields: true
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null

View File

@@ -19,37 +19,48 @@ spec:
properties:
spec:
properties:
admin_email:
description: The admin user email
type: string
admin_password_secret:
description: Secret where the admin password can be found
type: string
admin_user:
default: admin
description: Username to use for the admin account
type: string
api_version:
description: apiVersion of the deployment type
type: string
broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
bundle_cacert_secret:
description: Secret where can be found the trusted Certificate Authority Bundle
type: string
ca_trust_bundle:
description: Path where the trusted CA bundle is available
type: string
control_plane_ee_image:
description: Registry path to the Execution Environment container
image to use on control plane pods
type: string
create_preload_data:
default: true
description: Whether or not to preload data upon instance creation
type: boolean
deployment_type:
description: Name of the deployment type
type: string
development_mode:
description: If the deployment should be done in development mode
type: boolean
ldap_cacert_secret:
description: Secret where can be found the LDAP trusted Certificate
Authority Bundle
ee_extra_env:
type: string
tower_admin_email:
description: The admin user email
ee_extra_volume_mounts:
description: Specify volume mounts to be added to Execution container
type: string
tower_admin_password_secret:
description: Secret where the admin password can be found
type: string
tower_admin_user:
default: admin
description: Username to use for the admin account
type: string
tower_broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
tower_create_preload_data:
default: true
description: Whether or not to preload data upon Tower instance creation
type: boolean
tower_ee_images:
ee_images:
description: Registry path to the Execution Environment container
to use
items:
@@ -60,82 +71,12 @@ spec:
type: string
type: object
type: array
tower_extra_volumes:
description: Specify extra volumes to add to the application pod
ee_pull_credentials_secret:
description: Secret where pull credentials for registered ees can
be found
type: string
tower_garbage_collect_secrets:
default: false
description: Whether or not to remove secrets upon instance removal
type: boolean
tower_hostname:
description: The hostname of the instance
type: string
tower_image:
description: Registry path to the application container to use
type: string
tower_image_pull_policy:
default: IfNotPresent
description: The image pull policy
enum:
- Always
- always
- Never
- never
- IfNotPresent
- ifnotpresent
type: string
tower_image_pull_secret:
description: The image pull secret
type: string
tower_ingress_annotations:
description: Annotations to add to the ingress
type: string
tower_ingress_tls_secret:
description: Secret where the ingress TLS secret can be found
type: string
tower_ingress_type:
description: The ingress type to use to reach the deployed instance
enum:
- none
- Ingress
- ingress
- Route
- route
- LoadBalancer
- loadbalancer
type: string
tower_loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
tower_loadbalancer_port:
default: 80
description: Port to use for the loadbalancer
type: integer
tower_loadbalancer_protocol:
default: http
description: Protocol to use for the loadbalancer
enum:
- http
- https
type: string
tower_node_selector:
description: nodeSelector for the AWX pods
type: string
tower_old_postgres_configuration_secret:
description: Secret where the old database configuration can be found
for data migration
type: string
tower_postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
tower_postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
tower_postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
tower_postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
limits:
properties:
@@ -156,49 +97,195 @@ spec:
type: string
type: object
type: object
tower_postgres_storage_class:
extra_settings:
description: Extra settings to specify for the API
items:
properties:
setting:
type: string
value:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
extra_volumes:
description: Specify extra volumes to add to the application pod
type: string
garbage_collect_secrets:
default: false
description: Whether or not to remove secrets upon instance removal
type: boolean
hostname:
description: The hostname of the instance
type: string
image:
description: Registry path to the application container to use
type: string
image_pull_policy:
default: IfNotPresent
description: The image pull policy
enum:
- Always
- always
- Never
- never
- IfNotPresent
- ifnotpresent
type: string
image_pull_secret:
description: The image pull secret
type: string
image_version:
description: Application container image version to use
type: string
ingress_annotations:
description: Annotations to add to the Ingress Controller
type: string
ingress_tls_secret:
description: Secret where the Ingress TLS secret can be found
type: string
ingress_type:
description: The ingress type to use to reach the deployed instance
enum:
- none
- Ingress
- ingress
- Route
- route
type: string
init_container_image:
description: Registry path to the init container to use
type: string
init_container_image_version:
description: Init container image version to use
type: string
kind:
description: Kind of the deployment type
type: string
ldap_cacert_secret:
description: Secret where can be found the LDAP trusted Certificate
Authority Bundle
type: string
loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
loadbalancer_port:
default: 80
description: Port to use for the loadbalancer
type: integer
loadbalancer_protocol:
default: http
description: Protocol to use for the loadbalancer
enum:
- http
- https
type: string
node_selector:
description: nodeSelector for the pods
type: string
old_postgres_configuration_secret:
description: Secret where the old database configuration can be found
for data migration
type: string
postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
postgres_image_version:
description: PostgreSQL container image version to use
type: string
postgres_label_selector:
description: Label selector used to identify postgres pod for data
migration
type: string
postgres_resource_requirements:
description: Resource requirements for the PostgreSQL container
properties:
limits:
properties:
cpu:
type: string
memory:
type: string
type: object
requests:
properties:
cpu:
type: string
memory:
type: string
type: object
type: object
postgres_selector:
description: nodeSelector for the Postgres pods
type: string
postgres_storage_class:
description: Storage class to use for the PostgreSQL PVC
type: string
tower_projects_existing_claim:
postgres_storage_requirements:
description: Storage requirements for the PostgreSQL container
properties:
limits:
properties:
storage:
type: string
type: object
requests:
properties:
storage:
type: string
type: object
type: object
postgres_tolerations:
description: node tolerations for the Postgres pods
type: string
projects_existing_claim:
description: PersistentVolumeClaim to mount /var/lib/projects directory
type: string
tower_projects_persistence:
projects_persistence:
default: false
description: Whether or not the /var/lib/projects directory will be
persistent
type: boolean
tower_projects_storage_access_mode:
projects_storage_access_mode:
default: ReadWriteMany
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
type: string
tower_projects_storage_class:
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
tower_projects_storage_size:
projects_storage_size:
default: 8Gi
description: Size for the /var/lib/projects PersistentVolumeClaim
type: string
tower_projects_use_existing_claim:
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
enum:
- _Yes_
- _No_
type: string
tower_redis_image:
redis_image:
description: Registry path to the redis container to use
type: string
tower_replicas:
redis_image_version:
description: Redis container image version to use
type: string
replicas:
default: 1
description: Number of instance replicas
format: int32
type: integer
tower_route_host:
route_host:
description: The DNS to use to points to the instance
type: string
tower_route_tls_secret:
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
tower_route_tls_termination_mechanism:
route_tls_termination_mechanism:
default: Edge
description: The secure TLS termination mechanism to use
enum:
@@ -207,26 +294,43 @@ spec:
- Passthrough
- passthrough
type: string
tower_secret_key_secret:
secret_key_secret:
description: Secret where the secret key can be found
type: string
tower_task_args:
service_account_annotations:
description: ServiceAccount annotations
type: string
service_labels:
description: Additional labels to apply to the service
type: string
service_type:
description: The service type to be used on the deployed instance
enum:
- LoadBalancer
- loadbalancer
- ClusterIP
- clusterip
- NodePort
- nodeport
type: string
task_args:
items:
type: string
type: array
tower_task_command:
task_command:
items:
type: string
type: array
tower_task_extra_env:
task_extra_env:
type: string
tower_task_extra_volume_mounts:
task_extra_volume_mounts:
description: Specify volume mounts to be added to Task container
type: string
tower_task_privileged:
task_privileged:
default: false
description: If a privileged security context should be enabled
type: boolean
tower_task_resource_requirements:
task_resource_requirements:
description: Resource requirements for the task container
properties:
limits:
@@ -248,22 +352,23 @@ spec:
type: string
type: object
type: object
tower_tolerations:
description: node tolerations for the AWX pods
tolerations:
description: node tolerations for the pods
type: string
tower_web_args:
web_args:
items:
type: string
type: array
tower_web_command:
web_command:
items:
type: string
type: array
tower_web_extra_env:
web_extra_env:
type: string
tower_web_extra_volume_mounts:
web_extra_volume_mounts:
description: Specify volume mounts to be added to the Web container
type: string
tower_web_resource_requirements:
web_resource_requirements:
description: Resource requirements for the web container
properties:
limits:
@@ -288,6 +393,18 @@ spec:
type: object
status:
properties:
URL:
description: URL to access the deployed instance
type: string
adminPasswordSecret:
description: Admin password secret name of the deployed instance
type: string
adminUser:
description: Admin user of the deployed instance
type: string
broadcastWebsocketSecret:
description: Broadcast websocket secret name of the deployed instance
type: string
conditions:
description: The resulting conditions when a Service Telemetry is
instantiated
@@ -303,22 +420,19 @@ spec:
type: string
type: object
type: array
towerAdminPasswordSecret:
description: Admin password of the deployed instance
type: string
towerAdminUser:
description: Admin user of the deployed instance
type: string
towerImage:
image:
description: URL of the image used for the deployed instance
type: string
towerMigratedFromSecret:
description: The secret used for migrating an old Tower.
migratedFromSecret:
description: The secret used for migrating an old instance.
type: string
towerURL:
description: URL to access the deployed instance
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
towerVersion:
secretKeySecret:
description: Secret key secret name of the deployed instance
type: string
version:
description: Version of the deployed instance
type: string
type: object

1
docs/awx-demo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 825 KiB

View File

@@ -6,14 +6,14 @@ To migrate data from an older AWX installation, you must provide some informatio
### Secret Key
You can find your old secret key in the inventory file you used to deploy AWX in releases prior to version 18.
You can find your old secret key in the inventory file you used to deploy AWX in releases prior to version 18.
```yaml
apiVersion: v1
kind: Secret
metadata:
name: <resourcename>-secret-key
namespace: <target namespace>
namespace: <target-namespace>
stringData:
secret_key: <old-secret-key>
type: Opaque
@@ -43,6 +43,15 @@ type: Opaque
> For `host`, a URL resolvable by the cluster could look something like `postgresql.<namespace>.svc.cluster.local`, where `<namespace>` is filled in with the namespace of the AWX deployment you are migrating data from.
If your AWX deployment is already using an external database server or its database is otherwise not managed
by the AWX deployment, you can instead create the same secret as above but omit the `-old-` from the `name`.
In the next section pass it in through `postgres_configuration_secret` instead, omitting the `_old_`
from the key and ensuring the value matches the name of the secret. This will make AWX pick up on the existing
database and apply any pending migrations. It is strongly recommended to backup your database beforehand.
The postgresql pod for the old deployment is used when streaming data to the new postgresql pod. If your postgresql pod has a custom label,
you can pass that via the `postgres_label_selector` variable to make sure the postgresql pod can be found.
## Deploy AWX
When you apply your AWX object, you must specify the name to the database secret you created above:
@@ -53,6 +62,6 @@ kind: AWX
metadata:
name: awx
spec:
tower_old_postgres_configuration_secret: <resourcename>-old-postgres-configuration
old_postgres_configuration_secret: <resourcename>-old-postgres-configuration
...
```

View File

@@ -27,8 +27,3 @@ provisioner:
group_vars:
all:
operator_namespace: ${TEST_NAMESPACE:-default}
env:
K8S_AUTH_KUBECONFIG: /tmp/molecule/kind-default/kubeconfig
KUBECONFIG: /tmp/molecule/kind-default/kubeconfig
ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/roles
KIND_PORT: '${TEST_CLUSTER_PORT:-9443}'

View File

@@ -11,10 +11,18 @@
- "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/ansible/group_vars/all"
tasks:
- name: Create Custom Resource Definition
- name: Create AWX Custom Resource Definition
k8s:
definition: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awx_v1beta1_crd.yaml'])) }}"
- name: Create AWXBackup Custom Resource Definition
k8s:
definition: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awxbackup_v1beta1_crd.yaml'])) }}"
- name: Create AWXRestore Custom Resource Definition
k8s:
definition: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awxrestore_v1beta1_crd.yaml'])) }}"
- name: Ensure specified namespace is present
k8s:
api_version: v1

View File

@@ -1,2 +0,0 @@
[defaults]
stdout_callback = yaml

View File

@@ -1,133 +0,0 @@
---
- name: Build Operator in Kind container
hosts: k8s
vars:
image_name: awx.ansible.com/awx-operator:testing
tasks:
# using command so we don't need to install any dependencies
- name: Get existing image hash
command: docker images -q {{ image_name }}
register: prev_hash
changed_when: false
- name: Build Operator Image
command: docker build -f /build/build/Dockerfile -t {{ image_name }} /build
register: build_cmd
changed_when: not prev_hash.stdout or (prev_hash.stdout and prev_hash.stdout not in ''.join(build_cmd.stdout_lines[-2:]))
- name: Converge
hosts: localhost
connection: local
vars:
ansible_python_interpreter: '{{ ansible_playbook_python }}'
deploy_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"
templates_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/ansible/templates"
pull_policy: Never
operator_image: awx.ansible.com/awx-operator
operator_version: testing
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awx_v1beta1_molecule.yaml'])) | from_yaml }}"
tasks:
- block:
- name: Delete the Operator Deployment
k8s:
state: absent
namespace: '{{ operator_namespace }}'
definition: "{{ lookup('template', '/'.join([templates_dir, 'operator.yml.j2'])) }}"
register: delete_deployment
when: hostvars[groups.k8s.0].build_cmd.changed
- name: Wait 30s for Operator Deployment to terminate
k8s_info:
api_version: '{{ definition.apiVersion }}'
kind: '{{ definition.kind }}'
namespace: '{{ operator_namespace }}'
name: '{{ definition.metadata.name }}'
vars:
definition: "{{ lookup('template', '/'.join([templates_dir, 'operator.yml.j2'])) | from_yaml }}"
register: deployment
until: not deployment.resources
delay: 3
retries: 10
when: delete_deployment.changed
- name: Create the Operator Deployment
k8s:
namespace: '{{ operator_namespace }}'
definition: "{{ lookup('template', '/'.join([templates_dir, 'operator.yml.j2'])) }}"
- name: Ensure the AWX custom_resource namespace exists
k8s:
state: present
name: '{{ custom_resource.metadata.namespace }}'
kind: Namespace
api_version: v1
- name: Create the AWX Custom Resource
k8s:
state: present
namespace: '{{ custom_resource.metadata.namespace }}'
definition: '{{ custom_resource }}'
- name: Wait 15m for reconciliation to run
k8s_info:
api_version: '{{ custom_resource.apiVersion }}'
kind: '{{ custom_resource.kind }}'
namespace: '{{ custom_resource.metadata.namespace }}'
name: '{{ custom_resource.metadata.name }}'
register: cr
until:
- "'Successful' in (cr | json_query('resources[].status.conditions[].reason'))"
delay: 6
retries: 150
rescue:
- name: debug cr
ignore_errors: yes
failed_when: false
debug:
var: debug_cr
vars:
debug_cr: '{{ lookup("k8s",
kind=custom_resource.kind,
api_version=custom_resource.apiVersion,
namespace=custom_resource.metadata.namespace,
resource_name=custom_resource.metadata.name)
}}'
- name: debug awx deployment
ignore_errors: yes
failed_when: false
debug:
var: deploy
vars:
deploy: '{{ lookup("k8s",
kind="Deployment",
api_version="apps/v1",
namespace=custom_resource.metadata.namespace,
label_selector="app.kubernetes.io/name=example-awx")
}}'
- name: get operator logs
ignore_errors: yes
failed_when: false
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ operator_namespace }}
environment:
KUBECONFIG: '{{ lookup("env", "KUBECONFIG") }}'
vars:
definition: "{{ lookup('template', '/'.join([templates_dir, 'operator.yml.j2'])) | from_yaml }}"
register: log
- name: print debug output
debug: var=log.stdout_lines
- name: fail if converge didn't succeed
fail:
msg: "Failed on action: converge"
- import_playbook: '{{ playbook_dir }}/../default/asserts.yml'

View File

@@ -1,46 +0,0 @@
---
dependency:
name: galaxy
driver:
name: docker
lint: |
set -e
yamllint .
ansible-lint
platforms:
- name: kind-test-local
groups:
- k8s
image: bsycorp/kind:v1.17.9
privileged: True
override_command: no
exposed_ports:
- 8443/tcp
- 10080/tcp
published_ports:
- 0.0.0.0:${TEST_CLUSTER_PORT:-10443}:8443/tcp
pre_build_image: yes
volumes:
- ${MOLECULE_PROJECT_DIRECTORY}:/build:Z
provisioner:
name: ansible
log: True
inventory:
group_vars:
all:
operator_namespace: ${TEST_NAMESPACE:-default}
env:
K8S_AUTH_KUBECONFIG: /tmp/molecule/kind-test-local/kubeconfig
KUBECONFIG: /tmp/molecule/kind-test-local/kubeconfig
ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/roles
KIND_PORT: '${TEST_CLUSTER_PORT:-10443}'
scenario:
test_sequence:
- lint
- destroy
- dependency
- syntax
- create
- prepare
- converge
- destroy

View File

@@ -1,38 +0,0 @@
---
- name: Prepare kubernetes environment
hosts: k8s
gather_facts: no
vars:
kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}"
tasks:
- name: delete the kubeconfig if present
file:
path: '{{ kubeconfig }}'
state: absent
delegate_to: localhost
- name: Fetch the kubeconfig
fetch:
dest: '{{ kubeconfig }}'
flat: yes
src: /root/.kube/config
- name: Change the kubeconfig port to the proper value
replace:
regexp: 8443
replace: "{{ lookup('env', 'KIND_PORT') }}"
path: '{{ kubeconfig }}'
mode: 0644
delegate_to: localhost
- name: Wait for the Kubernetes API to become available (this could take a minute)
uri:
url: "http://localhost:10080/kubernetes-ready"
status_code: 200
validate_certs: no
register: result
until: (result.status|default(-1)) == 200
retries: 60
delay: 5
- import_playbook: ../default/prepare.yml

View File

@@ -36,6 +36,7 @@
pull_policy: Never
operator_image: awx.ansible.com/awx-operator
operator_version: testing
ansible_debug_logs: "true"
# Change this to _awx to test AWX, _tower to test Tower.
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awx_v1beta1_molecule.yaml'])) | from_yaml }}"
@@ -125,8 +126,6 @@
ignore_errors: yes
failed_when: false
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ operator_namespace }} -c operator
environment:
KUBECONFIG: '{{ lookup("env", "KUBECONFIG") }}'
vars:
definition: "{{ lookup('template', '/'.join([templates_dir, 'operator.yml.j2'])) | from_yaml }}"
register: log

View File

@@ -1,6 +1,6 @@
---
collections:
- name: community.kubernetes
- name: kubernetes.core
version: '==1.1.1'
- name: operator_sdk.util
version: '==0.1.0'

95
roles/backup/README.md Normal file
View File

@@ -0,0 +1,95 @@
Backup Role
=========
The purpose of this role is to create a backup of your AWX deployment which includes:
- custom deployment specific values in the spec section of the AWX custom resource object
- backup of the postgresql database
- secret_key, admin_password, and broadcast_websocket secrets
- database configuration
Requirements
------------
This role assumes you are authenticated with an Openshift or Kubernetes cluster:
- The awx-operator has been deployed to the cluster
- AWX is deployed to via the operator
Usage
----------------
Then create a file named `backup-awx.yml` with the following contents:
```yaml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWXBackup
metadata:
name: awxbackup-2021-04-22
namespace: my-namespace
spec:
deployment_name: mytower
```
Note that the `deployment_name` above is the name of the AWX deployment you intend to backup from. The namespace above is the one containing the AWX deployment that will be backed up.
Finally, use `kubectl` to create the backup object in your cluster:
```bash
$ kubectl apply -f backup-awx.yml
```
The resulting pvc will contain a backup tar that can be used to restore to a new deployment. Future backups will also be stored in separate tars on the same pvc.
Role Variables
--------------
A custom, pre-created pvc can be used by setting the following variables.
```
backup_pvc: 'awx-backup-volume-claim'
```
> If no pvc or storage class is provided, the cluster's default storage class will be used to create the pvc.
This role will automatically create a pvc using a Storage Class if provided:
```
backup_storage_class: 'standard'
backup_storage_requirements: '20Gi'
```
By default, the backup pvc will be created in the same namespace the awxbackup object is created in. If you want your backup to be stored
in a specific namespace, you can do so by specifying `backup_pvc_namespace`. Keep in mind that you will
need to provide the same namespace when restoring.
```
backup_pvc_namespace: 'custom-namespace'
```
If a custom postgres configuration secret was used when deploying AWX, it will automatically be used by the backup role.
To check the name of this secret, look at the postgresConfigurationSecret status on your AWX object.
The postgresql pod for the old deployment is used when backing up data to the new postgresql pod. If your postgresql pod has a custom label,
you can pass that via the `postgres_label_selector` variable to make sure the postgresql pod can be found.
Testing
----------------
You can test this role directly by creating and running the following playbook with the appropriate variables:
```
---
- name: Backup AWX
hosts: localhost
gather_facts: false
roles:
- backup
```
License
-------
MIT

View File

@@ -0,0 +1,12 @@
---
# Required: specify name of tower deployment to backup from
deployment_name: ''
kind: 'AWXBackup'
api_version: '{{ deployment_type }}.ansible.com/v1beta1'
# Specify a pre-created PVC (name) to backup to
backup_pvc: ''
backup_pvc_namespace: "{{ meta.namespace }}"
# Size of backup PVC if created dynamically
backup_storage_requirements: ''

View File

@@ -0,0 +1,31 @@
---
galaxy_info:
author: Ansible
description: AWX role for AWX Operator for Kubernetes.
company: Red Hat, Inc.
license: MIT
min_ansible_version: 2.8
platforms:
- name: EL
versions:
- all
- name: Debian
versions:
- all
galaxy_tags:
- tower
- controller
- awx
- ansible
- backup
- automation
dependencies: []
collections:
- kubernetes.core
- operator_sdk.util

View File

@@ -0,0 +1,30 @@
---
- name: Get AWX custom resource object
k8s_info:
version: v1beta1
kind: AWX
namespace: '{{ meta.namespace }}'
name: '{{ deployment_name }}'
register: _awx_cro
- name: Set AWX object
set_fact:
awx_spec:
spec: "{{ this_awx['resources'][0]['spec'] }}"
- name: Set names of backed up secrets in the CR spec
set_fact:
awx_spec: "{{ awx_spec | combine ({ item.key : item.value }) }}"
with_items:
- {"key": "secret_key_secret", "value": "{{ this_awx['resources'][0]['status']['secretKeySecret'] }}"}
- {"key": "admin_password_secret", "value": "{{ this_awx['resources'][0]['status']['adminPasswordSecret'] }}"}
- {"key": "broadcast_websocket_secret", "value": "{{ this_awx['resources'][0]['status']['broadcastWebsocketSecret'] }}"}
- {"key": "postgres_configuration_secret", "value": "{{ this_awx['resources'][0]['status']['postgresConfigurationSecret'] }}"}
- name: Write awx object to pvc
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: >-
bash -c 'echo "$0" > {{ backup_dir }}/awx_object' {{ awx_spec | to_yaml | quote }}

View File

@@ -0,0 +1,9 @@
---
- name: Delete any existing management pod
k8s:
name: "{{ meta.name }}-db-management"
kind: Pod
namespace: "{{ backup_pvc_namespace }}"
state: absent
force: true

View File

@@ -0,0 +1,35 @@
---
- name: Get secret name
set_fact:
_name: "{{ this_awx['resources'][0]['status'][item] }}"
- name: Fail if status is not set on AWX CR
block:
- name: Set error message
set_fact:
error_msg: "{{ item }} status is not set on AWX object yet"
- name: Handle error
import_tasks: error_handling.yml
- name: Fail early if secret name status is not set
fail:
msg: "{{ error_msg }}"
when: _name is not defined or _name == ''
- name: Get secret
k8s_info:
version: v1
kind: Secret
namespace: '{{ meta.namespace }}'
name: "{{ _name }}"
register: _secret
- name: Set secret data
set_fact:
_data: "{{ _secret['resources'][0]['data'] }}"
- name: Create and Add secret names and data to dictionary
set_fact:
secret_dict: "{{ secret_dict | default({}) | combine({ item: {'name': _name, 'data': _data }}) }}"

View File

@@ -0,0 +1,24 @@
---
- name: Get Secret Name
set_fact:
_name: "{{ awx_spec[item] | default('') }}"
- name: Skip if secret name not defined
block:
- name: Get secret
k8s_info:
version: v1
kind: Secret
namespace: '{{ meta.namespace }}'
name: "{{ _name }}"
register: _secret
- name: Set secret key
set_fact:
_data: "{{ _secret['resources'][0]['data'] }}"
- name: Create and Add secret names and data to dictionary
set_fact:
secret_dict: "{{ secret_dict | default({}) | combine({item: { 'name': _name, 'data': _data }}) }}"
when: _name != ''

View File

@@ -0,0 +1,11 @@
---
- name: Determine the timestamp
set_fact:
now: '{{ lookup("pipe", "date +%FT%TZ") }}'
- name: Emit ocp event with error
k8s:
kind: Event
namespace: "{{ meta.namespace }}"
template: "event.yml.j2"

View File

@@ -0,0 +1,80 @@
---
- name: Delete any existing management pod
k8s:
name: "{{ meta.name }}-db-management"
kind: Pod
namespace: "{{ backup_pvc_namespace }}"
state: absent
force: true
wait: true
# Check to make sure provided pvc exists, error loudly if not. Otherwise, the management pod will just stay in pending state forever.
- name: Check provided PVC exists
k8s_info:
name: "{{ backup_pvc }}"
kind: PersistentVolumeClaim
namespace: "{{ backup_pvc_namespace }}"
register: provided_pvc
when:
- backup_pvc != ''
- name: Surface error to user
block:
- name: Set error message
set_fact:
error_msg: "{{ backup_pvc }} does not exist, please create this pvc first."
- name: Handle error
import_tasks: error_handling.yml
- name: Fail early if pvc is defined but does not exist
fail:
msg: "{{ backup_pvc }} does not exist, please create this pvc first."
when:
- backup_pvc != ''
- provided_pvc.resources | length == 0
# If backup_pvc is defined, use in management-pod.yml.j2
- name: Set default pvc name
set_fact:
_default_backup_pvc: "{{ deployment_name }}-backup-claim"
# by default, it will re-use the old pvc if already created (unless a pvc is provided)
- name: Set PVC to use for backup
set_fact:
backup_claim: "{{ backup_pvc | default(_default_backup_pvc, true) }}"
- block:
- name: Create PVC for backup
k8s:
kind: PersistentVolumeClaim
template: "backup_pvc.yml.j2"
- name: Remove PVC ownerReference
k8s:
definition:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: '{{ deployment_name }}-backup-claim'
namespace: '{{ backup_pvc_namespace }}'
ownerReferences: null
when:
- backup_pvc == '' or backup_pvc is not defined
- name: Create management pod from templated deployment config
k8s:
name: "{{ meta.name }}-db-management"
kind: Deployment
state: present
template: "management-pod.yml.j2"
wait: true
- name: Look up details for this deployment
k8s_info:
api_version: "{{ api_version }}"
kind: "AWX"
name: "{{ deployment_name }}"
namespace: "{{ meta.namespace }}"
register: this_awx

View File

@@ -0,0 +1,47 @@
---
- name: Patching labels to {{ kind }} kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
metadata:
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
- name: Look up details for this backup object
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
register: this_backup
- block:
- include_tasks: init.yml
- include_tasks: postgres.yml
- include_tasks: awx-cro.yml
- include_tasks: secrets.yml
- name: Set flag signifying this backup was successful
set_fact:
backup_complete: true
- include_tasks: cleanup.yml
when:
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
- name: Update status variables
include_tasks: update_status.yml

View File

@@ -0,0 +1,102 @@
---
- name: Get PostgreSQL configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: "{{ this_awx['resources'][0]['status']['postgresConfigurationSecret'] }}"
register: pg_config
- name: Fail if postgres configuration secret status does not exist
fail:
msg: "The postgresConfigurationSecret status is not set on the AWX object yet or the secret has been deleted."
when: not pg_config | default([]) | length
- name: Store Database Configuration
set_fact:
awx_postgres_user: "{{ pg_config['resources'][0]['data']['username'] | b64decode }}"
awx_postgres_pass: "{{ pg_config['resources'][0]['data']['password'] | b64decode }}"
awx_postgres_database: "{{ pg_config['resources'][0]['data']['database'] | b64decode }}"
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
awx_postgres_type: "{{ pg_config['resources'][0]['data']['type'] | default('unmanaged'|b64encode) | b64decode }}"
- block:
- name: Delete pod to reload a resource configuration
set_fact:
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ deployment_name }}"
when: postgres_label_selector is not defined
- name: Get the postgres pod information
k8s_info:
kind: Pod
namespace: '{{ meta.namespace }}'
label_selectors:
- "{{ postgres_label_selector }}"
register: postgres_pod
until:
- "postgres_pod['resources'] | length"
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
delay: 5
retries: 60
- name: Set the resource pod name as a variable.
set_fact:
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
when: awx_postgres_type == 'managed'
- name: Determine the timestamp for the backup once for all nodes
set_fact:
now: '{{ lookup("pipe", "date +%F-%T") }}'
- name: Set backup directory name
set_fact:
backup_dir: "/backups/tower-openshift-backup-{{ now }}"
- name: Create directory for backup
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: >-
mkdir -p {{ backup_dir }}
- name: Precreate file for database dump
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: >-
touch {{ backup_dir }}/tower.db
- name: Set permissions on file for database dump
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: >-
bash -c "chmod 0600 {{ backup_dir }}/tower.db && chown postgres:root {{ backup_dir }}/tower.db"
- name: Set full resolvable host name for postgres pod
set_fact:
resolvable_db_host: '{{ (awx_postgres_type == "managed") | ternary(awx_postgres_host + "." + meta.namespace + ".svc.cluster.local", awx_postgres_host) }}' # noqa 204
- name: Set pg_dump command
set_fact:
pgdump: >-
pg_dump --clean --create
-h {{ resolvable_db_host }}
-U {{ awx_postgres_user }}
-d {{ awx_postgres_database }}
-p {{ awx_postgres_port }}
-F custom
- name: Write pg_dump to backup on PVC
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: |
bash -c """
set -e -o pipefail
PGPASSWORD={{ awx_postgres_pass }} {{ pgdump }} > {{ backup_dir }}/tower.db
echo 'Successful'
"""
register: data_migration
failed_when: "'Successful' not in data_migration.stdout"

View File

@@ -0,0 +1,36 @@
---
- name: Create Temporary secrets file
tempfile:
state: file
suffix: .json
register: tmp_secrets
- name: Dump (generated) secret names from statuses and data into file
include_tasks: dump_generated_secret.yml
with_items:
- secretKeySecret
- adminPasswordSecret
- broadcastWebsocketSecret
- postgresConfigurationSecret
- name: Dump secret names from awx spec and data into file
include_tasks: dump_secret.yml
loop:
- route_tls_secret
- ingress_tls_secret
- ldap_cacert_secret
- bundle_cacert_secret
- image_pull_secret
- ee_pull_credentials_secret
- name: Nest secrets under a single variable
set_fact:
secrets: {"secrets": '{{ secret_dict }}'}
- name: Write postgres configuration to pvc
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: >-
bash -c "echo '{{ secrets | to_yaml }}' > {{ backup_dir }}/secrets.yml"

View File

@@ -0,0 +1,13 @@
---
# The backup directory in this status can be referenced when restoring
- name: Update CR Backup status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
backupDirectory: "{{ backup_dir }}"
backupClaim: "{{ backup_claim }}"
when: backup_complete

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ deployment_name }}-backup-claim
namespace: {{ backup_pvc_namespace }}
ownerReferences: null
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
spec:
accessModes:
- ReadWriteOnce
{% if backup_storage_class is defined %}
storageClassName: {{ backup_storage_class }}
{% endif %}
resources:
requests:
storage: {{ backup_storage_requirements | default('5Gi', true) }}

View File

@@ -0,0 +1,17 @@
---
apiVersion: v1
kind: Event
metadata:
name: backup-error.{{ now }}
namespace: {{ meta.namespace }}
involvedObject:
apiVersion: awx.ansible.com/v1beta1
kind: {{ kind }}
name: {{ meta.name }}
namespace: {{ meta.namespace }}
message: {{ error_msg }}
reason: BackupFailed
type: Warning
firstTimestamp: {{ now }}
lastTimestamp: {{ now }}
count: 1

View File

@@ -0,0 +1,28 @@
---
apiVersion: v1
kind: Pod
metadata:
name: {{ meta.name }}-db-management
namespace: {{ backup_pvc_namespace }}
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
spec:
containers:
- name: {{ meta.name }}-db-management
image: "{{ postgres_image }}:{{ postgres_image_version }}"
imagePullPolicy: Always
command: ["sleep", "infinity"]
volumeMounts:
- name: {{ meta.name }}-backup
mountPath: /backups
readOnly: false
volumes:
- name: {{ meta.name }}-backup
persistentVolumeClaim:
claimName: {{ backup_claim }}
readOnly: false
restartPolicy: Never

View File

@@ -0,0 +1,6 @@
---
deployment_type: "awx"
postgres_image: postgres
postgres_image_version: 12
backup_complete: false
database_type: "unmanaged"

View File

@@ -1,21 +0,0 @@
---
# Whether secrets should be garbage collected
# on teardown
#
tower_garbage_collect_secrets: false
# Secret to lookup that provide the admin password
#
tower_admin_password_secret: ''
# Secret to lookup that provide the secret key
#
tower_secret_key_secret: ''
# Secret to lookup that provide the PostgreSQL configuration
#
tower_postgres_configuration_secret: ''
# Secret to lookup that provide the broadcast websocket key
#
tower_broadcast_websocket_secret: ''

View File

@@ -1,27 +0,0 @@
---
- block:
- name: Define secrets name
set_fact:
_admin_password: '{{ tower_admin_password_secret | length | ternary(tower_admin_password_secret, meta.name + "-admin-password") }}'
_secret_key: '{{ tower_secret_key_secret | length | ternary(tower_secret_key_secret, meta.name + "-secret-key") }}'
# yamllint disable-line rule:line-length
_broadcast_websocket_secret: '{{ tower_broadcast_websocket_secret | length | ternary(tower_broadcast_websocket_secret, meta.name + "-broadcast-websocket") }}' # noqa 204
# yamllint disable-line rule:line-length
_postgres_configuration: '{{ tower_postgres_configuration_secret | length | ternary(tower_postgres_configuration_secret, meta.name + "-postgres-configuration") }}' # noqa 204
- name: Remove ownerReferences reference
k8s:
definition:
apiVersion: v1
kind: Secret
metadata:
name: '{{ item }}'
namespace: '{{ meta.namespace }}'
ownerReferences: null
loop:
- '{{ _admin_password }}'
- '{{ _secret_key }}'
- '{{ _postgres_configuration }}'
- '{{ _broadcast_websocket_secret }}'
when: not tower_garbage_collect_secrets | bool

View File

@@ -1,157 +1,206 @@
---
deployment_type: awx
kind: '{{ deployment_type | upper }}'
api_version: '{{ deployment_type }}.ansible.com/v1beta1'
database_name: "{{ deployment_type }}"
database_username: "{{ deployment_type }}"
tower_task_privileged: false
tower_ingress_type: none
task_privileged: false
service_type: ClusterIP
ingress_type: none
# Add annotations to the service account. Specify as literal block. E.g.:
# service_account_annotations: |
# eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME>
service_account_annotations: ''
# Custom labels for the tower service. Specify as literal block. E.g.:
# service_labels: |
# environment: non-production
# zone: internal
service_labels: ''
# Add annotations to the ingress. Specify as literal block. E.g.:
# tower_ingress_annotations: |
# ingress_annotations: |
# kubernetes.io/ingress.class: nginx
# nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s
tower_ingress_annotations: ''
ingress_annotations: ''
# TLS secret for the ingress. The secret either has to exist before hand with
# the corresponding cert and key or just be an indicator for where an automated
# process like cert-manager (enabled via annotations) will store the TLS
# certificate and key.
tower_ingress_tls_secret: ''
ingress_tls_secret: ''
tower_loadbalancer_protocol: 'http'
tower_loadbalancer_port: '80'
loadbalancer_protocol: 'http'
loadbalancer_port: '80'
loadbalancer_annotations: ''
# The TLS termination mechanism to use to access
# the services. Supported mechanism are: edge, passthrough
#
tower_route_tls_termination_mechanism: edge
route_tls_termination_mechanism: edge
# Secret to lookup that provide the TLS specific
# credentials to deploy
#
tower_route_tls_secret: ''
route_tls_secret: ''
# Host to create the root with.
# If not specific will default to <instance-name>-<namespace>-<routerCanonicalHostname>
#
tower_route_host: ''
route_host: ''
tower_hostname: '{{ deployment_type }}.example.com'
hostname: '{{ meta.name }}.example.com'
# Add a nodeSelector for the AWX pods. It must match a node's labels for the pod
# to be scheduled on that node. Specify as literal block. E.g.:
# tower_node_selector: |
# node_selector: |
# disktype: ssd
# kubernetes.io/arch: amd64
# kubernetes.io/os: linux
tower_node_selector: ''
node_selector: ''
# Add node tolerations for the AWX pods. Specify as literal block. E.g.:
# tower_tolerations: |
# tolerations: |
# - key: "dedicated"
# operator: "Equal"
# value: "AWX"
# effect: "NoSchedule"
tower_tolerations: ''
tolerations: ''
tower_admin_user: admin
tower_admin_email: test@example.com
admin_user: admin
admin_email: test@example.com
# Secret to lookup that provide the admin password
#
tower_admin_password_secret: ''
admin_password_secret: ''
# Secret to lookup that provide the broadcast websocket key
#
tower_broadcast_websocket_secret: ''
broadcast_websocket_secret: ''
# Secret to lookup that provide the secret key
#
tower_secret_key_secret: ''
secret_key_secret: ''
# Secret to lookup that provide the PostgreSQL configuration
#
postgres_configuration_secret: ''
# Secret to lookup that provides old database credentials (for migration)
tower_old_postgres_configuration_secret: ''
old_postgres_configuration_secret: ''
# Secret to lookup that provides default execution environment pull credentials
#
ee_pull_credentials_secret: ''
# Add extra volumes to the AWX pod. Specify as literal block. E.g.:
# tower_extra_volumes: |
# extra_volumes: |
# - name: my-volume
# emptyDir: {}
tower_extra_volumes: ''
extra_volumes: ''
# Use these image versions for Ansible AWX.
tower_image: quay.io/ansible/awx:19.0.0
tower_image_pull_policy: IfNotPresent
tower_image_pull_secret: ''
image: quay.io/ansible/awx
image_version: 19.2.2
redis_image: docker.io/redis
redis_image_version: latest
postgres_image: postgres
postgres_image_version: 12
init_container_image: quay.io/centos/centos
init_container_image_version: 8
image_pull_policy: IfNotPresent
image_pull_secret: ''
tower_ee_images:
- name: AWX EE 0.1.1
image: quay.io/ansible/awx-ee:0.1.1
ee_images:
- name: AWX EE 0.5.0
image: quay.io/ansible/awx-ee:0.5.0
tower_create_preload_data: true
control_plane_ee_image: quay.io/ansible/awx-ee:0.5.0
tower_replicas: "1"
create_preload_data: true
tower_task_args:
replicas: "1"
task_args:
- /usr/bin/launch_awx_task.sh
tower_task_command: []
tower_web_args: []
tower_web_command: []
task_command: []
web_args: []
web_command: []
tower_task_resource_requirements:
task_resource_requirements:
requests:
cpu: 500m
memory: 1Gi
tower_web_resource_requirements:
web_resource_requirements:
requests:
cpu: 1000m
memory: 2Gi
ee_resource_requirements:
requests:
cpu: 500m
memory: 1Gi
# Add extra environment variables to the AWX task/web containers. Specify as
# literal block. E.g.:
# tower_task_extra_env: |
# task_extra_env: |
# - name: FOO
# value: bar
# - name: BAZ
# value: bing
tower_task_extra_env: ''
tower_web_extra_env: ''
task_extra_env: ''
web_extra_env: ''
ee_extra_env: ''
# Mount extra volumes on the AWX task/web containers. Specify as literal block.
# E.g.:
# tower_task_extra_volume_mounts: ''
# task_extra_volume_mounts: ''
# - name: my-volume
# mountPath: /some/path
tower_task_extra_volume_mounts: ''
tower_web_extra_volume_mounts: ''
task_extra_volume_mounts: ''
web_extra_volume_mounts: ''
ee_extra_volume_mounts: ''
tower_redis_image: redis:latest
# Add a nodeSelector for the Postgres pods.
# It must match a node's labels for the pod to be scheduled on that node.
# Specify as literal block. E.g.:
# postgres_selector: |
# disktype: ssd
# kubernetes.io/arch: amd64
# kubernetes.io/os: linux
postgres_selector: ''
tower_postgres_image: postgres:12
tower_postgres_resource_requirements:
# Add node tolerations for the Postgres pods.
# Specify as literal block. E.g.:
# postgres_tolerations: |
# - key: "dedicated"
# operator: "Equal"
# value: "AWX"
# effect: "NoSchedule"
postgres_tolerations: ''
postgres_storage_requirements:
requests:
storage: 8Gi
tower_postgres_storage_class: ''
tower_postgres_data_path: '/var/lib/postgresql/data/pgdata'
postgres_resource_requirements: {}
postgres_data_path: '/var/lib/postgresql/data/pgdata'
# Persistence to the AWX project data folder
# Whether or not the /var/lib/projects directory will be persistent
tower_projects_persistence: false
projects_persistence: false
#
# Define an existing PersistentVolumeClaim to use
tower_projects_existing_claim: ''
projects_existing_claim: ''
#
# Define the storage_class, size and access_mode
# when not using an existing claim
tower_projects_storage_class: ''
tower_projects_storage_size: 8Gi
tower_projects_storage_access_mode: ReadWriteMany
# Secret to lookup that provide the PostgreSQL configuration
#
tower_postgres_configuration_secret: ''
projects_storage_size: 8Gi
projects_storage_access_mode: ReadWriteMany
ca_trust_bundle: "/etc/pki/tls/certs/ca-bundle.crt"
@@ -159,4 +208,12 @@ ca_trust_bundle: "/etc/pki/tls/certs/ca-bundle.crt"
#
ldap_cacert_secret: ''
# Secret to lookup that provides the custom CA trusted bundle
bundle_cacert_secret: ''
# Whether secrets should be garbage collected
# on teardown
#
garbage_collect_secrets: false
development_mode: false

View File

@@ -28,5 +28,5 @@ galaxy_info:
dependencies: []
collections:
- community.kubernetes
- kubernetes.core
- operator_sdk.util

View File

@@ -3,9 +3,9 @@
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ tower_admin_password_secret }}'
name: '{{ admin_password_secret }}'
register: _custom_admin_password
when: tower_admin_password_secret | length
when: admin_password_secret | length
- name: Check for default admin password configuration
k8s_info:
@@ -22,7 +22,7 @@
- name: Create admin password secret
k8s:
apply: true
definition: "{{ lookup('template', 'tower_admin_password_secret.yaml.j2') }}"
definition: "{{ lookup('template', 'admin_password_secret.yaml.j2') }}"
- name: Read admin password secret
k8s_info:
@@ -35,8 +35,8 @@
- name: Set admin password secret
set_fact:
admin_password_secret: '{{ _generated_admin_password["resources"] | default([]) | length | ternary(_generated_admin_password, _admin_password_secret) }}'
__admin_password_secret: '{{ _generated_admin_password["resources"] | default([]) | length | ternary(_generated_admin_password, _admin_password_secret) }}'
- name: Store admin password
set_fact:
tower_admin_password: "{{ admin_password_secret['resources'][0]['data']['password'] | b64decode }}"
admin_password: "{{ __admin_password_secret['resources'][0]['data']['password'] | b64decode }}"

View File

@@ -3,9 +3,9 @@
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ tower_broadcast_websocket_secret }}'
name: '{{ broadcast_websocket_secret }}'
register: _custom_broadcast_websocket
when: tower_broadcast_websocket_secret | length
when: broadcast_websocket_secret | length
- name: Check for default broadcast websocket secret configuration
k8s_info:
@@ -23,7 +23,7 @@
- name: Create broadcast websocket secret
k8s:
apply: true
definition: "{{ lookup('template', 'tower_broadcast_websocket_secret.yaml.j2') }}"
definition: "{{ lookup('template', 'broadcast_websocket_secret.yaml.j2') }}"
- name: Read broadcast websocket secret
k8s_info:
@@ -37,8 +37,8 @@
- name: Set broadcast websocket secret
set_fact:
# yamllint disable-line rule:line-length
broadcast_websocket_secret: '{{ _generated_broadcast_websocket["resources"] | default([]) | length | ternary(_generated_broadcast_websocket, _broadcast_websocket_secret) }}' # noqa 204
__broadcast_websocket_secret: '{{ _generated_broadcast_websocket["resources"] | default([]) | length | ternary(_generated_broadcast_websocket, _broadcast_websocket_secret) }}' # noqa 204
- name: Store broadcast websocket secret name
set_fact:
broadcast_websocket_secret_value: "{{ broadcast_websocket_secret['resources'][0]['data']['secret'] | b64decode }}"
broadcast_websocket_secret_value: "{{ __broadcast_websocket_secret['resources'][0]['data']['secret'] | b64decode }}"

View File

@@ -0,0 +1,27 @@
---
- block:
- name: Define secrets name
set_fact:
_admin_password: '{{ admin_password_secret | length | ternary(admin_password_secret, meta.name + "-admin-password") }}'
_secret_key: '{{ secret_key_secret | length | ternary(secret_key_secret, meta.name + "-secret-key") }}'
# yamllint disable-line rule:line-length
_broadcast_websocket_secret: '{{ broadcast_websocket_secret | length | ternary(broadcast_websocket_secret, meta.name + "-broadcast-websocket") }}' # noqa 204
# yamllint disable-line rule:line-length
_postgres_configuration: '{{ postgres_configuration_secret | length | ternary(postgres_configuration_secret, meta.name + "-postgres-configuration") }}' # noqa 204
- name: Remove ownerReferences reference
k8s:
definition:
apiVersion: v1
kind: Secret
metadata:
name: '{{ item }}'
namespace: '{{ meta.namespace }}'
ownerReferences: null
loop:
- '{{ _admin_password }}'
- '{{ _secret_key }}'
- '{{ _postgres_configuration }}'
- '{{ _broadcast_websocket_secret }}'
when: not garbage_collect_secrets | bool

View File

@@ -3,9 +3,9 @@
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ tower_postgres_configuration_secret }}'
name: '{{ postgres_configuration_secret }}'
register: _custom_pg_config_resources
when: tower_postgres_configuration_secret | length
when: postgres_configuration_secret | length
- name: Check for default PostgreSQL configuration
k8s_info:
@@ -18,9 +18,9 @@
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ tower_old_postgres_configuration_secret }}'
name: '{{ old_postgres_configuration_secret }}'
register: _custom_old_pg_config_resources
when: tower_old_postgres_configuration_secret | length
when: old_postgres_configuration_secret | length
- name: Check for default old PostgreSQL configuration
k8s_info:
@@ -50,7 +50,7 @@
- name: Create Database configuration
k8s:
apply: true
definition: "{{ lookup('template', 'tower_postgres_secret.yaml.j2') }}"
definition: "{{ lookup('template', 'postgres_secret.yaml.j2') }}"
- name: Read Database Configuration
k8s_info:
@@ -64,12 +64,45 @@
set_fact:
pg_config: '{{ _generated_pg_config_resources["resources"] | default([]) | length | ternary(_generated_pg_config_resources, _pg_config) }}'
- name: Create Database if no database is specified
k8s:
apply: true
definition: "{{ lookup('template', 'tower_postgres.yaml.j2') }}"
when:
- pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed'
- name: Set actual postgres configuration secret used
set_fact:
__postgres_configuration_secret: "{{ pg_config['resources'][0]['metadata']['name'] }}"
- block:
- name: Create Database if no database is specified
k8s:
apply: true
definition: "{{ lookup('template', 'postgres.yaml.j2') }}"
register: create_statefulset_result
rescue:
- name: Scale down Deployment for migration
include_tasks: scale_down_deployment.yml
- name: Scale down PostgreSQL statefulset for migration
kubernetes.core.k8s_scale:
api_version: apps/v1
kind: StatefulSet
name: "{{ meta.name }}-postgres"
namespace: "{{ meta.namespace }}"
replicas: 0
wait: yes
- name: Remove PostgreSQL statefulset for upgrade
k8s:
state: absent
api_version: apps/v1
kind: StatefulSet
name: "{{ meta.name }}-postgres"
namespace: "{{ meta.namespace }}"
wait: yes
when: create_statefulset_result.error == 422
- name: Recreate PostgreSQL statefulset with updated values
k8s:
apply: true
definition: "{{ lookup('template', 'postgres.yaml.j2') }}"
when: pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed'
- name: Store Database Configuration
set_fact:
@@ -78,11 +111,12 @@
awx_postgres_database: "{{ pg_config['resources'][0]['data']['database'] | b64decode }}"
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
awx_postgres_sslmode: "{{ pg_config['resources'][0]['data']['sslmode'] | default('prefer'|b64encode) | b64decode }}"
- name: Look up details for this deployment
k8s_info:
api_version: 'v1beta1' # TODO: How to parameterize this?
kind: "AWX" # TODO: How to parameterize this?
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
register: this_awx
@@ -92,4 +126,4 @@
when:
- old_pg_config['resources'] is defined
- old_pg_config['resources'] | length
- this_awx['resources'][0]['status']['towerMigratedFromSecret'] is not defined
- this_awx['resources'][0]['status']['migratedFromSecret'] is not defined

View File

@@ -1,36 +0,0 @@
---
- name: Check if there are any super users defined.
community.kubernetes.k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "echo 'from django.contrib.auth.models import User;
nsu = User.objects.filter(is_superuser=True).count();
exit(0 if nsu > 0 else 1)'
| awx-manage shell"
ignore_errors: true
register: users_result
changed_when: users_result.return_code > 0
- name: Create super user via Django if it doesn't exist.
community.kubernetes.k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "echo \"from django.contrib.auth.models import User;
User.objects.create_superuser('{{ tower_admin_user }}', '{{ tower_admin_email }}', '{{ tower_admin_password }}')\"
| awx-manage shell"
when: users_result.return_code > 0
- name: Create preload data if necessary. # noqa 305
community.kubernetes.k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage create_preload_data"
register: cdo
changed_when: "'added' in cdo.stdout"
when: tower_create_preload_data | bool

View File

@@ -0,0 +1,120 @@
---
- name: Check if there are any super users defined.
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "echo 'from django.contrib.auth.models import User;
nsu = User.objects.filter(is_superuser=True, username=\"{{ admin_user }}\").count();
exit(0 if nsu > 0 else 1)'
| awx-manage shell"
ignore_errors: true
register: users_result
changed_when: users_result.return_code > 0
- name: Update super user password via Django if it does exist (same password is a noop)
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage update_password --username '{{ admin_user }}' --password '{{ admin_password }}'"
register: update_pw_result
changed_when: users_result.stdout == 'Password not updated'
when: users_result.return_code == 0
- name: Create super user via Django if it doesn't exist.
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "echo \"from django.contrib.auth.models import User;
User.objects.create_superuser('{{ admin_user }}', '{{ admin_email }}', '{{ admin_password }}')\"
| awx-manage shell"
when: users_result.return_code > 0
- name: Create preload data if necessary. # noqa 305
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage create_preload_data"
register: cdo
changed_when: "'added' in cdo.stdout"
when: create_preload_data | bool
- name: Check if legacy queue is present
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage list_instances | grep '^\[tower capacity=[0-9]*\]'"
register: legacy_queue
changed_when: false
- name: Unregister legacy queue
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage unregister_queue --queuename=tower"
when: "'[tower capacity=' in legacy_queue.stdout"
- name: Check for specified default execution environment pull credentials
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ ee_pull_credentials_secret }}'
register: _custom_execution_environments_pull_credentials
when: ee_pull_credentials_secret | length
- name: Check for default execution environment pull credentials
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-ee-pull-credentials'
register: _default_execution_environments_pull_credentials
- name: Set admin password secret
set_fact:
_execution_environments_pull_credentials: >-
{{ _custom_execution_environments_pull_credentials["resources"] | default([]) | length
| ternary(_custom_execution_environments_pull_credentials, _default_execution_environments_pull_credentials) }}
- name: Register default execution environments (without authentication)
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage register_default_execution_environments"
register: ree
changed_when: "'changed: True' in ree.stdout"
when: not _execution_environments_pull_credentials['resources'] | default([]) | length
- block:
- name: Store default execution environment pull credentials
set_fact:
default_execution_environment_pull_credentials_user: "{{ _execution_environments_pull_credentials['resources'][0]['data']['username'] | b64decode }}"
default_execution_environment_pull_credentials_pass: "{{ _execution_environments_pull_credentials['resources'][0]['data']['password'] | b64decode }}"
default_execution_environment_pull_credentials_url: "{{ _execution_environments_pull_credentials['resources'][0]['data']['url'] | b64decode }}"
default_execution_environment_pull_credentials_url_verify: >-
{{ _execution_environments_pull_credentials['resources'][0]['data']['ssl_verify'] | default("True"|b64encode) | b64decode }}
- name: Register default execution environments (with authentication)
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage register_default_execution_environments
--registry-username='{{ default_execution_environment_pull_credentials_user }}'
--registry-password='{{ default_execution_environment_pull_credentials_pass }}'
--registry-url='{{ default_execution_environment_pull_credentials_url }}'
--verify-ssl='{{ default_execution_environment_pull_credentials_url_verify }}'"
register: ree
changed_when: "'changed: True' in ree.stdout"
when: _execution_environments_pull_credentials['resources'] | default([]) | length

View File

@@ -0,0 +1,12 @@
---
- name: Retrieve bundle Certificate Authority Secret
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ bundle_cacert_secret }}'
register: bundle_cacert
- name: Load bundle Certificate Authority Secret content
set_fact:
bundle_ca_crt: '{{ bundle_cacert["resources"][0]["data"]["bundle-ca.crt"] | b64decode }}'
when: '"bundle-ca.crt" in bundle_cacert["resources"][0]["data"]'

View File

@@ -1,6 +1,6 @@
---
- name: Retrieve LDAP CA Certificate Secret
community.kubernetes.k8s_info:
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ ldap_cacert_secret }}'

View File

@@ -1,17 +1,17 @@
---
- name: Retrieve Route TLS Secret
community.kubernetes.k8s_info:
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ tower_route_tls_secret }}'
name: '{{ route_tls_secret }}'
register: route_tls
- name: Load Route TLS Secret content
set_fact:
tower_route_tls_key: '{{ route_tls["resources"][0]["data"]["tls.key"] | b64decode }}'
tower_route_tls_crt: '{{ route_tls["resources"][0]["data"]["tls.crt"] | b64decode }}'
route_tls_key: '{{ route_tls["resources"][0]["data"]["tls.key"] | b64decode }}'
route_tls_crt: '{{ route_tls["resources"][0]["data"]["tls.crt"] | b64decode }}'
- name: Load Route TLS Secret content
set_fact:
tower_route_ca_crt: '{{ route_tls["resources"][0]["data"]["ca.crt"] | b64decode }}'
route_ca_crt: '{{ route_tls["resources"][0]["data"]["ca.crt"] | b64decode }}'
when: '"ca.crt" in route_tls["resources"][0]["data"]'

View File

@@ -3,8 +3,8 @@
k8s:
state: present
definition:
apiVersion: awx.ansible.com/v1beta1
kind: AWX
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
metadata:
@@ -13,12 +13,9 @@
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
- name: Get current version
set_fact:
tower_image_version: "{{ tower_image.split(':')[1] }}"
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
- name: Include secret key configuration tasks
include_tasks: secret_key_configuration.yml
@@ -28,6 +25,11 @@
when:
- ldap_cacert_secret != ''
- name: Load bundle certificate authority certificate
include_tasks: load_bundle_cacert_secret.yml
when:
- bundle_cacert_secret != ''
- name: Include admin password configuration tasks
include_tasks: admin_password_configuration.yml
@@ -40,50 +42,11 @@
- name: Load Route TLS certificate
include_tasks: load_route_tls_secret.yml
when:
- tower_ingress_type | lower == 'route'
- tower_route_tls_secret != ''
- ingress_type | lower == 'route'
- route_tls_secret != ''
- name: Ensure configured instance resources exist in the cluster.
k8s:
apply: yes
definition: "{{ lookup('template', item) | from_yaml_all | list }}"
with_items:
- tower_config.yaml.j2
- name: Apply Resources
k8s:
apply: yes
definition: "{{ lookup('template', item + '.yaml.j2') }}"
register: tower_deployment_result
loop:
- 'tower_app_credentials'
- 'tower_service_account'
- 'tower_persistent'
- 'tower_deployment'
- 'tower_service'
- 'tower_ingress'
- name: Get the resource pod information.
k8s_info:
kind: Pod
namespace: '{{ meta.namespace }}'
label_selectors:
- "app.kubernetes.io/name={{ meta.name }}"
- "app.kubernetes.io/managed-by=awx-operator"
- "app.kubernetes.io/component=awx"
register: tower_pods
until: "tower_pods['resources'][0]['status']['phase'] == 'Running'"
delay: 5
retries: 60
- name: Set the resource pod name as a variable.
set_fact:
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] }}"
- name: Verify the resource pod name is populated.
assert:
that: tower_pod_name != ''
fail_msg: "Could not find the tower pod's name."
- name: Include resources configuration tasks
include_tasks: resources_configuration.yml
- name: Check for pending migrations
k8s_exec:
@@ -107,7 +70,11 @@
- database_check is defined
- (database_check.stdout|trim) != '0'
- include_tasks: initialize.yml
- name: Initialize Django
include_tasks: initialize_django.yml
- name: Update status variables
include_tasks: update_status.yml
- name: Cleanup & Set garbage collection refs
include_tasks: cleanup.yml

View File

@@ -1,21 +1,33 @@
---
- name: Set actual old postgres configuration secret name
set_fact:
old_postgres_configuration_name: "{{ old_pg_config['resources'][0]['metadata']['name'] }}"
- name: Store Database Configuration
set_fact:
tower_old_postgres_user: "{{ old_pg_config['resources'][0]['data']['username'] | b64decode }}"
tower_old_postgres_pass: "{{ old_pg_config['resources'][0]['data']['password'] | b64decode }}"
tower_old_postgres_database: "{{ old_pg_config['resources'][0]['data']['database'] | b64decode }}"
tower_old_postgres_port: "{{ old_pg_config['resources'][0]['data']['port'] | b64decode }}"
tower_old_postgres_host: "{{ old_pg_config['resources'][0]['data']['host'] | b64decode }}"
awx_old_postgres_user: "{{ old_pg_config['resources'][0]['data']['username'] | b64decode }}"
awx_old_postgres_pass: "{{ old_pg_config['resources'][0]['data']['password'] | b64decode }}"
awx_old_postgres_database: "{{ old_pg_config['resources'][0]['data']['database'] | b64decode }}"
awx_old_postgres_port: "{{ old_pg_config['resources'][0]['data']['port'] | b64decode }}"
awx_old_postgres_host: "{{ old_pg_config['resources'][0]['data']['host'] | b64decode }}"
- name: Default label selector to custom resource generated postgres
set_fact:
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ meta.name }}"
when: postgres_label_selector is not defined
- name: Get the postgres pod information
k8s_info:
kind: Pod
namespace: '{{ meta.namespace }}'
label_selectors:
- "app.kubernetes.io/name={{ meta.name }}-postgres"
name: '{{ meta.name }}-postgres-0' # using name to keep compatibility
field_selectors:
- status.phase=Running
register: postgres_pod
until: "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
until:
- "postgres_pod['resources'] | length"
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
delay: 5
retries: 60
@@ -23,47 +35,34 @@
set_fact:
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
- name: Check for presence of Deployment
k8s_info:
api_version: v1
kind: Deployment
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
register: tower_deployment
- name: Scale down Deployment for migration
k8s_scale:
api_version: v1
kind: Deployment
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
replicas: 0
when: tower_deployment['resources'] | length
include_tasks: scale_down_deployment.yml
- name: Set pg_dump command
set_fact:
pgdump: >-
pg_dump --clean --create
-h {{ tower_old_postgres_host }}
-U {{ tower_old_postgres_user }}
-d {{ tower_old_postgres_database }}
-p {{ tower_old_postgres_port }}
pg_dump
-h {{ awx_old_postgres_host }}
-U {{ awx_old_postgres_user }}
-d {{ awx_old_postgres_database }}
-p {{ awx_old_postgres_port }}
-F custom
- name: Set pg_restore command
set_fact:
psql_restore: >-
psql -U {{ database_username }}
-d template1
-p {{ awx_postgres_port }}
pg_restore: >-
pg_restore --clean --if-exists
-U {{ database_username }}
-d {{ database_name }}
- name: Stream backup from pg_dump to the new postgresql container
community.kubernetes.k8s_exec:
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ postgres_pod_name }}"
command: |
bash -c """
set -e -o pipefail
PGPASSWORD={{ tower_old_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ psql_restore }}
PGPASSWORD={{ awx_old_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ pg_restore }}
echo 'Successful'
"""
register: data_migration
@@ -71,4 +70,4 @@
- name: Set flag signifying that this instance has been migrated
set_fact:
tower_migrated_from_secret: "{{ tower_old_postgres_configuration_secret }}"
tower_migrated_from_secret: "{{ old_postgres_configuration_name }}"

View File

@@ -0,0 +1,80 @@
---
- name: Get the current resource pod information.
k8s_info:
api_version: v1
kind: Pod
namespace: '{{ meta.namespace }}'
label_selectors:
- "app.kubernetes.io/name={{ meta.name }}"
- "app.kubernetes.io/managed-by={{ deployment_type }}-operator"
- "app.kubernetes.io/component={{ deployment_type }}"
field_selectors:
- status.phase=Running
register: tower_pods
- name: Set the resource pod name as a variable.
set_fact:
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] | default('') }}"
- name: Apply Resources
k8s:
apply: yes
definition: "{{ lookup('template', item + '.yaml.j2') }}"
wait: yes
register: tower_resources_result
loop:
- 'config'
- 'app_credentials'
- 'service_account'
- 'persistent'
- 'service'
- 'ingress'
- name: Apply deployment resources
k8s:
apply: yes
definition: "{{ lookup('template', 'deployment.yaml.j2') }}"
wait: yes
register: tower_deployment_result
- block:
- name: Delete pod to reload a resource configuration
k8s:
api_version: v1
state: absent
kind: Pod
namespace: '{{ meta.namespace }}'
name: '{{ tower_pod_name }}'
wait: yes
when:
- tower_resources_result.changed
- tower_pod_name | length
- name: Get the new resource pod information after updating resource.
k8s_info:
kind: Pod
namespace: '{{ meta.namespace }}'
label_selectors:
- "app.kubernetes.io/name={{ meta.name }}"
- "app.kubernetes.io/managed-by={{ deployment_type }}-operator"
- "app.kubernetes.io/component={{ deployment_type }}"
field_selectors:
- status.phase=Running
register: _new_pod
until:
- _new_pod['resources'] | length
- _new_pod['resources'][0]['metadata']['name'] != tower_pod_name
delay: 5
retries: 60
- name: Update new resource pod name as a variable.
set_fact:
tower_pod_name: '{{ _new_pod["resources"][0]["metadata"]["name"] }}'
when:
- tower_resources_result.changed or tower_deployment_result.changed
- name: Verify the resource pod name is populated.
assert:
that: tower_pod_name != ''
fail_msg: "Could not find the tower pod's name."

View File

@@ -0,0 +1,19 @@
---
- name: Check for presence of Deployment
k8s_info:
api_version: v1
kind: Deployment
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
register: tower_deployment
- name: Scale down Deployment for migration
kubernetes.core.k8s_scale:
api_version: v1
kind: Deployment
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
replicas: 0
wait: yes
when: tower_deployment['resources'] | length

View File

@@ -3,9 +3,9 @@
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ tower_secret_key_secret }}'
name: '{{ secret_key_secret }}'
register: _custom_secret_key
when: tower_secret_key_secret | length
when: secret_key_secret | length
- name: Check for default secret key configuration
k8s_info:
@@ -22,7 +22,7 @@
- name: Create secret key secret
k8s:
apply: true
definition: "{{ lookup('template', 'tower_secret_key.yaml.j2') }}"
definition: "{{ lookup('template', 'secret_key.yaml.j2') }}"
- name: Read secret key secret
k8s_info:
@@ -35,8 +35,8 @@
- name: Set secret key secret
set_fact:
secret_key_secret: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}'
__secret_key_secret: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}'
- name: Store secret key secret name
set_fact:
secret_key_secret_name: "{{ secret_key_secret['resources'][0]['metadata']['name'] }}"
secret_key_secret_name: "{{ __secret_key_secret['resources'][0]['metadata']['name'] }}"

View File

@@ -1,9 +1,4 @@
---
- name: Set apiVersion and kind variables
set_fact:
api_version: '{{ hostvars["localhost"]["inventory_file"].split("/")[4:6] | join("/") }}'
kind: '{{ hostvars["localhost"]["inventory_file"].split("/")[6] }}'
- name: Update admin password status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
@@ -11,7 +6,7 @@
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
towerAdminPasswordSecret: "{{ admin_password_secret['resources'][0]['metadata']['name'] }}"
adminPasswordSecret: "{{ __admin_password_secret['resources'][0]['metadata']['name'] }}"
- name: Update admin user status
operator_sdk.util.k8s_status:
@@ -20,10 +15,37 @@
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
towerAdminUser: "{{ tower_admin_user }}"
adminUser: "{{ admin_user }}"
- name: Update postgres configuration status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
postgresConfigurationSecret: "{{ pg_config['resources'][0]['metadata']['name'] }}"
- name: Update broadcast websocket status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
broadcastWebsocketSecret: "{{ __broadcast_websocket_secret['resources'][0]['metadata']['name'] }}"
- name: Update secret key status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
secretKeySecret: "{{ secret_key_secret_name }}"
- name: Retrieve instance version
community.kubernetes.k8s_exec:
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
@@ -39,7 +61,7 @@
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
towerVersion: "{{ instance_version.stdout | trim }}"
version: "{{ instance_version.stdout | trim }}"
- name: Update image status
operator_sdk.util.k8s_status:
@@ -48,11 +70,11 @@
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
towerImage: "{{ tower_image }}"
image: "{{ image }}"
- block:
- name: Retrieve route URL
community.kubernetes.k8s_info:
k8s_info:
kind: Route
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}'
@@ -65,16 +87,16 @@
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
towerURL: "https://{{ route_url['resources'][0]['status']['ingress'][0]['host'] }}"
URL: "https://{{ route_url['resources'][0]['status']['ingress'][0]['host'] }}"
when: tower_ingress_type | lower == 'route'
when: ingress_type | lower == 'route'
- name: Update towerMigratedFromSecret status
- name: Update migratedFromSecret status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
towerMigratedFromSecret: "{{ tower_migrated_from_secret }}"
migratedFromSecret: "{{ tower_migrated_from_secret }}"
when: tower_migrated_from_secret is defined

View File

@@ -7,7 +7,8 @@ metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
stringData:
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -8,8 +8,9 @@ metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
data:
credentials.py: "{{ lookup('template', 'credentials.py.j2') | b64encode }}"
ldap.py: "{{ lookup('template', 'ldap.py.j2') | b64encode }}"

View File

@@ -7,7 +7,8 @@ metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
stringData:
secret: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -8,8 +8,9 @@ metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
data:
environment: |
AWX_SKIP_MIGRATIONS=true
@@ -45,7 +46,7 @@ data:
AWX_AUTO_DEPROVISION_INSTANCES = True
CLUSTER_HOST_ID = socket.gethostname()
SYSTEM_UUID = '00000000-0000-0000-0000-000000000000'
SYSTEM_UUID = os.environ.get('MY_POD_UID', '00000000-0000-0000-0000-000000000000')
CSRF_COOKIE_SECURE = False
SESSION_COOKIE_SECURE = False
@@ -77,7 +78,6 @@ data:
LOGGING['loggers']['social']['handlers'] = ['console']
LOGGING['loggers']['system_tracking_migrations']['handlers'] = ['console']
LOGGING['loggers']['rbac_migrations']['handlers'] = ['console']
LOGGING['loggers']['awx.isolated.manager.playbooks']['handlers'] = ['console']
LOGGING['handlers']['callback_receiver'] = {'class': 'logging.NullHandler'}
LOGGING['handlers']['task_system'] = {'class': 'logging.NullHandler'}
LOGGING['handlers']['tower_warnings'] = {'class': 'logging.NullHandler'}
@@ -89,6 +89,10 @@ data:
BROADCAST_WEBSOCKET_PORT = 8052
BROADCAST_WEBSOCKET_PROTOCOL = 'http'
{% for item in extra_settings | default([]) %}
{{ item.setting }} = {{ item.value }}
{% endfor %}
nginx_conf: |
worker_processes 1;
pid /tmp/nginx.pid;
@@ -126,7 +130,7 @@ data:
}
{% if tower_route_tls_termination_mechanism | lower == 'passthrough' %}
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
server {
listen 8052 default_server;
server_name _;
@@ -137,11 +141,16 @@ data:
{% endif %}
server {
{% if tower_route_tls_termination_mechanism | lower == 'passthrough' %}
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
listen 8053 ssl;
ssl_certificate /etc/nginx/pki/web.crt;
ssl_certificate_key /etc/nginx/pki/web.key;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
{% else %}
listen 8052 default_server;
{% endif %}
@@ -152,8 +161,6 @@ data:
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
add_header Content-Security-Policy "default-src 'self'; connect-src 'self' ws: wss:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' *.pendo.io; img-src 'self' *.pendo.io data:; report-uri /csp-violation/";
add_header X-Content-Security-Policy "default-src 'self'; connect-src 'self' ws: wss:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' *.pendo.io; img-src 'self' *.pendo.io data:; report-uri /csp-violation/";
# Protect against click-jacking https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009)
add_header X-Frame-Options "DENY";
@@ -170,7 +177,7 @@ data:
}
location /favicon.ico {
alias /var/lib/awx/public/static/favicon.ico;
alias /var/lib/awx/public/static/media/favicon.ico;
}
location /websocket {
@@ -206,6 +213,13 @@ data:
{%- endif %}
proxy_set_header X-Forwarded-Port 443;
uwsgi_param HTTP_X_FORWARDED_PORT 443;
add_header Strict-Transport-Security max-age=15768000;
# Protect against click-jacking https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009)
add_header X-Frame-Options "DENY";
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Expires "0";
add_header Pragma "no-cache";
}
}
}

View File

@@ -4,10 +4,10 @@ DATABASES = {
'ENGINE': 'awx.main.db.profiled_pg',
'NAME': "{{ awx_postgres_database }}",
'USER': "{{ awx_postgres_user }}",
'PASSWORD': "{{ awx_postgres_pass | quote }}",
'PASSWORD': "{{ awx_postgres_pass }}",
'HOST': '{{ awx_postgres_host }}',
'PORT': "{{ awx_postgres_port }}",
'OPTIONS': { 'sslmode': '{{ pg_sslmode|default("prefer") }}',
'OPTIONS': { 'sslmode': '{{ awx_postgres_sslmode }}',
'sslrootcert': '{{ ca_trust_bundle }}',
},
}

View File

@@ -7,33 +7,54 @@ metadata:
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/version: '{{ tower_image_version }}'
app.kubernetes.io/version: '{{ image_version }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
spec:
replicas: {{ tower_replicas }}
replicas: {{ replicas }}
selector:
matchLabels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
template:
metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/version: '{{ tower_image_version }}'
app.kubernetes.io/version: '{{ image_version }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
spec:
serviceAccountName: '{{ meta.name }}'
{% if tower_image_pull_secret %}
{% if image_pull_secret %}
imagePullSecrets:
- name: {{ tower_image_pull_secret }}
- name: {{ image_pull_secret }}
{% endif %}
{% if bundle_ca_crt %}
initContainers:
- name: init
image: '{{ init_container_image }}:{{ init_container_image_version }}'
imagePullPolicy: '{{ image_pull_policy }}'
command:
- /bin/sh
- -c
- |
mkdir -p /etc/pki/ca-trust/extracted/{java,pem,openssl,edk2}
update-ca-trust
volumeMounts:
- name: "ca-trust-extracted"
mountPath: "/etc/pki/ca-trust/extracted"
- name: "{{ meta.name }}-bundle-cacert"
mountPath: /etc/pki/ca-trust/source/anchors/bundle-ca.crt
subPath: bundle-ca.crt
readOnly: true
{% endif %}
containers:
- image: '{{ tower_redis_image }}'
- image: '{{ redis_image }}:{{ redis_image_version }}'
imagePullPolicy: '{{ image_pull_policy }}'
name: redis
args: ["redis-server", "/etc/redis.conf"]
volumeMounts:
@@ -45,25 +66,42 @@ spec:
mountPath: "/var/run/redis"
- name: "{{ meta.name }}-redis-data"
mountPath: "/data"
- image: '{{ tower_image }}'
- image: '{{ image }}:{{ image_version }}'
name: '{{ meta.name }}-web'
{% if tower_web_command %}
command: {{ tower_web_command }}
{% if web_command %}
command: {{ web_command }}
{% endif %}
{% if tower_web_args %}
args: {{ tower_web_args }}
{% if web_args %}
args: {{ web_args }}
{% endif %}
imagePullPolicy: '{{ tower_image_pull_policy }}'
imagePullPolicy: '{{ image_pull_policy }}'
ports:
- containerPort: 8052
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
{% if ingress_type | lower == 'route' and route_tls_termination_mechanism | lower == 'passthrough' %}
- containerPort: 8053
{% endif %}
volumeMounts:
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/"
{% if bundle_ca_crt %}
- name: "ca-trust-extracted"
mountPath: "/etc/pki/ca-trust/extracted"
- name: "{{ meta.name }}-bundle-cacert"
mountPath: /etc/pki/ca-trust/source/anchors/bundle-ca.crt
subPath: bundle-ca.crt
readOnly: true
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
{% endif %}
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/execution_environments.py"
subPath: execution_environments.py
readOnly: true
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/credentials.py"
subPath: credentials.py
readOnly: true
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/ldap.py"
subPath: ldap.py
readOnly: true
{% if ingress_type | lower == 'route' and route_tls_termination_mechanism | lower == 'passthrough' %}
- name: "{{ meta.name }}-nginx-certs"
mountPath: "/etc/nginx/pki"
readOnly: true
@@ -94,12 +132,14 @@ spec:
mountPath: "/var/run/awx-rsyslog"
- name: rsyslog-dir
mountPath: "/var/lib/awx/rsyslog"
- name: "{{ meta.name }}-projects"
mountPath: "/var/lib/awx/projects"
{% if development_mode | bool %}
- name: awx-devel
mountPath: "/awx_devel"
{% endif %}
{% if tower_web_extra_volume_mounts -%}
{{ tower_web_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% if web_extra_volume_mounts -%}
{{ web_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% endif %}
env:
- name: MY_POD_NAMESPACE
@@ -110,26 +150,43 @@ spec:
- name: AWX_KUBE_DEVEL
value: "1"
{% endif %}
{% if tower_web_extra_env -%}
{{ tower_web_extra_env | indent(width=12, indentfirst=True) }}
{% if web_extra_env -%}
{{ web_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
resources: {{ tower_web_resource_requirements }}
- image: '{{ tower_image }}'
resources: {{ web_resource_requirements }}
- image: '{{ image }}:{{ image_version }}'
name: '{{ meta.name }}-task'
imagePullPolicy: '{{ tower_image_pull_policy }}'
{% if tower_task_privileged == true %}
imagePullPolicy: '{{ image_pull_policy }}'
{% if task_privileged == true %}
securityContext:
privileged: true
{% endif %}
{% if tower_task_command %}
command: {{ tower_task_command }}
{% if task_command %}
command: {{ task_command }}
{% endif %}
{% if tower_task_args %}
args: {{ tower_task_args }}
{% if task_args %}
args: {{ task_args }}
{% endif %}
volumeMounts:
{% if bundle_ca_crt %}
- name: "ca-trust-extracted"
mountPath: "/etc/pki/ca-trust/extracted"
- name: "{{ meta.name }}-bundle-cacert"
mountPath: /etc/pki/ca-trust/source/anchors/bundle-ca.crt
subPath: bundle-ca.crt
readOnly: true
{% endif %}
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/"
mountPath: "/etc/tower/conf.d/execution_environments.py"
subPath: execution_environments.py
readOnly: true
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/credentials.py"
subPath: credentials.py
readOnly: true
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/ldap.py"
subPath: ldap.py
readOnly: true
- name: "{{ secret_key_secret_name }}"
mountPath: /etc/tower/SECRET_KEY
@@ -155,8 +212,8 @@ spec:
- name: awx-devel
mountPath: "/awx_devel"
{% endif %}
{% if tower_task_extra_volume_mounts -%}
{{ tower_task_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% if task_extra_volume_mounts -%}
{{ task_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% endif %}
env:
- name: SUPERVISOR_WEB_CONFIG_PATH
@@ -179,15 +236,24 @@ spec:
- name: AWX_KUBE_DEVEL
value: "1"
{% endif %}
{% if tower_task_extra_env -%}
{{ tower_task_extra_env | indent(width=12, indentfirst=True) }}
{% if task_extra_env -%}
{{ task_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
resources: {{ tower_task_resource_requirements }}
- image: '{{ tower_ee_images[0].image }}'
resources: {{ task_resource_requirements }}
- image: '{{ control_plane_ee_image }}'
name: '{{ meta.name }}-ee'
imagePullPolicy: '{{ tower_image_pull_policy }}'
imagePullPolicy: '{{ image_pull_policy }}'
resources: {{ ee_resource_requirements }}
args: ['receptor', '--config', '/etc/receptor.conf']
volumeMounts:
{% if bundle_ca_crt %}
- name: "ca-trust-extracted"
mountPath: "/etc/pki/ca-trust/extracted"
- name: "{{ meta.name }}-bundle-cacert"
mountPath: /etc/pki/ca-trust/source/anchors/bundle-ca.crt
subPath: bundle-ca.crt
readOnly: true
{% endif %}
- name: "{{ meta.name }}-receptor-config"
mountPath: "/etc/receptor.conf"
subPath: receptor.conf
@@ -196,26 +262,42 @@ spec:
mountPath: "/var/run/receptor"
- name: "{{ meta.name }}-projects"
mountPath: "/var/lib/awx/projects"
{% if development_mode | bool %}
{% if ee_extra_volume_mounts -%}
{{ ee_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% endif %}
env:
{% if development_mode | bool %}
- name: SDB_NOTIFY_HOST
valueFrom:
fieldRef:
fieldPath: status.podIP
{% endif %}
{% if tower_node_selector %}
nodeSelector:
{{ tower_node_selector | indent(width=8) }}
{% if ee_extra_env -%}
{{ ee_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
{% if tower_tolerations %}
{% if node_selector %}
nodeSelector:
{{ node_selector | indent(width=8) }}
{% endif %}
{% if tolerations %}
tolerations:
{{ tower_tolerations | indent(width=8) }}
{{ tolerations | indent(width=8) }}
{% endif %}
volumes:
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
{% if bundle_ca_crt %}
- name: "ca-trust-extracted"
emptyDir: {}
- name: "{{ meta.name }}-bundle-cacert"
secret:
secretName: "{{ bundle_cacert_secret }}"
items:
- key: bundle-ca.crt
path: 'bundle-ca.crt'
{% endif %}
{% if ingress_type | lower == 'route' and route_tls_termination_mechanism | lower == 'passthrough' %}
- name: "{{ meta.name }}-nginx-certs"
secret:
secretName: "{{ tower_route_tls_secret }}"
secretName: "{{ route_tls_secret }}"
items:
- key: tls.key
path: 'web.key'
@@ -283,10 +365,10 @@ spec:
- key: receptor_conf
path: receptor.conf
- name: "{{ meta.name }}-projects"
{% if tower_projects_persistence|bool %}
{% if projects_persistence|bool %}
persistentVolumeClaim:
{% if tower_projects_existing_claim %}
claimName: {{ tower_projects_existing_claim }}
{% if projects_existing_claim %}
claimName: {{ projects_existing_claim }}
{% else %}
claimName: '{{ meta.name }}-projects-claim'
{% endif %}
@@ -298,6 +380,6 @@ spec:
hostPath:
path: /awx_devel
{% endif %}
{% if tower_extra_volumes -%}
{{ tower_extra_volumes | indent(width=8, indentfirst=True) }}
{% if extra_volumes -%}
{{ extra_volumes | indent(width=8, indentfirst=True) }}
{% endif %}

View File

@@ -1,5 +1,6 @@
DEFAULT_EXECUTION_ENVIRONMENTS = [
{% for item in tower_ee_images %}
{'name': '{{ item.name }}' , 'image': '{{ item.image }}'}
GLOBAL_JOB_EXECUTION_ENVIRONMENTS = [
{% for item in ee_images %}
{'name': '{{ item.name }}' , 'image': '{{ item.image }}'},
{% endfor %}
]
CONTROL_PLANE_EXECUTION_ENVIRONMENT = '{{ control_plane_ee_image }}'

View File

@@ -0,0 +1,72 @@
{% if ingress_type|lower == "ingress" %}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: '{{ meta.name }}-ingress'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
{% if ingress_annotations %}
annotations:
{{ ingress_annotations | indent(width=4) }}
{% endif %}
spec:
rules:
- host: '{{ hostname }}'
http:
paths:
- path: /
backend:
serviceName: '{{ meta.name }}-service'
servicePort: 80
{% if ingress_tls_secret %}
tls:
- hosts:
- {{ hostname }}
secretName: {{ ingress_tls_secret }}
{% endif %}
{% endif %}
{% if ingress_type|lower == "route" %}
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
spec:
{% if route_host != '' %}
host: {{ route_host }}
{% endif %}
port:
targetPort: '{{ (route_tls_termination_mechanism | lower == "passthrough") | ternary("https", "http") }}'
tls:
insecureEdgeTerminationPolicy: Redirect
termination: {{ route_tls_termination_mechanism | lower }}
{% if route_tls_termination_mechanism | lower == 'edge' and route_tls_secret != '' %}
key: |-
{{ route_tls_key | indent(width=6, indentfirst=True) }}
certificate: |-
{{ route_tls_crt | indent(width=6, indentfirst=True) }}
{% if route_ca_crt is defined %}
caCertificate: |-
{{ route_ca_crt | indent(width=6, indentfirst=True) }}
{% endif %}
{% endif %}
to:
kind: Service
name: {{ meta.name }}-service
weight: 100
wildcardPolicy: None
{% endif %}

View File

@@ -0,0 +1,22 @@
{% if projects_persistence|bool and projects_existing_claim == '' %}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: '{{ meta.name }}-projects-claim'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
spec:
accessModes:
- {{ projects_storage_access_mode }}
resources:
requests:
storage: {{ projects_storage_size }}
{% if projects_storage_class is defined %}
storageClassName: {{ projects_storage_class }}
{% endif %}
{% endif %}

View File

@@ -0,0 +1,131 @@
# Postgres StatefulSet.
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: '{{ meta.name }}-postgres'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
app.kubernetes.io/component: database
spec:
selector:
matchLabels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
serviceName: '{{ meta.name }}'
replicas: 1
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
spec:
containers:
- image: '{{ postgres_image }}:{{ postgres_image_version }}'
imagePullPolicy: '{{ image_pull_policy }}'
name: postgres
env:
# For postgres_image based on rhel8/postgresql-12
- name: POSTGRESQL_DATABASE
valueFrom:
secretKeyRef:
name: '{{ __postgres_configuration_secret }}'
key: database
- name: POSTGRESQL_USER
valueFrom:
secretKeyRef:
name: '{{ __postgres_configuration_secret }}'
key: username
- name: POSTGRESQL_PASSWORD
valueFrom:
secretKeyRef:
name: '{{ __postgres_configuration_secret }}'
key: password
# For postgres_image based on postgres
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: '{{ __postgres_configuration_secret }}'
key: database
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: '{{ __postgres_configuration_secret }}'
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: '{{ __postgres_configuration_secret }}'
key: password
- name: PGDATA
value: '{{ postgres_data_path }}'
- name: POSTGRES_INITDB_ARGS
value: '{{ postgres_initdb_args }}'
- name: POSTGRES_HOST_AUTH_METHOD
value: '{{ postgres_host_auth_method }}'
ports:
- containerPort: {{ awx_postgres_port | default('5432')}}
name: postgres
volumeMounts:
- name: postgres
mountPath: '{{ postgres_data_path | dirname }}'
subPath: '{{ postgres_data_path | dirname | basename }}'
resources: {{ postgres_resource_requirements }}
{% if postgres_selector %}
nodeSelector:
{{ postgres_selector | indent(width=8) }}
{% endif %}
{% if postgres_tolerations %}
tolerations:
{{ postgres_tolerations | indent(width=8) }}
{% endif %}
volumeClaimTemplates:
- metadata:
name: postgres
spec:
accessModes:
- ReadWriteOnce
{% if postgres_storage_class is defined %}
storageClassName: '{{ postgres_storage_class }}'
{% endif %}
resources: {{ postgres_storage_requirements }}
# Postgres Service.
---
apiVersion: v1
kind: Service
metadata:
name: '{{ meta.name }}-postgres'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
app.kubernetes.io/component: database
spec:
ports:
- port: 5432
clusterIP: None
selector:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'

View File

@@ -8,8 +8,9 @@ metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
stringData:
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
username: '{{ database_username }}'

View File

@@ -7,7 +7,8 @@ metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
stringData:
secret_key: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -0,0 +1,53 @@
---
apiVersion: v1
kind: Service
metadata:
name: '{{ meta.name }}-service'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
{{ service_labels | indent(width=4) }}
{% if service_type | lower == 'loadbalancer' and loadbalancer_annotations %}
annotations:
{{ loadbalancer_annotations | indent(width=4) }}
{% endif %}
spec:
ports:
{% if service_type | lower != 'loadbalancer' and loadbalancer_protocol | lower != 'https' %}
- port: 80
protocol: TCP
targetPort: 8052
name: http
{% endif %}
{% if ingress_type | lower == 'route' and route_tls_termination_mechanism | lower == 'passthrough' %}
- port: 443
protocol: TCP
targetPort: 8053
name: https
{% endif %}
{% if service_type | lower == 'loadbalancer' and loadbalancer_protocol | lower == 'https' %}
- port: {{ loadbalancer_port }}
protocol: TCP
targetPort: 8052
name: https
{% elif service_type | lower == 'loadbalancer' and loadbalancer_protocol | lower != 'https' %}
- port: {{ loadbalancer_port }}
protocol: TCP
targetPort: 8052
name: http
{% endif %}
selector:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
{% if service_type | lower == "loadbalancer" %}
type: LoadBalancer
{% elif service_type | lower == "nodeport" %}
type: NodePort
{% else %}
type: ClusterIP
{% endif %}

View File

@@ -7,8 +7,13 @@ metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
{% if service_account_annotations %}
annotations:
{{ service_account_annotations | indent(width=4) }}
{% endif %}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
@@ -25,6 +30,9 @@ rules:
- apiGroups: [""]
resources: ["pods/attach"]
verbs: ["create"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "create", "delete"]
---
kind: RoleBinding

View File

@@ -1,70 +0,0 @@
{% if 'ingress' == tower_ingress_type|lower %}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: '{{ meta.name }}-ingress'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
{% if tower_ingress_annotations %}
annotations:
{{ tower_ingress_annotations | indent(width=4) }}
{% endif %}
spec:
rules:
- host: '{{ tower_hostname }}'
http:
paths:
- path: /
backend:
serviceName: '{{ meta.name }}-service'
servicePort: 80
{% if tower_ingress_tls_secret %}
tls:
- hosts:
- {{ tower_hostname }}
secretName: {{ tower_ingress_tls_secret }}
{% endif %}
{% endif %}
{% if 'route' == tower_ingress_type|lower %}
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
spec:
{% if tower_route_host != '' %}
host: {{ tower_route_host }}
{% endif %}
port:
targetPort: '{{ (tower_route_tls_termination_mechanism | lower == "passthrough") | ternary("https", "http") }}'
tls:
insecureEdgeTerminationPolicy: Redirect
termination: {{ tower_route_tls_termination_mechanism | lower }}
{% if tower_route_tls_termination_mechanism | lower == 'edge' and tower_route_tls_secret != '' %}
key: |-
{{ tower_route_tls_key | indent(width=6, indentfirst=True) }}
certificate: |-
{{ tower_route_tls_crt | indent(width=6, indentfirst=True) }}
{% if tower_route_ca_crt is defined %}
caCertificate: |-
{{ tower_route_ca_crt | indent(width=6, indentfirst=True) }}
{% endif %}
{% endif %}
to:
kind: Service
name: {{ meta.name }}-service
weight: 100
wildcardPolicy: None
{% endif %}

View File

@@ -1,21 +0,0 @@
{% if tower_projects_persistence|bool and tower_projects_existing_claim == '' %}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: '{{ meta.name }}-projects-claim'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
spec:
accessModes:
- {{ tower_projects_storage_access_mode }}
resources:
requests:
storage: {{ tower_projects_storage_size }}
{% if tower_projects_storage_class != '' %}
storageClassName: {{ tower_projects_storage_class }}
{% endif %}
{% endif %}

View File

@@ -1,93 +0,0 @@
# Postgres StatefulSet.
---
apiVersion: v1
kind: StatefulSet
metadata:
name: '{{ meta.name }}-postgres'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}-postgres'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: database
spec:
selector:
matchLabels:
app.kubernetes.io/name: '{{ meta.name }}-postgres'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: database
serviceName: '{{ meta.name }}'
replicas: 1
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/name: '{{ meta.name }}-postgres'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: database
spec:
containers:
- image: '{{ tower_postgres_image }}'
name: postgres
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: '{{ meta.name }}-postgres-configuration'
key: database
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: '{{ meta.name }}-postgres-configuration'
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: '{{ meta.name }}-postgres-configuration'
key: password
- name: PGDATA
value: '{{ tower_postgres_data_path }}'
- name: POSTGRES_INITDB_ARGS
value: '{{ postgres_initdb_args }}'
- name: POSTGRES_HOST_AUTH_METHOD
value: '{{ postgres_host_auth_method }}'
ports:
- containerPort: 5432
name: postgres
volumeMounts:
- name: postgres
mountPath: '{{ tower_postgres_data_path | dirname }}'
subPath: '{{ tower_postgres_data_path | dirname | basename }}'
volumeClaimTemplates:
- metadata:
name: postgres
spec:
accessModes:
- ReadWriteOnce
{% if tower_postgres_storage_class != '' %}
storageClassName: '{{ tower_postgres_storage_class }}'
{% endif %}
resources: {{ tower_postgres_resource_requirements }}
# Postgres Service.
---
apiVersion: v1
kind: Service
metadata:
name: '{{ meta.name }}-postgres'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}-postgres'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: database
spec:
ports:
- port: 5432
clusterIP: None
selector:
app.kubernetes.io/name: '{{ meta.name }}-postgres'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: database

View File

@@ -1,49 +0,0 @@
---
apiVersion: v1
kind: Service
metadata:
name: '{{ meta.name }}-service'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
{% if tower_ingress_type | lower == 'loadbalancer' %}
annotations:
{{ tower_loadbalancer_annotations | indent(width=4) }}
{% endif %}
spec:
ports:
{% if tower_ingress_type | lower != 'loadbalancer' and tower_loadbalancer_protocol | lower != 'https' %}
- port: 80
protocol: TCP
targetPort: 8052
name: http
{% endif %}
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
- port: 443
protocol: TCP
targetPort: 8053
name: https
{% endif %}
{% if tower_ingress_type | lower == 'loadbalancer' and tower_loadbalancer_protocol | lower == 'https' %}
- port: {{ tower_loadbalancer_port }}
protocol: TCP
targetPort: 8052
name: https
{% elif tower_ingress_type | lower == 'loadbalancer' and tower_loadbalancer_protocol | lower != 'https' %}
- port: {{ tower_loadbalancer_port }}
protocol: TCP
targetPort: 8052
name: http
{% endif %}
selector:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/managed-by: awx-operator
app.kubernetes.io/component: awx
{% if tower_ingress_type | lower == "loadbalancer" %}
type: LoadBalancer
{% elif tower_ingress_type != "none" %}
type: NodePort
{% endif %}

View File

@@ -2,4 +2,5 @@
postgres_initdb_args: '--auth-host=scram-sha-256'
postgres_host_auth_method: 'scram-sha-256'
ldap_cacert_ca_crt: ''
tower_projects_existing_claim: ''
bundle_ca_crt: ''
projects_existing_claim: ''

121
roles/restore/README.md Normal file
View File

@@ -0,0 +1,121 @@
Restore Role
=========
The purpose of this role is to restore your AWX deployment from an existing PVC backup. The backup includes:
- custom deployment specific values in the spec section of the AWX custom resource object
- backup of the postgresql database
- secret_key, admin_password, and broadcast_websocket secrets
- database configuration
Requirements
------------
This role assumes you are authenticated with an Openshift or Kubernetes cluster:
- The awx-operator has been deployed to the cluster
- AWX is deployed to via the operator
- An AWX backup is available on a PVC in your cluster (see the backup [README.md](../backup/README.md))
Usage
----------------
Then create a file named `restore-awx.yml` with the following contents:
```yaml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWXRestore
metadata:
name: restore1
namespace: my-namespace
spec:
deployment_name: mytower
backup_name: awxbackup-2021-04-22
backup_pvc_namespace: 'old-awx-namespace'
```
Note that the `deployment_name` above is the name of the AWX deployment you intend to create and restore to.
The namespace specified is the namespace the resulting AWX deployment will be in. The namespace you specified must be pre-created.
```
kubectl create ns my-namespace
```
Finally, use `kubectl` to create the restore object in your cluster:
```bash
$ kubectl apply -f restore-awx.yml
```
This will create a new deployment and restore your backup to it.
> :warning: admin_password_secret value will replace the password for the `admin_user` user (by default, this is the `admin` user).
Role Variables
--------------
The name of the backup directory can be found as a status on your AWXBackup object. This can be found in your cluster's console, or with the client as shown below.
```bash
$ kubectl get awxbackup awxbackup1 -o jsonpath="{.items[0].status.backupDirectory}"
/backups/tower-openshift-backup-2021-04-02-03:25:08
```
```
backup_dir: '/backups/tower-openshift-backup-2021-04-02-03:25:08'
```
The name of the PVC can also be found by looking at the backup object.
```bash
$ kubectl get awxbackup awxbackup1 -o jsonpath="{.items[0].status.backupClaim}"
awx-backup-volume-claim
```
```
backup_pvc: 'awx-backup-volume-claim'
```
By default, the backup pvc will be created in the same namespace the awxbackup object is created in. This namespace must be specified using the `backup_pvc_namespace` variable.
```
backup_pvc_namespace: 'custom-namespace'
```
If a custom postgres configuration secret was used when deploying AWX, it must be set:
```
postgres_configuration_secret: 'awx-postgres-configuration'
```
If the awxbackup object no longer exists, it is still possible to restore from the backup it created by specifying the pvc name and the back directory.
```
backup_pvc: myoldtower-backup-claim
backup_dir: /backups/tower-openshift-backup-2021-04-02-03:25:08
```
Testing
----------------
You can test this role directly by creating and running the following playbook with the appropriate variables:
```
---
- name: Restore AWX
hosts: localhost
gather_facts: false
roles:
- restore
```
License
-------
MIT

View File

@@ -0,0 +1,12 @@
---
# Required: specify name of tower deployment to restore to
deployment_name: ''
kind: 'AWXRestore'
api_version: '{{ deployment_type }}.ansible.com/v1beta1'
# Required: specify a pre-created PVC (name) to restore from
backup_pvc: ''
backup_pvc_namespace: ''
# Required: backup name, found on the awxbackup object
backup_dir: ''

View File

@@ -0,0 +1,31 @@
---
galaxy_info:
author: Ansible
description: AWX role for AWX Operator for Kubernetes.
company: Red Hat, Inc.
license: MIT
min_ansible_version: 2.8
platforms:
- name: EL
versions:
- all
- name: Debian
versions:
- all
galaxy_tags:
- tower
- controller
- awx
- ansible
- restore
- automation
dependencies: []
collections:
- kubernetes.core
- operator_sdk.util

View File

@@ -0,0 +1,36 @@
---
- name: Delete any existing management pod
k8s:
name: "{{ meta.name }}-db-management"
kind: Pod
namespace: "{{ backup_pvc_namespace }}"
state: absent
force: true
- name: Remove ownerReferences from secrets to avoid garbage collection
k8s:
definition:
apiVersion: v1
kind: Secret
metadata:
name: '{{ item }}'
namespace: '{{ meta.namespace }}'
ownerReferences: null
loop:
- '{{ secret_key_secret }}'
- '{{ admin_password_secret }}'
- '{{ broadcast_websocket_secret }}'
- '{{ postgres_configuration_secret }}'
- name: Cleanup temp spec file
file:
path: "{{ tmp_spec.path }}"
state: absent
when: tmp_spec.path is defined
- name: Cleanup temp secret vars file
file:
path: "{{ secret_vars.path }}"
state: absent
when: secret_vars.path is defined

View File

@@ -0,0 +1,44 @@
---
- name: Get AWX object definition from pvc
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: >-
bash -c "cat '{{ backup_dir }}/awx_object'"
register: awx_object
- name: Create temp file for spec dict
tempfile:
state: file
register: tmp_spec
- name: Write spec vars to temp file
copy:
content: "{{ awx_object.stdout }}"
dest: "{{ tmp_spec.path }}"
mode: '0644'
- name: Include spec vars to save them as a dict
include_vars: "{{ tmp_spec.path }}"
- name: Deploy AWX
k8s:
state: "{{ state | default('present') }}"
namespace: "{{ meta.namespace }}"
apply: yes
definition: "{{ lookup('template', 'awx_object.yml.j2') }}"
wait: true
wait_condition:
type: "Running"
status: "True"
- name: Remove ownerReferences to prevent garbage collection of new AWX CRO
k8s:
definition:
apiVersion: '{{ api_version }}'
kind: AWX
metadata:
name: '{{ deployment_name }}'
namespace: '{{ meta.namespace }}'
ownerReferences: null

View File

@@ -0,0 +1,11 @@
---
- name: Determine the timestamp
set_fact:
now: '{{ lookup("pipe", "date +%FT%TZ") }}'
- name: Emit ocp event with error
k8s:
kind: Event
namespace: "{{ meta.namespace }}"
template: "event.yml.j2"

View File

@@ -0,0 +1,104 @@
---
- name: Set variables from awxbackup object statuses if provided
block:
- name: Look up details for the backup
k8s_info:
api_version: "{{ backup_api_version }}"
kind: "{{ backup_kind }}"
name: "{{ backup_name }}"
namespace: "{{ backup_pvc_namespace }}"
register: this_backup
- name: Surface error to user
block:
- name: Set error message
set_fact:
error_msg: "Cannot read the backup status variables for {{ backup_kind }} {{ backup_name }}."
- name: Handle error
import_tasks: error_handling.yml
- name: Fail early if pvc is defined but does not exist
fail:
msg: "{{ error_msg }}"
when:
- this_backup['resources'] | length == 0
- this_backup['resources'][0] is not defined
- this_backup['resources'][0]['status'] is not defined
- this_backup['resources'][0]['status']['backupClaim'] is not defined
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
- name: Set backup facts
set_fact:
backup_pvc: "{{ this_backup['resources'][0]['status']['backupClaim'] }}"
backup_dir: "{{ this_backup['resources'][0]['status']['backupDirectory'] }}"
when:
- backup_name != '' or backup_name is defined
# Check to make sure provided pvc exists, error loudly if not. Otherwise, the management pod will just stay in pending state forever.
- name: Check provided PVC exists
k8s_info:
name: "{{ backup_pvc }}"
kind: PersistentVolumeClaim
namespace: "{{ backup_pvc_namespace }}"
register: provided_pvc
when:
- backup_pvc != ''
- name: Surface error to user
block:
- name: Set error message
set_fact:
error_msg: "{{ backup_pvc }} does not exist, please create this pvc first."
- name: Handle error
import_tasks: error_handling.yml
- name: Fail early if pvc is defined but does not exist
fail:
msg: "{{ error_msg }}"
when:
- backup_pvc != ''
- provided_pvc.resources | length == 0
- name: Delete any existing management pod
k8s:
name: "{{ meta.name }}-db-management"
kind: Pod
namespace: "{{ backup_pvc_namespace }}"
state: absent
force: true
wait: true
- name: Create management pod from templated deployment config
k8s:
name: "{{ meta.name }}-db-management"
kind: Deployment
state: present
template: "management-pod.yml.j2"
wait: true
- name: Check to make sure backup directory exists on PVC
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ meta.name }}-db-management"
command: >-
bash -c "stat {{ backup_dir }}"
register: stat_backup_dir
- name: Error if backup dir is missing
block:
- name: Set error message
set_fact:
error_msg: "{{ backup_dir }} does not exist, see the backupDirectory status on your AWXBackup for the correct backup_dir."
- name: Handle error
import_tasks: error_handling.yml
- name: Fail early if backup dir provided does not exist
fail:
msg: "{{ error_msg }}"
when:
- backup_dir != ''
- stat_backup_dir.return_code != 0

View File

@@ -0,0 +1,47 @@
---
- name: Patching labels to {{ kind }} kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
metadata:
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
- name: Look up details for this restore object
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
register: this_restore
- block:
- include_tasks: init.yml
- include_tasks: secrets.yml
- include_tasks: deploy_awx.yml
- include_tasks: postgres.yml
- name: Set flag signifying this restore was successful
set_fact:
tower_restore_complete: True
- include_tasks: cleanup.yml
when:
- this_restore['resources'][0]['status']['restoreComplete'] is not defined
- name: Update status variables
include_tasks: update_status.yml

Some files were not shown because too many files have changed in this diff Show More