Compare commits

...

449 Commits

Author SHA1 Message Date
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
Shane McDonald
d8b7ed81b5 Merge pull request #189 from shanemcd/bump-19
Version bump for AWX 19
2021-04-07 18:00:16 -04:00
Shane McDonald
f4980917d2 Merge pull request #186 from tchellomello/build
Added build.sh to facilitate local tests
2021-04-07 17:27:45 -04:00
Shane McDonald
1c9173f48a Regenerate OLM metadata 2021-04-07 17:24:14 -04:00
Shane McDonald
f6b7a32a33 Bump version 2021-04-07 17:24:08 -04:00
Shane McDonald
aa03a7f268 Ensure CRD exists before deploying Operator 2021-04-07 17:20:52 -04:00
Shane McDonald
136b2c47f8 Remove unnecessary variables from molecule CR 2021-04-07 17:20:04 -04:00
Shane McDonald
0043c375d8 Merge pull request #184 from no-12/devel
add tower_image_pull_secret as property of AWX resource
2021-04-07 16:30:05 -04:00
Shane McDonald
c44c3fb095 Merge pull request #176 from rooftopcellist/fix-mismatched-db-name
Fix data migrations when the database names do not match
2021-04-07 16:29:52 -04:00
Shane McDonald
cb70e97366 Merge pull request #180 from tchellomello/add_labels_to_awx_kind
Added expected labels to AWX kind
2021-04-07 16:29:37 -04:00
Marcelo Moreira de Mello
1d21dc7f20 Added build.sh to facilitate local tests 2021-04-07 16:28:10 -04:00
Marcelo Moreira de Mello
4d4ed3e827 Added labels to AWX kind resource 2021-04-07 14:24:34 -04:00
Nico Ohnezat
0eb4286b71 add tower_image_pull_secret as property of AWX resource 2021-04-07 17:55:18 +02:00
Shane McDonald
f73cff3cb3 Merge pull request #177 from tchellomello/persistent_vol
Introducing ability to mount /var/lib/projects
2021-04-07 11:14:30 -04:00
Marcelo Moreira de Mello
54c8a7beef Fixed webUI form drop-down 2021-04-06 22:52:00 -04:00
Marcelo Moreira de Mello
584d45d315 Introducing ability to mount /var/lib/projects 2021-04-06 12:53:08 -04:00
Christian M. Adams
43aa01ce5f Fix data migrations when the database names do not match 2021-04-05 17:14:47 -04:00
Shane McDonald
a0c6565e59 Merge pull request #174 from shanemcd/cleanup
Clean up instances of tower_ee_image
2021-04-05 16:30:28 -04:00
Shane McDonald
bac795a36a Clean up instances of tower_ee_image 2021-04-05 15:50:29 -04:00
Shane McDonald
c9acc30009 Merge pull request #170 from tylerauerbeck/update-actions
Update GH Actions to run on push to devel
2021-04-03 17:34:45 -04:00
Shane McDonald
0cf0fd52c7 Merge pull request #171 from shanemcd/tower-ee-images
More flexibility for customizing default EEs
2021-04-03 17:32:27 -04:00
Shane McDonald
2b8530b3e2 Update instantiate playbook to document tower_ee_images 2021-04-03 17:21:53 -04:00
Shane McDonald
550756c33c Update CRD stuff related to tower_ee_image -> tower_ee_images rename 2021-04-03 17:21:49 -04:00
Shane McDonald
4230120884 More flexibility for customizing default EEs 2021-04-03 17:15:56 -04:00
Tyler Auerbeck
90b88676c5 Update README; Update GHA to run on push to devel 2021-04-03 14:42:24 -04:00
Shane McDonald
862123e2d6 Merge pull request #169 from shanemcd/fix-instantiate
Fix instantiate playbook when development_mode var is not provided
2021-04-03 13:05:42 -04:00
Shane McDonald
c1a2f6e649 Fix instantiate playbook when development_mode var is not provided 2021-04-03 12:54:43 -04:00
Shane McDonald
c0d3047dab Merge pull request #166 from ilijamt/wrong-supervisor-conf
fix wrong conf file for SUPERVISOR_WEB_CONFIG_PATH in kubernetes deployment file
2021-04-03 12:45:52 -04:00
Shane McDonald
1a50cd339e Merge pull request #162 from Spredzy/add_bundle_dockerfile
bundle.Dockerfile: Add the Dockerfile so user can build their own bundle
2021-04-03 12:45:30 -04:00
Shane McDonald
30db53d250 Merge pull request #164 from tchellomello/unique_labels
Use k8s labels to create unique matchLabels for svc and deployments
2021-04-03 12:44:31 -04:00
Shane McDonald
1309cc63c9 Merge pull request #165 from TrueTickets/athak/add-nodeselector-and-tolerations
Add support for nodeSelector and tolerations
2021-04-03 12:42:17 -04:00
Shane McDonald
32b862c79b Update roles/installer/templates/tower_deployment.yaml.j2 2021-04-03 12:36:55 -04:00
Shane McDonald
e09a468d2c Merge pull request #168 from shanemcd/goodbye-travis
Remove usage of Travis CI
2021-04-03 12:35:51 -04:00
Shane McDonald
adb896f294 Remove usage of Travis CI 2021-04-03 12:26:13 -04:00
Shane McDonald
2fd3158c7b Merge pull request #167 from shanemcd/remove-environment-sh
Remove usage of environment.sh
2021-04-03 12:25:20 -04:00
Shane McDonald
ba2672a0b0 Remove usage of environment.sh
This is no longer sourced in the launch scripts.
2021-04-03 12:07:02 -04:00
Shane McDonald
7c02a9728a Merge pull request #136 from tylerauerbeck/gha
Intial GH Actions - Publish latest build and CI
2021-04-03 11:58:55 -04:00
Ilija Matoski
9b327f6ad5 fix wrong conf file 2021-04-03 13:30:55 +02:00
Atha Kouroussis
2a3f700fde Update README and OLM catalog manifests 2021-04-02 11:03:54 -03:00
Yanis Guenane
d221c64f62 README.md: Extend README.md to explain how to generate the bundle 2021-04-02 15:43:26 +02:00
Yanis Guenane
0f1cc494fe bundle.Dockerfile: Add the Dockerfile so user can build their own bundle 2021-04-02 15:34:42 +02:00
Atha Kouroussis
be68adbf01 Add support for nodeSelector and tolerations 2021-04-01 18:28:07 -03:00
Marcelo Moreira de Mello
185238c199 Use k8s labels on managed resources 2021-04-01 14:04:59 -04:00
Yanis Guenane
210ac2c419 Merge pull request #157 from tchellomello/ldaps
Added ability to specify LDAP CA cert
2021-04-01 09:56:52 +02:00
Marcelo Moreira de Mello
658cf92a3b Make sure we only proceed with ldap-ca.crt is a valid secret 2021-03-31 11:25:25 -04:00
Yanis Guenane
d3f7594aea Merge pull request #160 from tchellomello/warning_admin_pass
tower_admin_password_secret warning note @ docs
2021-03-31 14:24:21 +02:00
Marcelo Moreira de Mello
939dd0b295 Warning for tower_admin_password_secret 2021-03-30 22:34:27 -04:00
Shane McDonald
51e384292c Merge pull request #159 from tchellomello/typo
Fixed typo on migration docs
2021-03-30 12:00:02 -04:00
Marcelo Moreira de Mello
f27f1d188c Fixed typo on migration docs 2021-03-30 10:44:28 -04:00
Marcelo Moreira de Mello
8974e3446a Added ability to configure LDAP CA 2021-03-29 22:19:22 -04:00
Shane McDonald
57a408e384 Merge pull request #155 from shanemcd/update-awx-ee
Use newer awx-ee image
2021-03-29 13:04:36 -04:00
Shane McDonald
1fa391a9f1 Bump awx-ee version 2021-03-29 12:39:57 -04:00
Shane McDonald
7885f8e454 Merge pull request #154 from starcraft66/patch-1
Create kustomization.yaml
2021-03-29 09:39:19 -04:00
Yanis Guenane
32ac0941dc Merge pull request #156 from Spredzy/hidden_tower_ee_image
olm-catalog: Set tower_ee_image as hidden
2021-03-29 14:48:24 +02:00
Yanis Guenane
371d826dd4 olm-catalog: Set tower_ee_image as hidden 2021-03-29 14:09:39 +02:00
Shane McDonald
aeebe6cc4b Allow group to access receptor socket 2021-03-28 15:09:18 -04:00
Shane McDonald
257a3ba807 Allow tower_ee_image to be specified in CR 2021-03-28 15:09:03 -04:00
Shane McDonald
ecdfaf6c0d Pin version of awx-ee 2021-03-28 15:08:49 -04:00
Shane McDonald
bc28071205 Update variable name 2021-03-28 15:07:39 -04:00
Shane McDonald
8962d501b3 Delete unnecessary file 2021-03-28 15:07:14 -04:00
Shane McDonald
e91031fa73 Fix deployment playbook 2021-03-28 15:06:41 -04:00
Tristan
cb2a059e16 Update kustomization.yaml 2021-03-28 01:25:18 -04:00
Tristan
5e5c7bbdaf Create kustomization.yaml
Creating a kustomization.yaml file will allow awx-operator to be added as a remote resource in a Kustomize deployment.
e.g. :
```
resources:
- https://github.com/ansible/awx-operator/deploy?ref=0.7.0
```
2021-03-28 01:10:50 -04:00
Shane McDonald
8b241e7871 Merge pull request #153 from billett83/devel
Handling HTTP loadbalancer
2021-03-26 09:54:49 -04:00
cbillett83@outlook.com
0740fc2bc1 fixes #151 Handling HTTP loadbalancer 2021-03-26 11:20:13 +00:00
billett83
a3cf6c4ea8 Merge pull request #2 from ansible/devel
merge changes
2021-03-26 11:05:21 +00:00
Shane McDonald
697ff11fa7 Merge pull request #144 from rooftopcellist/more_unique_pg_pod
Name pg pod in a more unique way
2021-03-25 11:20:14 -04:00
Yanis Guenane
0d6980b9b4 Merge pull request #145 from Spredzy/liveliness
Update liveness probe defaults
2021-03-24 21:04:48 +01:00
Yanis Guenane
387932e960 Update liveness probe defaults
The liveness probes default are too agressive and can lead to
undeployable operators[1][2] - We are bumping them as per the
operator-sdk default in 1.0[3]

[1] https://github.com/operator-framework/operator-sdk/issues/3216
[2] https://github.com/operator-framework/operator-sdk/issues/3267
[3]
ea43495073

Fixes: https://github.com/ansible/awx-operator/issues/131
2021-03-24 20:33:07 +01:00
Yanis Guenane
79e62755b8 Merge pull request #143 from Spredzy/update_bundle_params
Update bundle variables to catchup with latest commits
2021-03-24 20:25:38 +01:00
Christian M. Adams
746dc2738f Name pg pod in a more unique way
- this is to make it possible to run migration with multiple deployments in the same pod
2021-03-24 13:37:39 -04:00
Shane McDonald
7e67838adb Merge pull request #137 from Zokormazo/backup-read-default-old-configuration
Check the default old PostgreSQL configuration
2021-03-24 11:53:53 -04:00
Shane McDonald
7010ab1fc6 Update deploy/olm-catalog/awx-operator/manifests/awx-operator.clusterserviceversion.yaml 2021-03-24 11:52:33 -04:00
Shane McDonald
4eb4abf4f5 Merge pull request #141 from billett83/devel
fixes #140 - Allow for private hosted awx-ee image
2021-03-24 09:14:21 -04:00
Yanis Guenane
451e2b6497 Update bundle variables to catchup with latest commits 2021-03-24 14:07:36 +01:00
cbillett83@outlook.com
60479971b8 resolve build failure 2021-03-24 10:19:14 +00:00
cbillett83@outlook.com
76092c366e alow private hosted awx-ee image 2021-03-24 10:02:33 +00:00
billett83
e09c48d67c Merge pull request #1 from ansible/devel
Merge changes
2021-03-23 16:44:07 +00:00
Shane McDonald
556cb23a14 Merge pull request #138 from shanemcd/bump-18
Bump version / update default AWX image / fix CRD
2021-03-23 11:31:52 -04:00
Shane McDonald
62ec946e4f Use latest version of quay.io/ansible/awx 2021-03-23 11:15:55 -04:00
Shane McDonald
693ce5a17e Fix CRD
Fallout from https://github.com/ansible/awx-operator/pull/128
2021-03-23 11:15:51 -04:00
Shane McDonald
385a4f65a1 Bump version 2021-03-23 11:15:47 -04:00
Shane McDonald
3df272da27 Merge pull request #128 from billett83/devel
fixes #127 Provided service type LoadBalancer
2021-03-23 09:49:34 -04:00
Julen Landa Alustiza
60199f79aa Check the default old PostgreSQL configuration
Signed-off-by: Julen Landa Alustiza <jlanda@redhat.com>
2021-03-23 12:59:29 +01:00
Tyler Auerbeck
d713dce7e0 Intial GH Actions 2021-03-21 20:42:19 -04:00
Yanis Guenane
b00de51fb9 Merge pull request #132 from Spredzy/add_display_name
olm-catalog: Add displayName for the resource
2021-03-19 11:30:50 +01:00
Yanis Guenane
c81266af66 olm-catalog: Add displayName for the resource 2021-03-19 11:14:27 +01:00
Shane McDonald
c320dc835b Fix image 2021-03-18 14:17:13 -04:00
Shane McDonald
f47604998e Merge pull request #116 from rooftopcellist/backup_restore
Optional data migration if source DB configuration is provided
2021-03-18 14:15:30 -04:00
Shane McDonald
7d6743c44d Fix linter 2021-03-18 13:58:26 -04:00
Shane McDonald
bb519664cd Add seperate docs for migration 2021-03-18 12:33:05 -04:00
Shane McDonald
92a7bf22a1 Tweak migration logic 2021-03-18 12:31:02 -04:00
Shane McDonald
851ff16c0f Allow for overriding namespace when deploying via playbook 2021-03-18 11:22:04 -04:00
Shane McDonald
79534a1465 Dont require database names to match when doing migration 2021-03-18 11:22:04 -04:00
Shane McDonald
64c10f29c4 Uncomment status tasks 2021-03-18 11:22:04 -04:00
Shane McDonald
94a4861d13 Bulk removal of no_log statements
The operator would be impossible to debug with these
2021-03-18 11:22:04 -04:00
Shane McDonald
da26472a03 Fix reconcilation loop after data migration changes 2021-03-18 11:22:00 -04:00
cbillett83@outlook.com
76acd335b9 removed extra space 2021-03-18 11:12:03 +00:00
cbillett83@outlook.com
1570c0a883 Minor Changes from Spredzy 2021-03-18 10:58:00 +00:00
Christian M. Adams
c22577bc80 Make data migration idempotent 2021-03-17 16:03:46 -04:00
billett83
a65834dbf3 Update README.md
Co-authored-by: Shane McDonald <me@shanemcd.com>
2021-03-17 15:27:40 +00:00
billett83
e990c6bed2 Update README.md
Co-authored-by: Shane McDonald <me@shanemcd.com>
2021-03-17 15:27:35 +00:00
billett83
4297b158dc Update ansible/instantiate-awx-deployment.yml
Co-authored-by: Shane McDonald <me@shanemcd.com>
2021-03-17 15:27:30 +00:00
billett83
f099b15ff8 Update ansible/templates/crd.yml.j2
Co-authored-by: Shane McDonald <me@shanemcd.com>
2021-03-17 15:21:11 +00:00
billett83
add62c2973 Update deploy/awx-operator.yaml
Co-authored-by: Shane McDonald <me@shanemcd.com>
2021-03-17 15:20:33 +00:00
billett83
084e0b38a8 Update deploy/crds/awx_v1beta1_crd.yaml
Co-authored-by: Shane McDonald <me@shanemcd.com>
2021-03-17 15:20:25 +00:00
billett83
c6c94ce48d Update deploy/olm-catalog/awx-operator/manifests/awx-operator.clusterserviceversion.yaml
Co-authored-by: Shane McDonald <me@shanemcd.com>
2021-03-17 15:20:16 +00:00
cbillett83@outlook.com
781d3e0ec7 Provided service type LoadBalancer 2021-03-17 11:59:57 +00:00
Yanis Guenane
1cd93c6752 Merge pull request #125 from Spredzy/fix_wrong_variable_name
tower_deployment: Use the proper conditional variable
2021-03-17 10:50:34 +01:00
Christian M. Adams
e83e54419a Add no_log where needed, scale down pods before migration 2021-03-16 13:32:16 -04:00
Christian M. Adams
5b89c5c433 Clean db on Tower data is restored to 2021-03-16 13:32:15 -04:00
Christian M. Adams
0e1b12f4b1 Data migration from 3.8 to 4.0 via pg_dump streamed to psql 2021-03-16 13:32:15 -04:00
Christian M. Adams
93d53c712c Use k8s_exec tasks 2021-03-16 13:32:15 -04:00
Christian M. Adams
6a5bdaf2f7 init backup & restore 2021-03-16 13:32:15 -04:00
Shane McDonald
6cc3c47e33 Merge pull request #126 from dericcrago/image_pull_secret
added 'tower_image_pull_secret'
2021-03-15 12:26:01 -04:00
Deric Crago
1beae86c1d added 'tower_image_pull_secret' to 'README.md' 2021-03-15 11:47:07 -04:00
Deric Crago
7a559b9f3b added 'tower_image_pull_secret' 2021-03-15 11:27:37 -04:00
Yanis Guenane
cc3a752550 Merge pull request #120 from Spredzy/scram-sha
PostgreSQL: Set scram-sha-256 as default host auth method
2021-03-15 13:16:59 +01:00
Yanis Guenane
7442555869 tower_deployment: Use the proper conditional variable
fixes: https://github.com/ansible/awx-operator/issues/118
2021-03-15 12:58:14 +01:00
Yanis Guenane
10566b46b1 PostgreSQL: Set scram-sha-256 as default host auth method 2021-03-09 11:40:23 +01:00
Yanis Guenane
d32cf447ea Merge pull request #119 from Spredzy/better_passwords
Rely on /dev/null to generate passwords
2021-03-09 10:19:39 +01:00
Yanis Guenane
07dda4c8ef Rely on /dev/null to generate passwords 2021-03-09 10:01:38 +01:00
Yanis Guenane
a860b0f459 Merge pull request #115 from Spredzy/move_to_secret_base
Move tower_broadcast_websocket_secret to a Secret
2021-03-04 20:56:48 +01:00
Yanis Guenane
9683dc23a4 Move tower_broadcast_websocket_secret to a Secret 2021-03-04 20:21:38 +01:00
Shane McDonald
e4fd5aeb32 Merge pull request #76 from shanemcd/new-deployment-model
New deployment model
2021-03-04 11:46:46 -05:00
Shane McDonald
b1788be272 Merge pull request #1 from rooftopcellist/patch-ee-receptor
Dynamically set the deployment type for the configmap name
2021-03-03 15:46:30 -05:00
Christian M. Adams
92efe37100 Dynamically set the deployment type for the configmap name 2021-03-03 15:39:37 -05:00
Shane McDonald
21f284fb49 Ignore olm-catalog in yamllint 2021-03-03 13:13:12 -05:00
Shane McDonald
d53245b984 Regenerate bundle info 2021-03-03 12:35:07 -05:00
Shane McDonald
9595c6c008 New deployment model 2021-03-03 12:30:17 -05:00
Shane McDonald
9545acd301 Merge pull request #113 from shanemcd/refactor-templates
Refactor templates
2021-03-01 14:14:38 -05:00
Shane McDonald
1ff4d8f6c9 Refactor templates 2021-03-01 13:58:49 -05:00
Yanis Guenane
d839088521 Merge pull request #103 from Spredzy/more_flexibility
Augment the OpenAPI schema at the CRD definition level
2021-03-01 15:24:11 +01:00
Yanis Guenane
32a53f3747 Merge pull request #112 from Spredzy/increase_debug_in_ci
Improve CI troubleshooting
2021-03-01 11:00:55 +01:00
Yanis Guenane
70690ccd50 Improve CI troubleshooting 2021-03-01 10:42:36 +01:00
Yanis Guenane
c579537d66 Update API and operator interface 2021-02-25 17:44:00 +01:00
Yanis Guenane
e589a999a8 kind,api_version: Dynamically retrieve those values 2021-02-25 13:56:42 +01:00
Shane McDonald
53f3f07645 Merge pull request #110 from rooftopcellist/docs_typo
Fix minor typo in README.md
2021-02-24 15:31:27 -05:00
Christian M. Adams
b8d12d93fb Fix minor typo in README.md 2021-02-24 14:09:29 -05:00
Yanis Guenane
5f60f6d004 Merge pull request #107 from Spredzy/update_readdme
Update README
2021-02-24 09:45:48 +01:00
Yanis Guenane
87a6db538a Merge pull request #106 from Spredzy/full_openapi_schema
OpenAPI: Extend the schema to all role variables
2021-02-24 09:45:36 +01:00
Yanis Guenane
733d739124 Update README 2021-02-23 15:02:14 +01:00
Yanis Guenane
c7abc4b8d6 Merge pull request #108 from ansible/add-license-1
Add LICENSE file
2021-02-23 14:56:21 +01:00
Yanis Guenane
9271cd464e Add LICENSE file 2021-02-23 14:39:14 +01:00
Yanis Guenane
f04017ca95 OpenAPI: Extend the schema to all role variables
This is the full implementation of the OpenAPI schema that maps to the
currently existing roles defaults variable.

Prior to this commit, all variables specified at the spec level that
didn't have an entry in the OpenAPI schema at the CRD level were simply
ignored, unless --validate=false was specified.

This commit fixes that and provide a mapping between the CRD level
OpenAPI schema and the variables availabe in <roles>/defaults/main.yml.

This commit is simply about ensuring one can provide all the available
variables. A follow up commit will come to add logic in the OpenAPI
schema definition as it can be shown here[1]

[1]
https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema
2021-02-22 16:19:54 +01:00
Yanis Guenane
5690fa7cc1 Merge pull request #102 from Spredzy/templatize_api_version
Make the API version used for status update parametrable
2021-02-17 11:43:25 +01:00
Yanis Guenane
a44cfb676d Make the API version used for status update parametrable 2021-02-17 11:21:29 +01:00
Yanis Guenane
d3e7c308c4 Merge pull request #100 from Spredzy/improved_req_mems
Requirements: Improve CRD OpenAPI schema
2021-02-16 18:31:08 +01:00
Yanis Guenane
53fd88a4e1 Requirements: Improve CRD OpenAPI schema 2021-02-16 18:14:17 +01:00
Yanis Guenane
3b9b4225ae Merge pull request #96 from Spredzy/default_and_v1
Move to apiextensions.k8s.io/v1 and enable default value on CRD
2021-02-16 15:32:34 +01:00
Yanis Guenane
1a58392804 Merge pull request #98 from Spredzy/improve_local_test
Discard .cache from linting and commiting
2021-02-16 14:55:29 +01:00
Yanis Guenane
78eab6873e Merge pull request #99 from Spredzy/fix_logs
CI: Properly return logs when deployment fails
2021-02-16 14:55:19 +01:00
Yanis Guenane
25fc21a6cd Enum: allow various casing 2021-02-16 14:30:31 +01:00
Yanis Guenane
a39b914963 CI: Bump bsycorp/kind to v1.17.9 2021-02-16 14:30:31 +01:00
Yanis Guenane
a4ee609a76 CRD: Add default value to openAPIV3Schema 2021-02-16 14:30:31 +01:00
Yanis Guenane
fbae5cf590 CRD: Move to apiextensions.k8s.io/v1 2021-02-16 14:30:31 +01:00
Yanis Guenane
6f965c9180 CI: Properly return logs when deployment fails 2021-02-16 14:16:12 +01:00
Yanis Guenane
4e8308c90d Discard .cache from linting and commiting 2021-02-16 14:14:36 +01:00
Yanis Guenane
e5e996569c Merge pull request #93 from Spredzy/resource_requirements
Allow greater flexibility to specify resource requests/limits
2021-02-10 16:52:45 +01:00
Yanis Guenane
fd4e3b2d4c Allow greater flexibility to specify resource requests/limits 2021-02-10 15:58:48 +01:00
Yanis Guenane
025dfa54df Merge pull request #95 from Spredzy/tls_custom_passthrough
TLS: Enable passthrough termination mechanism
2021-02-10 15:34:51 +01:00
Yanis Guenane
1fe7c4dd20 TLS: Enable passthrough termination mechanism
Depends-On: https://github.com/ansible/awx-operator/pull/94
2021-02-10 15:20:27 +01:00
Yanis Guenane
b5536ffd80 Merge pull request #94 from Spredzy/tls_customization
TLS: Enable customization of TLS behavior on route when using edge mechanism
2021-02-10 15:19:56 +01:00
Yanis Guenane
c895ca0f6d TLS: Enable customization of TLS behavior on route 2021-02-10 12:11:29 +01:00
Yanis Guenane
121c034e6c Merge pull request #91 from Spredzy/improved_ux
Update CSV with richer fields
2021-02-09 22:43:54 +01:00
Yanis Guenane
452bb128c6 Update CSV with richer fields 2021-02-09 22:23:05 +01:00
Yanis Guenane
821198c05e Merge pull request #90 from Spredzy/standar_gc
Secret: Create a toggle to garbage collect secrets in finalizer
2021-02-09 22:22:37 +01:00
Yanis Guenane
8049dfac9c Secret: Create a toggle to garbage collect secrets in finalizer. 2021-02-09 22:08:24 +01:00
Yanis Guenane
8481390bac Merge pull request #92 from Spredzy/fix_ci
travis.yml: Explicitly list ansible as a dep
2021-02-09 22:07:52 +01:00
Yanis Guenane
0eab2f9686 travis.yml: Explicitly list ansible as a dep 2021-02-09 21:52:51 +01:00
Yanis Guenane
72fd95994b Merge pull request #88 from Spredzy/admin_password
Admin Password: Allow one to specify an admin password secret else generate it
2021-02-09 09:28:50 +01:00
Yanis Guenane
e858f34f2c Admin Password: Allow one to specify an admin password secret else generate it 2021-02-08 19:29:55 +01:00
Yanis Guenane
90bfe5073b Merge pull request #89 from Spredzy/secret_key
Secret Key: Allow one to specify a secret key else generate it
2021-02-08 19:25:43 +01:00
Yanis Guenane
dfb96d1e18 Secret Key: Allow one to specify a secret key else generate it 2021-02-08 19:11:44 +01:00
Yanis Guenane
5cf9f72f60 Merge pull request #84 from Spredzy/database_configuration
PostgreSQL: Allow one to provide her own db configuration secret
2021-02-08 19:08:03 +01:00
Yanis Guenane
e5f1041350 PostgreSQL: Allow one to provide her own db configuration secret
If a user provide its own secret by using the
`tower_postgres_configuration_secret` use this variable, else try to use
`<instance>-postgres-configuration` secret. Else create one and use a
local database.
2021-02-08 15:13:56 +01:00
Yanis Guenane
f5ac42dfe2 Merge pull request #87 from Spredzy/fix_yamlliny
yamllint: Fix warning
2021-02-08 14:23:43 +01:00
Yanis Guenane
0149afcd9e yamllint: Fix warning 2021-02-08 14:05:16 +01:00
Yanis Guenane
5efd45570e Merge pull request #85 from Spredzy/fix_creds
tower_config: Remove credential from tower_config.yml
2021-02-08 09:48:58 +01:00
Yanis Guenane
357e8ad2c9 tower_config: Remove credential from tower_config.yml 2021-02-08 09:34:56 +01:00
Yanis Guenane
c5cd12e662 Merge pull request #86 from Spredzy/change_role_names
Rename base roles
2021-02-08 09:31:17 +01:00
Yanis Guenane
ad476e4782 Rename base roles 2021-02-05 22:23:23 +01:00
Yanis Guenane
3a2d3d889a Merge pull request #82 from Spredzy/normalize
deployment_type: Introduce the new variable
2021-02-05 21:32:10 +01:00
Yanis Guenane
285be0faff deployment_type: Introduce the new variable. 2021-02-05 21:19:16 +01:00
Yanis Guenane
38c57a61d0 Merge pull request #83 from Spredzy/database_configuration
PostgreSQL: Remove unused/wrongly used variable
2021-02-05 18:33:26 +01:00
Yanis Guenane
7837db6e53 Merge pull request #81 from Spredzy/change_default_admin_username
tower_admin_user: default to admin
2021-02-05 18:32:43 +01:00
Yanis Guenane
2daae08790 PostgreSQL: Remove unused/wrongly used variable 2021-02-05 16:11:28 +01:00
Yanis Guenane
c378e0da9f Merge pull request #79 from Spredzy/toc_readme
README: Add a ToC at the top of the README
2021-02-05 16:01:21 +01:00
Yanis Guenane
470870526b tower_admin_user: default to admin 2021-02-05 15:38:44 +01:00
Yanis Guenane
ae7aae4048 README: Add a ToC at the top of the README 2021-02-05 12:19:21 +01:00
Yanis Guenane
90023b8d75 Merge pull request #74 from Spredzy/trim_csv
Remove boiler plated ao-logs run from CSV file
2021-01-28 16:24:14 +01:00
Yanis Guenane
9189333611 Remove boiler plated ao-logs run from CSV file 2021-01-28 16:00:27 +01:00
Yanis Guenane
4e11d45386 Merge pull request #73 from Spredzy/bump_csv
Bump awx-operator tag in CSV
2021-01-26 21:32:03 +01:00
Yanis Guenane
9c53c4067e Bump awx-operator tag in CSV 2021-01-26 21:17:23 +01:00
124 changed files with 7825 additions and 1278 deletions

View File

@@ -1,3 +1,4 @@
---
skip_list:
- '306'
- '602'
@@ -5,3 +6,4 @@ skip_list:
exclude_paths:
- deploy/
- .cache/

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

44
.github/workflows/ci.yaml vendored Normal file
View File

@@ -0,0 +1,44 @@
---
name: CI
on:
pull_request:
branches: [devel]
push:
branches: [devel]
jobs:
pull_request:
runs-on: ubuntu-18.04
name: pull_request
env:
DOCKER_API_VERSION: "1.38"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: "3.8"
- name: Install Dependencies
run: |
pip install \
molecule \
molecule-docker \
yamllint \
ansible-lint \
openshift \
jmespath \
ansible
- name: Install Collections
run: |
ansible-galaxy collection install community.kubernetes operator_sdk.util
- name: Run Molecule
env:
MOLECULE_VERBOSITY: 3
run: |
molecule test -s test-local

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 }}

35
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,35 @@
---
name: Release
on:
release:
types:
- created
jobs:
release:
runs-on: ubuntu-18.04
name: Push tagged image to Quay
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:${{ github.event.release.tag_name }}
- name: Push To Quay
uses: redhat-actions/push-to-registry@v2.1.1
with:
image: awx-operator
tags: ${{ github.event.release.tag_name }}
registry: quay.io/ansible/
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}

1
.gitignore vendored
View File

@@ -1 +1,2 @@
*~
.cache/

View File

@@ -1,19 +0,0 @@
---
services: docker
language: python
before_install:
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- sudo apt-get update
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
env:
- DOCKER_API_VERSION=1.38
install:
- pip3 install docker molecule molecule-docker yamllint ansible-lint openshift jmespath
- ansible-galaxy collection install community.kubernetes
script:
- molecule test -s test-local

View File

@@ -1,7 +1,12 @@
---
extends: default
ignore: |
.cache/
deploy/olm-catalog
rules:
truthy: disable
line-length:
max: 160
max: 170
level: warning

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.

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

862
README.md
View File

@@ -1,186 +1,731 @@
# AWX Operator
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Build Status](https://github.com/ansible/awx-operator/workflows/CI/badge.svg?event=push)](https://github.com/ansible/awx-operator/actions)
An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built with [Operator SDK](https://github.com/operator-framework/operator-sdk) and Ansible.
# Table of Contents
<!--ts-->
* [AWX Operator](#awx-operator)
* [Table of Contents](#table-of-contents)
* [Purpose](#purpose)
* [Usage](#usage)
* [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)
* [Database Configuration](#database-configuration)
* [External PostgreSQL Service](#external-postgresql-service)
* [Migrating data from an old AWX instance](#migrating-data-from-an-old-awx-instance)
* [Managed PostgreSQL Service](#managed-postgresql-service)
* [Advanced Configuration](#advanced-configuration)
* [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)
* [Persisting Projects Directory](#persisting-projects-directory)
* [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)
* [Verifiy Functionality](#verify-functionality)
* [Update Version](#update-version)
* [Commit / Create Release](#commit--create-release)
* [Author](#author)
<!--te-->
## Purpose
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
### Basic Install
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.
kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml
```bash
$ 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 you can create instances of AWX, for example:
Once Minikube is deployed, check if the node(s) and `kube-apiserver` communication is working as expected.
1. Make sure the namespace you're deploying into already exists (e.g. `kubectl create namespace ansible-awx`).
2. Create a file named `my-awx.yml` with the following contents:
```bash
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 6m28s v1.20.2
```
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
namespace: ansible-awx
spec:
tower_admin_user: test
tower_admin_email: test@example.com
tower_admin_password: changeme
tower_broadcast_websocket_secret: changeme
```
$ 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
```
3. Use `kubectl` to create the awx instance in your cluster:
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.
```
kubectl apply -f my-awx.yml
```
```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
```
After a few minutes, your new AWX instance will be accessible at `http://awx.mycompany.com/` (assuming your cluster has an Ingress controller configured). Log in using the `tower_admin_` credentials configured in the `spec`.
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
```
### Deploying a specific version of AWX
To achieve this, please add the following variable under spec within your CR (Custom Resource) file:
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
tower_image: ansible/awx:15.0.0 # replace this with desired image
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx-demo
spec:
service_type: nodeport
ingress_type: none
hostname: awx-demo.example.com
```
You may also override any default variables from `roles/awx/defaults/main.yml` using the same process, i.e. by adding those variables within your CR spec.
### Ingress Types
Finally, use `kubectl` to create the awx instance in your cluster:
Depending on the cluster that you're running on, you may wish to use an `Ingress` to access AWX, or you may wish to use a `Route` to access your AWX. To toggle between these two options, you can add the following to your AWX CR:
```bash
$ kubectl apply -f awx-demo.yml
awx.awx.ansible.com/awx-demo created
```
---
spec:
...
tower_ingress_type: Route
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`.
OR
```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
---
spec:
...
tower_ingress_type: Ingress
tower_hostname: awx.mycompany.com
$ 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
```
By default, no ingress/route is deployed as the default is set to `none`.
Once deployed, the AWX instance will be accessible by the command `minikube service awx-demo-service --url`.
### Privileged Tasks
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!!!!
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
There are three variables that are customizable for the admin user account creation.
| Name | Description | Default |
| --------------------------- | -------------------------------------------- | ---------------- |
| 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: **admin_password_secret must be a Kubernetes secret and not your text clear 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`
The secret that is expected to be passed should be formatted as follow:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: <resourcename>-admin-password
namespace: <target namespace>
stringData:
password: mysuperlongpassword
```
### Network and TLS Configuration
#### Service Type
If the `service_type` is not specified, the `ClusterIP` service will be used for your AWX Tower service.
The `service_type` supported options are: `ClusterIP`, `LoadBalancer` and `NodePort`.
The following variables are customizable for any `service_type`
| Name | Description | Default |
| ------------------------------------- | --------------------------------------------- | --------------------------------- |
| service_labels | Add custom labels | Empty string |
```yaml
---
spec:
...
service_type: ClusterIP
service_labels: |
environment: testing
```
* LoadBalancer
The following variables are customizable only when `service_type=LoadBalancer`
| Name | Description | Default |
| ------------------------------ | ---------------------------------------- | ------------- |
| loadbalancer_annotations | LoadBalancer annotations | Empty string |
| loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
| loadbalancer_port | Port used for Loadbalancer ingress | 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 `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:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: <resourcename>-postgres-configuration
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
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).
#### Managed PostgreSQL Service
If you don't have access to an external PostgreSQL service, the AWX operator can deploy one for you along side the AWX instance itself.
The following variables are customizable for the managed PostgreSQL service
| Name | Description | Default |
| ------------------------------------ | ------------------------------------------ | --------------------------------- |
| 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:
```yaml
---
spec:
...
postgres_resource_requirements:
requests:
cpu: 500m
memory: 2Gi
limits:
cpu: 1
memory: 4Gi
postgres_storage_requirements:
requests:
storage: 8Gi
limits:
storage: 50Gi
postgres_storage_class: fast-ssd
```
**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
#### Deploying a specific version of AWX
There are a few variables that are customizable for awx the image management.
| 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:
```yaml
---
spec:
...
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:
---
spec:
...
tower_task_privileged: true
```yaml
---
spec:
...
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:
oc adm policy add-scc-to-user privileged -z awx
```sh
#> oc adm policy add-scc-to-user privileged -z awx
```
Again, this is the most relaxed SCC that is provided by OpenShift, so be sure to familiarize yourself with the security concerns that accompany this action.
### Connecting to an external Postgres Service
When the Operator installs the AWX services and generates a Postgres deployment it will lay down a config file to enable AWX to connect to that service. To use an external database you just need to create a `Secret` that the AWX deployment will use instead and then set a property in the CR:
#### Containers Resource Requirements
---
spec:
...
external_database: true
The resource requirements for both, the task and the web containers are configurable - both the lower end (requests) and the upper end (limits).
The secret should have the name: *crname*-postgres-configuration and
should look like:
| 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} |
apiVersion: v1
kind: Secret
metadata:
name: <crname>-postgres-configuration
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
database: <desired database name>
username: <username to connect as>
password: <password to connect with>
type: Opaque
Example of customization could be:
### Persistent storage for Postgres
If you need to use a specific storage class for Postgres' storage, specify `tower_postgres_storage_class` in your AWX spec:
---
spec:
...
tower_postgres_storage_class: fast-ssd
If it's not specified, Postgres will store it's data on a volume using the default storage class for your cluster.
## Development
### 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:
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 (standalone)
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
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
```yaml
---
spec:
...
web_resource_requirements:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
task_resource_requirements:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
ee_resource_requirements:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
```
### Release Process
#### Assigning AWX pods to specific nodes
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 |
| -------------------------------| --------------------------- | ------- |
| 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:
```yaml
---
spec:
...
node_selector: |
disktype: ssd
kubernetes.io/arch: amd64
kubernetes.io/os: linux
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
If the variable `ldap_cacert_secret` is provided, the operator will look for a the data field `ldap-ca.crt` in the specified secret.
| Name | Description | Default |
| -------------------------------- | --------------------------------------- | --------|
| ldap_cacert_secret | LDAP Certificate Authority secret name | '' |
Example of customization could be:
```yaml
---
spec:
...
ldap_cacert_secret: <resourcename>-ldap-ca-cert
```
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>
```
#### Persisting Projects Directory
In cases which you want to persist the `/var/lib/projects` directory, there are few variables that are customizable for the `awx-operator`.
| Name | Description | Default |
| -----------------------------------| ---------------------------------------------------------------------------------------------------- | ---------------|
| 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:
```yaml
---
spec:
...
projects_persistence: true
projects_storage_class: rook-ceph
projects_storage_size: 20Gi
```
#### Custom Volume and Volume Mount Options
In a scenario where custom volumes and volume mounts are required to either overwrite defaults or mount configuration files.
| 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 | '' |
Example configuration for ConfigMap
#### Default execution environments from private registries
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.
The secret should be formated as follows:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
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
```
##### 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.
```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 | '' |
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).
## 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 of the Operator for Docker Hub
Run the following command inside this directory:
operator-sdk build quay.io/ansible/awx-operator:$VERSION
Then push the generated image to Docker Hub:
docker push quay.io/ansible/awx-operator:$VERSION
#### Build a new version of the `awx-operator.yaml` file
### Update version and files
Update the awx-operator version:
@@ -188,19 +733,60 @@ Update the awx-operator version:
Once the version has been updated, run from the root of the repo:
ansible-playbook ansible/chain-operator-files.yml
```sh
#> 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:
minikube start --memory 6g --cpus 4
minikube addons enable ingress
kubectl apply -f deploy/awx-operator.yaml
kubectl create namespace example-awx
kubectl apply -f deploy/crds/awx_v1beta1_cr.yaml
<test everything>
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.
```sh
#> minikube start --memory 6g --cpus 4
#> minikube addons enable ingress
#> 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 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
```
### 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,26 @@
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
dest: ../deploy/awx-operator.yaml
mode: '0644'

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

View File

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

View File

@@ -9,7 +9,7 @@
- name: Deploy AWX
k8s:
state: "{{ state | default('present') }}"
namespace: default
namespace: "{{ namespace | default('default') }}"
apply: yes
wait: yes
definition:
@@ -18,11 +18,14 @@
metadata:
name: awx
spec:
tower_admin_user: test
tower_admin_email: test@example.com
tower_admin_password: changeme
tower_broadcast_websocket_secret: changeme
tower_ingress_type: "{{ tower_ingress_type | default(omit) }}" # Either Route or Ingress
tower_image: "{{ tower_image | default(omit) }}"
development_mode: "{{ development_mode | default(omit) }}"
tower_image_pull_policy: "{{ tower_image_pull_policy | 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 }}"
image_pull_policy: "{{ image_pull_policy | default(omit) }}"
# ee_images:
# - name: test-ee
# image: quay.io/<user>/awx-ee

View File

@@ -1,6 +1,12 @@
#jinja2: trim_blocks:False
# This file is generated by Ansible. Changes will be lost.
# 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' %}
@@ -8,5 +14,3 @@
{% include 'service_account.yml.j2' %}
{% include 'operator.yml.j2' %}
{% include 'crd.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

@@ -1,5 +1,5 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxs.awx.ansible.com
@@ -11,40 +11,416 @@ spec:
plural: awxs
singular: awx
scope: Namespaced
subresources:
status: {}
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
validation:
openAPIV3Schema:
description: Schema validation for the AWX CRD
type: object
properties:
spec:
type: object
subresources:
status: {}
schema:
openAPIV3Schema:
description: Schema validation for the AWX CRD
properties:
external_database:
type: boolean
description: |
If true you must supply a secret containing the location and credentials for
connecting to the external database by a user who has permission to create
and apply a schema.
The secret should have the name: <custom resource name>-postgres-configuration and
should look like:
apiVersion: v1
kind: Secret
metadata:
name: <crname>-postgres-configuration
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
database: <desired database name>
username: <username to connect as>
password: <password to connect with>
type: Opaque
spec:
properties:
deployment_type:
description: Name of the deployment type
type: string
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
admin_user:
description: Username to use for the admin account
type: string
default: admin
hostname:
description: The hostname of the instance
type: string
admin_email:
description: The admin user email
type: string
admin_password_secret:
description: Secret where the admin password can be found
type: string
postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
old_postgres_configuration_secret:
description: Secret where the old database configuration can be found for data migration
type: string
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
broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
extra_volumes:
description: Specify extra volumes to add to the application pod
type: string
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:
- none
- Ingress
- ingress
- Route
- route
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
loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
loadbalancer_protocol:
description: Protocol to use for the loadbalancer
type: string
default: http
enum:
- http
- https
loadbalancer_port:
description: Port to use for the loadbalancer
type: integer
default: 80
route_host:
description: The DNS to use to points to the instance
type: string
route_tls_termination_mechanism:
description: The secure TLS termination mechanism to use
type: string
default: Edge
enum:
- Edge
- edge
- Passthrough
- passthrough
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
node_selector:
description: nodeSelector for the pods
type: string
service_labels:
description: Additional labels to apply to the service
type: string
tolerations:
description: node tolerations for the pods
type: string
image:
description: Registry path to the application container to use
type: string
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:
type: object
properties:
name:
type: string
image:
type: string
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
enum:
- Always
- always
- Never
- never
- IfNotPresent
- ifnotpresent
image_pull_secret:
description: The image pull secret
type: string
task_resource_requirements:
description: Resource requirements for the task container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
web_resource_requirements:
description: Resource requirements for the web container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
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
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
postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
ca_trust_bundle:
description: Path where the trusted CA bundle is available
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
type: string
projects_persistence:
description: Whether or not the /var/lib/projects directory will be persistent
default: false
type: boolean
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
type: string
enum:
- _Yes_
- _No_
projects_existing_claim:
description: PersistentVolumeClaim to mount /var/lib/projects directory
type: string
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
projects_storage_size:
description: Size for the /var/lib/projects PersistentVolumeClaim
default: 8Gi
type: string
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:
type: string
type: object
type: array
type: object
status:
properties:
URL:
description: URL to access the deployed instance
type: string
adminUser:
description: Admin user of the deployed instance
type: string
adminPasswordSecret:
description: Admin password secret name of the deployed instance
type: string
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
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
image:
description: URL of the image used for the deployed instance
type: string
conditions:
description: The resulting conditions when a Service Telemetry is instantiated
items:
properties:
status:
type: string
type:
type: string
reason:
type: string
lastTransitionTime:
type: string
type: object
type: array
type: object
type: object

View File

@@ -33,12 +33,16 @@ 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
port: 6789
initialDelaySeconds: 5
periodSeconds: 3
initialDelaySeconds: 15
periodSeconds: 20
volumes:
- name: runner
emptyDir: {}

View File

@@ -9,19 +9,24 @@ rules:
- route.openshift.io
resources:
- routes
- routes/custom-host
verbs:
- '*'
- apiGroups:
- ""
- "rbac.authorization.k8s.io"
resources:
- pods
- services
- services/finalizers
- serviceaccounts
- endpoints
- persistentvolumeclaims
- events
- configmaps
- secrets
- roles
- rolebindings
verbs:
- '*'
- apiGroups:
@@ -50,6 +55,13 @@ rules:
- deployments/finalizers
verbs:
- update
- apiGroups:
- apps
resources:
- deployments/scale
- statefulsets/scale
verbs:
- patch
- apiGroups:
- ""
resources:
@@ -67,5 +79,7 @@ rules:
- awx.ansible.com
resources:
- '*'
- awxbackups
- awxrestores
verbs:
- '*'

14
bundle.Dockerfile Normal file
View File

@@ -0,0 +1,14 @@
FROM scratch
LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1
LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/
LABEL operators.operatorframework.io.bundle.package.v1=awx-operator
LABEL operators.operatorframework.io.bundle.channels.v1=alpha
LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha
LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1
LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v0.19.4
LABEL operators.operatorframework.io.metrics.project_layout=ansible
COPY deploy/olm-catalog/awx-operator/manifests /manifests/
COPY deploy/olm-catalog/awx-operator/metadata /metadata/

View File

@@ -1,5 +1,591 @@
# This file is generated by Ansible. Changes will be lost.
# Update templates under ansible/templates/
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxs.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWX
listKind: AWXList
plural: awxs
singular: awx
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
description: Schema validation for the AWX CRD
properties:
spec:
properties:
deployment_type:
description: Name of the deployment type
type: string
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
admin_user:
description: Username to use for the admin account
type: string
default: admin
hostname:
description: The hostname of the instance
type: string
admin_email:
description: The admin user email
type: string
admin_password_secret:
description: Secret where the admin password can be found
type: string
postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
old_postgres_configuration_secret:
description: Secret where the old database configuration can be found for data migration
type: string
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
broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
extra_volumes:
description: Specify extra volumes to add to the application pod
type: string
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:
- none
- Ingress
- ingress
- Route
- route
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
loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
loadbalancer_protocol:
description: Protocol to use for the loadbalancer
type: string
default: http
enum:
- http
- https
loadbalancer_port:
description: Port to use for the loadbalancer
type: integer
default: 80
route_host:
description: The DNS to use to points to the instance
type: string
route_tls_termination_mechanism:
description: The secure TLS termination mechanism to use
type: string
default: Edge
enum:
- Edge
- edge
- Passthrough
- passthrough
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
node_selector:
description: nodeSelector for the pods
type: string
service_labels:
description: Additional labels to apply to the service
type: string
tolerations:
description: node tolerations for the pods
type: string
image:
description: Registry path to the application container to use
type: string
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:
type: object
properties:
name:
type: string
image:
type: string
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
enum:
- Always
- always
- Never
- never
- IfNotPresent
- ifnotpresent
image_pull_secret:
description: The image pull secret
type: string
task_resource_requirements:
description: Resource requirements for the task container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
web_resource_requirements:
description: Resource requirements for the web container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
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
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
postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
ca_trust_bundle:
description: Path where the trusted CA bundle is available
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
type: string
projects_persistence:
description: Whether or not the /var/lib/projects directory will be persistent
default: false
type: boolean
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
type: string
enum:
- _Yes_
- _No_
projects_existing_claim:
description: PersistentVolumeClaim to mount /var/lib/projects directory
type: string
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
projects_storage_size:
description: Size for the /var/lib/projects PersistentVolumeClaim
default: 8Gi
type: string
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:
type: string
type: object
type: array
type: object
status:
properties:
URL:
description: URL to access the deployed instance
type: string
adminUser:
description: Admin user of the deployed instance
type: string
adminPasswordSecret:
description: Admin password secret name of the deployed instance
type: string
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
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
image:
description: URL of the image used for the deployed instance
type: string
conditions:
description: The resulting conditions when a Service Telemetry is instantiated
items:
properties:
status:
type: string
type:
type: string
reason:
type: string
lastTransitionTime:
type: string
type: object
type: array
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
@@ -11,19 +597,24 @@ rules:
- route.openshift.io
resources:
- routes
- routes/custom-host
verbs:
- '*'
- apiGroups:
- ""
- "rbac.authorization.k8s.io"
resources:
- pods
- services
- services/finalizers
- serviceaccounts
- endpoints
- persistentvolumeclaims
- events
- configmaps
- secrets
- roles
- rolebindings
verbs:
- '*'
- apiGroups:
@@ -52,6 +643,13 @@ rules:
- deployments/finalizers
verbs:
- update
- apiGroups:
- apps
resources:
- deployments/scale
- statefulsets/scale
verbs:
- patch
- apiGroups:
- ""
resources:
@@ -69,6 +667,8 @@ rules:
- awx.ansible.com
resources:
- '*'
- awxbackups
- awxrestores
verbs:
- '*'
@@ -111,7 +711,7 @@ spec:
serviceAccountName: awx-operator
containers:
- name: awx-operator
image: "quay.io/ansible/awx-operator:0.6.0"
image: "quay.io/ansible/awx-operator:0.11.0"
imagePullPolicy: "Always"
volumeMounts:
- mountPath: /tmp/ansible-operator/runner
@@ -128,63 +728,16 @@ spec:
value: awx-operator
- name: ANSIBLE_GATHERING
value: explicit
- name: OPERATOR_VERSION
value: "0.11.0"
- name: ANSIBLE_DEBUG_LOGS
value: "false"
livenessProbe:
httpGet:
path: /healthz
port: 6789
initialDelaySeconds: 5
periodSeconds: 3
initialDelaySeconds: 15
periodSeconds: 20
volumes:
- name: runner
emptyDir: {}
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: awxs.awx.ansible.com
spec:
group: awx.ansible.com
names:
kind: AWX
listKind: AWXList
plural: awxs
singular: awx
scope: Namespaced
subresources:
status: {}
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
validation:
openAPIV3Schema:
description: Schema validation for the AWX CRD
type: object
properties:
spec:
type: object
properties:
external_database:
type: boolean
description: |
If true you must supply a secret containing the location and credentials for
connecting to the external database by a user who has permission to create
and apply a schema.
The secret should have the name: <custom resource name>-postgres-configuration and
should look like:
apiVersion: v1
kind: Secret
metadata:
name: <crname>-postgres-configuration
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
database: <desired database name>
username: <username to connect as>
password: <password to connect with>
type: Opaque

View File

@@ -1,33 +0,0 @@
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: example-awx
namespace: example-awx
spec:
tower_ingress_type: none
tower_task_privileged: false
tower_hostname: example-awx.test
tower_broadcast_websocket_secret: changeme
tower_admin_user: test
tower_admin_email: test@example.com
tower_admin_password: changeme
tower_image: ansible/awx:15.0.0
tower_task_mem_request: 1Gi
tower_task_cpu_request: 500m
tower_web_mem_request: 2Gi
tower_web_cpu_request: 1000m
tower_create_preload_data: true
tower_memcached_image: memcached:alpine
tower_redis_image: redis:latest
tower_postgres_storage_request: 8Gi
tower_postgres_storage_class: ''

View File

@@ -1,5 +1,5 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: awxs.awx.ansible.com
@@ -11,40 +11,416 @@ spec:
plural: awxs
singular: awx
scope: Namespaced
subresources:
status: {}
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
validation:
openAPIV3Schema:
description: Schema validation for the AWX CRD
type: object
properties:
spec:
type: object
subresources:
status: {}
schema:
openAPIV3Schema:
description: Schema validation for the AWX CRD
properties:
external_database:
type: boolean
description: |
If true you must supply a secret containing the location and credentials for
connecting to the external database by a user who has permission to create
and apply a schema.
The secret should have the name: <custom resource name>-postgres-configuration and
should look like:
apiVersion: v1
kind: Secret
metadata:
name: <crname>-postgres-configuration
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
database: <desired database name>
username: <username to connect as>
password: <password to connect with>
type: Opaque
spec:
properties:
deployment_type:
description: Name of the deployment type
type: string
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
admin_user:
description: Username to use for the admin account
type: string
default: admin
hostname:
description: The hostname of the instance
type: string
admin_email:
description: The admin user email
type: string
admin_password_secret:
description: Secret where the admin password can be found
type: string
postgres_configuration_secret:
description: Secret where the database configuration can be found
type: string
old_postgres_configuration_secret:
description: Secret where the old database configuration can be found for data migration
type: string
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
broadcast_websocket_secret:
description: Secret where the broadcast websocket secret can be found
type: string
extra_volumes:
description: Specify extra volumes to add to the application pod
type: string
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:
- none
- Ingress
- ingress
- Route
- route
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
loadbalancer_annotations:
description: Annotations to add to the loadbalancer
type: string
loadbalancer_protocol:
description: Protocol to use for the loadbalancer
type: string
default: http
enum:
- http
- https
loadbalancer_port:
description: Port to use for the loadbalancer
type: integer
default: 80
route_host:
description: The DNS to use to points to the instance
type: string
route_tls_termination_mechanism:
description: The secure TLS termination mechanism to use
type: string
default: Edge
enum:
- Edge
- edge
- Passthrough
- passthrough
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
node_selector:
description: nodeSelector for the pods
type: string
service_labels:
description: Additional labels to apply to the service
type: string
tolerations:
description: node tolerations for the pods
type: string
image:
description: Registry path to the application container to use
type: string
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:
type: object
properties:
name:
type: string
image:
type: string
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
enum:
- Always
- always
- Never
- never
- IfNotPresent
- ifnotpresent
image_pull_secret:
description: The image pull secret
type: string
task_resource_requirements:
description: Resource requirements for the task container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
web_resource_requirements:
description: Resource requirements for the web container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
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
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
postgres_data_path:
description: Path where the PostgreSQL data are located
type: string
ca_trust_bundle:
description: Path where the trusted CA bundle is available
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
type: string
projects_persistence:
description: Whether or not the /var/lib/projects directory will be persistent
default: false
type: boolean
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
type: string
enum:
- _Yes_
- _No_
projects_existing_claim:
description: PersistentVolumeClaim to mount /var/lib/projects directory
type: string
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
projects_storage_size:
description: Size for the /var/lib/projects PersistentVolumeClaim
default: 8Gi
type: string
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:
type: string
type: object
type: array
type: object
status:
properties:
URL:
description: URL to access the deployed instance
type: string
adminUser:
description: Admin user of the deployed instance
type: string
adminPasswordSecret:
description: Admin password secret name of the deployed instance
type: string
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
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
image:
description: URL of the image used for the deployed instance
type: string
conditions:
description: The resulting conditions when a Service Telemetry is instantiated
items:
properties:
status:
type: string
type:
type: string
reason:
type: string
lastTransitionTime:
type: string
type: object
type: array
type: object
type: object

View File

@@ -5,31 +5,19 @@ metadata:
name: example-awx
namespace: example-awx
spec:
tower_ingress_type: ingress
tower_task_privileged: false
tower_hostname: example-awx.test
tower_broadcast_websocket_secret: changeme
tower_admin_user: test
tower_admin_email: test@example.com
tower_admin_password: changeme
tower_image: ansible/awx:15.0.0
tower_task_mem_request: 128M
tower_task_cpu_request: 500m
tower_web_mem_request: 128M
tower_web_cpu_request: 500m
tower_create_preload_data: true
tower_memcached_image: memcached:alpine
tower_redis_image: redis:latest
tower_postgres_pass: awxpass
tower_postgres_image: postgres:12
tower_postgres_storage_request: 8Gi
tower_postgres_storage_class: ''
service_account_annotations: |
foo: bar
deployment_type: awx
ingress_type: ingress
web_resource_requirements:
requests:
cpu: 500m
memory: 128M
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

@@ -0,0 +1,5 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./awx-operator.yaml

View File

@@ -1,4 +1,3 @@
---
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
@@ -13,209 +12,713 @@ metadata:
"namespace": "example-awx"
},
"spec": {
"tower_admin_email": "test@example.com",
"tower_admin_password": "changeme",
"tower_admin_user": "test",
"tower_broadcast_websocket_secret": "changeme",
"tower_create_preload_data": true,
"tower_hostname": "example-awx.test",
"tower_ingress_type": "none",
"tower_memcached_image": "memcached:alpine",
"tower_postgres_storage_class": "",
"tower_postgres_storage_request": "8Gi",
"tower_redis_image": "redis:latest",
"tower_task_cpu_request": "500m",
"tower_image": "ansible/awx:15.0.0",
"tower_task_mem_request": "1Gi",
"tower_task_privileged": false,
"tower_web_cpu_request": "1000m"
"tower_web_mem_request": "2Gi"
}
},
{
"apiVersion": "awx.ansible.com/v1beta1",
"kind": "AWX",
"metadata": {
"name": "example-awx",
"namespace": "example-awx"
},
"spec": {
"tower_admin_email": "test@example.com",
"tower_admin_password": "changeme",
"tower_admin_user": "test",
"tower_broadcast_websocket_secret": "changeme",
"tower_create_preload_data": true,
"tower_hostname": "example-awx.test",
"tower_ingress_type": "ingress",
"tower_memcached_image": "memcached:alpine",
"tower_postgres_image": "postgres:12",
"tower_postgres_pass": "awxpass",
"tower_postgres_storage_class": "",
"tower_postgres_storage_request": "8Gi",
"tower_redis_image": "redis:latest",
"tower_task_cpu_request": "500m",
"tower_image": "ansible/awx:15.0.0",
"tower_task_mem_request": "128M",
"tower_task_privileged": false,
"tower_web_cpu_request": "500m",
"tower_web_mem_request": "128M"
"deployment_type": "awx",
"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"
}
},
"web_resource_requirements": {
"requests": {
"cpu": "500m",
"memory": "128M"
}
}
}
}
]
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.11.0
namespace: placeholder
spec:
apiservicedefinitions: {}
customresourcedefinitions:
owned:
- kind: AWX
name: awxs.awx.ansible.com
version: v1beta1
- 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: hostname
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Admin account username
path: admin_user
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Admin email address
path: admin_email
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: 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: postgres_configuration_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Old Database 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: secret_key_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- displayName: Broadcast Websocket Secret
path: broadcast_websocket_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- 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
- displayName: 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:ingress_type:Ingress
- displayName: 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:ingress_type:Ingress
- displayName: 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:service_type:LoadBalancer
- displayName: 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:service_type:LoadBalancer
- displayName: 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:service_type:LoadBalancer
- displayName: Route DNS 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:ingress_type:Route
- displayName: 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:ingress_type:Route
- displayName: Route TLS credential 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:ingress_type:Route
- displayName: 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: 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: 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: 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: 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: 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: 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: create_preload_data
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- displayName: Deploy the instance in development mode ?
path: development_mode
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- urn:alm:descriptor:com.tectonic.ui:hidden
- 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
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Deployment Type
path: deployment_type
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- 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: 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: postgres_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- 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: 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
- displayName: Certificate Authorirty Trust Bundle
path: ca_trust_bundle
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: LDAP Certificate Authority Trust Bundle
path: ldap_cacert_secret
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:io.kubernetes:Secret
- 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: projects_persistence
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- displayName: Use existing Persistent 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: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:projects_use_existing_claim:_Yes_
- urn:alm:descriptor:io.kubernetes:PersistentVolumeClaim
- 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:projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:text
- 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:projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:text
- 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:projects_use_existing_claim:_No_
- urn:alm:descriptor:com.tectonic.ui:text
- displayName: Task Command
path: task_command
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- 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
- 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
- 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
- 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
- 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
- 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: Web Args
path: web_args
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Web Command
path: web_command
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- 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
statusDescriptors:
- description: Route to access the instance deployed
displayName: URL
path: URL
x-descriptors:
- urn:alm:descriptor:org.w3:link
- description: Admin user for the instance deployed
displayName: Admin User
path: adminUser
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Admin password for the instance deployed
displayName: Admin Password
path: adminPasswordSecret
x-descriptors:
- urn:alm:descriptor:io.kubernetes:Secret
- description: Version of the instance deployed
displayName: Version
path: version
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Image of the instance deployed
displayName: Image
path: image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
version: v1beta1
description: AWX operator
displayName: AWX
icon:
- base64data: ""
mediatype: ""
- base64data: ""
mediatype: ""
install:
spec:
clusterPermissions:
- rules:
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- '*'
- apiGroups:
- ""
resources:
- pods
- services
- services/finalizers
- endpoints
- persistentvolumeclaims
- events
- configmaps
- secrets
verbs:
- '*'
- apiGroups:
- apps
- extensions
resources:
- deployments
- daemonsets
- replicasets
- statefulsets
- ingresses
verbs:
- '*'
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
verbs:
- get
- create
- apiGroups:
- apps
resourceNames:
- awx-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
- get
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- apiGroups:
- awx.ansible.com
resources:
- '*'
verbs:
- '*'
serviceAccountName: awx-operator
- rules:
- apiGroups:
- route.openshift.io
resources:
- routes
- routes/custom-host
verbs:
- '*'
- apiGroups:
- ""
- rbac.authorization.k8s.io
resources:
- pods
- services
- services/finalizers
- serviceaccounts
- endpoints
- persistentvolumeclaims
- events
- configmaps
- secrets
- roles
- rolebindings
verbs:
- '*'
- apiGroups:
- apps
- extensions
resources:
- deployments
- daemonsets
- replicasets
- statefulsets
- ingresses
verbs:
- '*'
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
verbs:
- get
- create
- apiGroups:
- apps
resourceNames:
- awx-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- apps
resources:
- deployments/scale
- statefulsets/scale
verbs:
- patch
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
- get
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- apiGroups:
- awx.ansible.com
resources:
- '*'
- awxbackups
- awxrestores
verbs:
- '*'
serviceAccountName: awx-operator
deployments:
- name: awx-operator
spec:
replicas: 1
selector:
matchLabels:
- name: awx-operator
spec:
replicas: 1
selector:
matchLabels:
name: awx-operator
strategy: {}
template:
metadata:
labels:
name: awx-operator
strategy: {}
template:
metadata:
labels:
name: awx-operator
spec:
containers:
- command:
- /usr/local/bin/ao-logs
- /tmp/ansible-operator/runner
- stdout
image: ansible/awx-operator:0.5.0
imagePullPolicy: Always
name: ansible
resources: {}
volumeMounts:
- mountPath: /tmp/ansible-operator/runner
name: runner
readOnly: true
- env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.annotations['olm.targetNamespaces']
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OPERATOR_NAME
value: awx-operator
image: ansible/awx-operator:0.5.0
imagePullPolicy: Always
name: operator
resources: {}
volumeMounts:
- mountPath: /tmp/ansible-operator/runner
name: runner
serviceAccountName: awx-operator
volumes:
- emptyDir: {}
name: runner
spec:
containers:
- env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.annotations['olm.targetNamespaces']
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OPERATOR_NAME
value: awx-operator
- name: ANSIBLE_GATHERING
value: explicit
- name: OPERATOR_VERSION
value: 0.11.0
- name: ANSIBLE_DEBUG_LOGS
value: "false"
image: quay.io/ansible/awx-operator:0.11.0
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /healthz
port: 6789
initialDelaySeconds: 15
periodSeconds: 20
name: awx-operator
resources: {}
volumeMounts:
- mountPath: /tmp/ansible-operator/runner
name: runner
serviceAccountName: awx-operator
volumes:
- emptyDir: {}
name: runner
strategy: deployment
installModes:
- supported: true
type: OwnNamespace
- supported: true
type: SingleNamespace
- supported: false
type: MultiNamespace
- supported: true
type: AllNamespaces
- supported: true
type: OwnNamespace
- supported: true
type: SingleNamespace
- supported: false
type: MultiNamespace
- supported: true
type: AllNamespaces
keywords:
- awx
- awx
links:
- name: Awx Operator
url: https://github.com/ansible/awx-operator
- name: Awx Operator
url: https://github.com/ansible/awx-operator
maintainers:
- email: yguenane@redhat.com
name: Yanis Guenane
- email: yguenane@redhat.com
name: Yanis Guenane
maturity: alpha
provider:
name: AWX Community
url: https://github.com/ansible/awx-operator
version: 0.0.1
replaces: awx-operator.v0.10.0
version: 0.11.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

@@ -1,5 +1,4 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
@@ -12,43 +11,427 @@ spec:
plural: awxs
singular: awx
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
description: Schema validation for the AWX CRD
properties:
spec:
properties:
external_database:
description: |
If true you must supply a secret containing the location and credentials for
connecting to the external database by a user who has permission to create
and apply a schema.
The secret should have the name: <custom resource name>-postgres-configuration and
should look like:
apiVersion: v1
kind: Secret
metadata:
name: <crname>-postgres-configuration
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
database: <desired database name>
username: <username to connect as>
password: <password to connect with>
type: Opaque
type: boolean
type: object
type: object
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
- name: v1beta1
schema:
openAPIV3Schema:
description: Schema validation for the AWX CRD
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
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
ee_extra_env:
type: string
ee_extra_volume_mounts:
description: Specify volume mounts to be added to Execution container
type: string
ee_images:
description: Registry path to the Execution Environment container
to use
items:
properties:
image:
type: string
name:
type: string
type: object
type: array
ee_pull_credentials_secret:
description: Secret where pull credentials for registered ees can
be found
type: string
ee_resource_requirements:
description: Resource requirements for the ee container
properties:
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
extra_settings:
description: Extra settings to specify for the API
items:
properties:
setting:
type: string
value:
type: string
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
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
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
projects_persistence:
default: false
description: Whether or not the /var/lib/projects directory will be
persistent
type: boolean
projects_storage_access_mode:
default: ReadWriteMany
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
type: string
projects_storage_class:
description: Storage class for the /var/lib/projects PersistentVolumeClaim
type: string
projects_storage_size:
default: 8Gi
description: Size for the /var/lib/projects PersistentVolumeClaim
type: string
projects_use_existing_claim:
description: Using existing PersistentVolumeClaim
enum:
- _Yes_
- _No_
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
replicas:
default: 1
description: Number of instance replicas
format: int32
type: integer
route_host:
description: The DNS to use to points to the instance
type: string
route_tls_secret:
description: Secret where the TLS related credentials are stored
type: string
route_tls_termination_mechanism:
default: Edge
description: The secure TLS termination mechanism to use
enum:
- Edge
- edge
- Passthrough
- passthrough
type: string
secret_key_secret:
description: Secret where the secret key can be found
type: string
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
task_command:
items:
type: string
type: array
task_extra_env:
type: string
task_extra_volume_mounts:
description: Specify volume mounts to be added to Task container
type: string
task_privileged:
default: false
description: If a privileged security context should be enabled
type: boolean
task_resource_requirements:
description: Resource requirements for the task container
properties:
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
tolerations:
description: node tolerations for the pods
type: string
web_args:
items:
type: string
type: array
web_command:
items:
type: string
type: array
web_extra_env:
type: string
web_extra_volume_mounts:
description: Specify volume mounts to be added to the Web container
type: string
web_resource_requirements:
description: Resource requirements for the web container
properties:
limits:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
requests:
properties:
cpu:
type: string
memory:
type: string
storage:
type: string
type: object
type: object
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
items:
properties:
lastTransitionTime:
type: string
reason:
type: string
status:
type: string
type:
type: string
type: object
type: array
image:
description: URL of the image used for the deployed instance
type: string
migratedFromSecret:
description: The secret used for migrating an old instance.
type: string
postgresConfigurationSecret:
description: Postgres Configuration secret name of the deployed instance
type: string
secretKeySecret:
description: Secret key secret name of the deployed instance
type: string
version:
description: Version of the deployed instance
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""

View File

@@ -1,4 +1,3 @@
---
annotations:
operators.operatorframework.io.bundle.channel.default.v1: alpha
operators.operatorframework.io.bundle.channels.v1: alpha

1
docs/awx-demo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 825 KiB

67
docs/migration.md Normal file
View File

@@ -0,0 +1,67 @@
# Migrating data from an old AWX instance
To migrate data from an older AWX installation, you must provide some information via Secrets.
## Creating Secrets for Migration
### Secret Key
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>
stringData:
secret_key: <old-secret-key>
type: Opaque
```
**Note**: `<resourcename>` must match the `name` of the AWX object you are creating. In our example below, it is `awx`.
### Old Database Credentials
The secret should be formatted as follows:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: <resourcename>-old-postgres-configuration
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
database: <desired database name>
username: <username to connect as>
password: <password to connect with>
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:
```yaml
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
spec:
old_postgres_configuration_secret: <resourcename>-old-postgres-configuration
...
```

View File

@@ -2,4 +2,4 @@
- hosts: localhost
gather_facts: no
roles:
- awx
- installer

View File

@@ -7,12 +7,31 @@
ansible_python_interpreter: '{{ ansible_playbook_python }}'
tasks:
- name: Get AWX Kind data
k8s_info:
api_version: awx.ansible.com/v1beta1
kind: AWX
namespace: example-awx
label_selectors:
- "app.kubernetes.io/name=example-awx"
- "app.kubernetes.io/part-of=example-awx"
- "app.kubernetes.io/managed-by=awx-operator"
- "app.kubernetes.io/component=awx"
register: awx_kind
- name: Verify there is one AWX kind
assert:
that: '{{ (awx_kind.resources | length) == 1 }}'
- name: Get AWX Pod data
k8s_info:
kind: Pod
namespace: example-awx
label_selectors:
- app=awx
- "app.kubernetes.io/name=example-awx"
- "app.kubernetes.io/part-of=example-awx"
- "app.kubernetes.io/managed-by=awx-operator"
- "app.kubernetes.io/component=awx"
register: tower_pods
- name: Verify there is one AWX pod

View File

@@ -5,6 +5,6 @@
vars:
ansible_python_interpreter: '{{ ansible_playbook_python }}'
roles:
- awx
- installer
- import_playbook: '{{ playbook_dir }}/asserts.yml'

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

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

View File

@@ -28,11 +28,11 @@
pull_policy: Never
operator_image: awx.ansible.com/awx-operator
operator_version: testing
ansible_debug_logs: "true"
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awx_v1beta1_molecule.yaml'])) | from_yaml }}"
tasks:
- block:
- name: Delete the Operator Deployment
k8s:
state: absent
@@ -97,8 +97,8 @@
kind=custom_resource.kind,
api_version=custom_resource.apiVersion,
namespace=custom_resource.metadata.namespace,
resource_name=custom_resource.metadata.name
)}}'
resource_name=custom_resource.metadata.name)
}}'
- name: debug awx deployment
ignore_errors: yes
@@ -110,13 +110,13 @@
kind="Deployment",
api_version="apps/v1",
namespace=custom_resource.metadata.namespace,
label_selector="app=awx"
)}}'
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 }} -c operator
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ operator_namespace }}
environment:
KUBECONFIG: '{{ lookup("env", "KUBECONFIG") }}'
vars:

View File

@@ -11,7 +11,7 @@ platforms:
- name: kind-test-local
groups:
- k8s
image: bsycorp/kind:latest-1.15
image: bsycorp/kind:v1.17.9
privileged: True
override_command: no
exposed_ports:

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 }}"
@@ -105,8 +106,8 @@
kind=custom_resource.kind,
api_version=custom_resource.apiVersion,
namespace=custom_resource.metadata.namespace,
resource_name=custom_resource.metadata.name
)}}'
resource_name=custom_resource.metadata.name)
}}'
- name: debug awx deployment
ignore_errors: yes
@@ -118,8 +119,8 @@
kind="Deployment",
api_version="apps/v1",
namespace=custom_resource.metadata.namespace,
label_selector="app=awx"
)}}'
label_selector="app.kubernetes.io/name=example-awx")
}}'
- name: get operator logs
ignore_errors: yes

View File

@@ -1,82 +0,0 @@
---
tower_task_privileged: false
tower_ingress_type: none
# Add annotations to the ingress. Specify as literal block. E.g.:
# tower_ingress_annotations: |
# kubernetes.io/ingress.class: nginx
# nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s
tower_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: ''
tower_hostname: example-awx.test
tower_admin_user: test
tower_admin_email: test@example.com
tower_admin_password: changeme
tower_broadcast_websocket_secret: changeme
# Add extra volumes to the AWX pod. Specify as literal block. E.g.:
# tower_extra_volumes: |
# - name: my-volume
# emptyDir: {}
tower_extra_volumes: ''
# Use these image versions for Ansible AWX.
tower_image: ansible/awx:15.0.0
tower_image_pull_policy: IfNotPresent
tower_create_preload_data: true
tower_replicas: "1"
tower_task_args:
- /usr/bin/launch_awx_task.sh
tower_task_command: []
tower_web_args: []
tower_web_command: []
tower_task_mem_request: 1Gi
tower_task_cpu_request: 500m
tower_web_mem_request: 2Gi
tower_web_cpu_request: 1000m
# Add extra environment variables to the AWX task/web containers. Specify as
# literal block. E.g.:
# tower_task_extra_env: |
# - name: FOO
# value: bar
# - name: BAZ
# value: bing
tower_task_extra_env: ''
tower_web_extra_env: ''
# Mount extra volumes on the AWX task/web containers. Specify as literal block.
# E.g.:
# tower_task_extra_volume_mounts: ''
# - name: my-volume
# mountPath: /some/path
tower_task_extra_volume_mounts: ''
tower_web_extra_volume_mounts: ''
tower_redis_image: redis:latest
tower_postgres_pass: awxpass
tower_postgres_image: postgres:12
tower_postgres_storage_request: 8Gi
tower_postgres_storage_class: ''
tower_postgres_data_path: '/var/lib/postgresql/data/pgdata'
tower_postgres_port: 5432
ca_trust_bundle: "/etc/pki/tls/certs/ca-bundle.crt"
development_mode: false

View File

@@ -1,37 +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
no_log: true
- 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

@@ -1,111 +0,0 @@
---
- name: Check for existing secret key
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-secret-key'
register: secret_key_resources
- name: Check for existing postgres configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-postgres-configuration'
register: postgres_config_resources
- name: Create Database configuration if it doesn't already exist
k8s:
apply: yes
definition: "{{ lookup('template', 'tower_postgres_secret.yaml.j2') }}"
register: k8s_postgres_config_result
when: postgres_config_resources['resources'] | length < 1 and not external_database | default(False) | bool
- name: Create Database if External Database not selected
k8s:
apply: yes
definition: "{{ lookup('template', 'tower_postgres.yaml.j2') }}"
register: k8s_postgres_result
when: not external_database | default(False) | bool
- name: Read Database Configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-postgres-configuration'
register: postgres_configuration
- name: Store Database Configuration
set_fact:
awx_postgres_user: "{{ postgres_configuration['resources'][0]['data']['username'] | b64decode }}"
awx_postgres_pass: "{{ postgres_configuration['resources'][0]['data']['password'] | b64decode }}"
awx_postgres_database: "{{ postgres_configuration['resources'][0]['data']['database'] | b64decode }}"
awx_postgres_port: "{{ postgres_configuration['resources'][0]['data']['port'] | b64decode }}"
awx_postgres_host: "{{ postgres_configuration['resources'][0]['data']['host'] | b64decode }}"
- name: Deploy Tower Secret Key if needed
k8s:
apply: yes
definition: "{{ lookup('template', 'tower_secret.yaml.j2') }}"
register: k8s_tower_secret_result
when: secret_key_resources['resources'] | length < 1
- name: Ensure configured AWX resources exist in the cluster.
k8s:
apply: yes
definition: "{{ lookup('template', item) | from_yaml_all | list }}"
register: k8s_defs_result
with_items:
- tower_config.yaml.j2
- name: Apply Tower Deployment Configuration
k8s:
apply: yes
definition: "{{ lookup('template', 'tower.yaml.j2') }}"
register: tower_deployment_result
- name: Get the AWX pod information.
k8s_info:
kind: Pod
namespace: '{{ meta.namespace }}'
label_selectors:
- app=awx
register: tower_pods
until: "tower_pods['resources'][0]['status']['phase'] == 'Running'"
delay: 5
retries: 60
- name: Set the awx pod name as a variable.
set_fact:
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] }}"
- name: Verify tower_pod_name is populated.
assert:
that: tower_pod_name != ''
fail_msg: "Could not find the tower pod's name."
- name: Check if database is populated (auth_user table exists).
community.kubernetes.k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "echo 'from django.db import connection;
tbl = \"auth_user\" in connection.introspection.table_names();
exit(0 if tbl else 1)'
| awx-manage shell"
ignore_errors: true
changed_when: false
register: database_check
when: k8s_defs_result is not changed
- name: Migrate the database if the K8s resources were updated. # noqa 305
community.kubernetes.k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage migrate --noinput"
register: migrate_result
when: (k8s_defs_result is changed) or (database_check is defined and database_check.return_code != 0)
- include_tasks: initialize.yml

View File

@@ -1,5 +0,0 @@
DATABASE_USER={{ awx_postgres_user }}
DATABASE_NAME={{ awx_postgres_database }}
DATABASE_HOST={{ awx_postgres_host }}
DATABASE_PORT={{ awx_postgres_port }}
DATABASE_PASSWORD={{ awx_postgres_pass }}

View File

@@ -1,280 +0,0 @@
# AWX Secret Configurations
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-secrets'
namespace: '{{ meta.namespace }}'
data:
credentials_py: "{{ lookup('template', 'credentials.py.j2') | b64encode }}"
environment_sh: "{{ lookup('template', 'environment.sh.j2') | b64encode }}"
# AWX Deployment.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
labels:
app: awx
spec:
replicas: {{ tower_replicas }}
selector:
matchLabels:
app: awx
template:
metadata:
labels:
app: awx
spec:
containers:
- image: '{{ tower_redis_image }}'
name: redis
args: ["redis-server", "/etc/redis.conf"]
volumeMounts:
- name: {{ meta.name }}-redis-config
mountPath: "/etc/redis.conf"
subPath: redis.conf
readOnly: true
- name: {{ meta.name }}-redis-socket
mountPath: "/var/run/redis"
- image: '{{ tower_image }}'
name: '{{ meta.name }}-web'
{% if tower_web_command %}
command: {{ tower_web_command }}
{% endif %}
{% if tower_web_args %}
args: {{ tower_web_args }}
{% endif %}
imagePullPolicy: '{{ tower_image_pull_policy }}'
ports:
- containerPort: 8052
volumeMounts:
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/"
readOnly: true
- name: {{ meta.name }}-secret-key
mountPath: /etc/tower/SECRET_KEY
subPath: SECRET_KEY
readOnly: true
- name: {{ meta.name }}-settings
mountPath: /etc/tower/settings.py
subPath: settings.py
readOnly: true
- name: {{ meta.name }}-nginx-conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
readOnly: true
- name: {{ meta.name }}-redis-socket
mountPath: "/var/run/redis"
- name: supervisor-socket
mountPath: "/var/run/supervisor"
- name: rsyslog-socket
mountPath: "/var/run/awx-rsyslog"
- name: rsyslog-dir
mountPath: "/var/lib/awx/rsyslog"
{% 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) }}
{% endif %}
{% if (development_mode | bool) or (tower_task_extra_env | bool) %}
env:
{% endif %}
{% if development_mode | bool %}
- name: AWX_KUBE_DEVEL
value: "1"
{% endif %}
{% if tower_task_extra_env %}
{{ tower_web_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
resources:
requests:
memory: '{{ tower_web_mem_request }}'
cpu: '{{ tower_web_cpu_request }}'
- image: '{{ tower_image }}'
name: '{{ meta.name }}-task'
imagePullPolicy: '{{ tower_image_pull_policy }}'
{% if tower_task_privileged == true %}
securityContext:
privileged: true
{% endif %}
{% if tower_task_command %}
command: {{ tower_task_command }}
{% endif %}
{% if tower_task_args %}
args: {{ tower_task_args }}
{% endif %}
volumeMounts:
- name: "{{ meta.name }}-application-credentials"
mountPath: "/etc/tower/conf.d/"
readOnly: true
- name: {{ meta.name }}-secret-key
mountPath: /etc/tower/SECRET_KEY
subPath: SECRET_KEY
readOnly: true
- name: {{ meta.name }}-settings
mountPath: /etc/tower/settings.py
subPath: settings.py
readOnly: true
- name: {{ meta.name }}-redis-socket
mountPath: "/var/run/redis"
- name: supervisor-socket
mountPath: "/var/run/supervisor"
- name: rsyslog-socket
mountPath: "/var/run/awx-rsyslog"
- name: rsyslog-dir
mountPath: "/var/lib/awx/rsyslog"
{% if development_mode | bool %}
- name: awx-devel
mountPath: "/awx_devel"
{% endif %}
{% if tower_task_extra_volume_mounts -%}
{{ tower_task_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% endif %}
env:
- name: SUPERVISOR_WEB_CONFIG_PATH
value: "/supervisor.conf"
- name: AWX_SKIP_MIGRATIONS
value: "1"
- name: MY_POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
{% if development_mode | bool %}
- name: AWX_KUBE_DEVEL
value: "1"
{% endif %}
{% if tower_task_extra_env -%}
{{ tower_task_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
resources:
requests:
memory: '{{ tower_task_mem_request }}'
cpu: '{{ tower_task_cpu_request }}'
volumes:
- name: "{{ meta.name }}-application-credentials"
secret:
secretName: "{{ meta.name }}-secrets"
items:
- key: credentials_py
path: 'credentials.py'
- key: environment_sh
path: 'environment.sh'
- name: {{ meta.name }}-secret-key
secret:
secretName: '{{ meta.name }}-secret-key'
items:
- key: secret_key
path: SECRET_KEY
- name: {{ meta.name }}-settings
configMap:
name: '{{ meta.name }}-awx-configmap'
items:
- key: settings
path: settings.py
- name: {{ meta.name }}-nginx-conf
configMap:
name: '{{ meta.name }}-awx-configmap'
items:
- key: nginx_conf
path: nginx.conf
- name: {{ meta.name }}-redis-config
configMap:
name: {{ meta.name }}-awx-configmap
items:
- key: redis_conf
path: redis.conf
- name: {{ meta.name }}-redis-socket
emptyDir: {}
- name: supervisor-socket
emptyDir: {}
- name: rsyslog-socket
emptyDir: {}
- name: rsyslog-dir
emptyDir: {}
{% if development_mode | bool %}
- name: awx-devel
hostPath:
path: /awx_devel
{% endif %}
{% if tower_extra_volumes -%}
{{ tower_extra_volumes | indent(width=8, indentfirst=True) }}
{% endif %}
# AWX Service.
---
apiVersion: v1
kind: Service
metadata:
name: '{{ meta.name }}-service'
namespace: '{{ meta.namespace }}'
labels:
app: awx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8052
name: http
selector:
app: awx
{% if tower_ingress_type != "none" %}
type: NodePort
{% endif %}
# AWX Ingress.
{% if 'ingress' == tower_ingress_type|lower %}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: '{{ meta.name }}-ingress'
namespace: '{{ meta.namespace }}'
{% 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 }}'
spec:
port:
targetPort: http
tls:
insecureEdgeTerminationPolicy: Redirect
termination: edge
to:
kind: Service
name: {{ meta.name }}-service
weight: 100
wildcardPolicy: None
{% endif %}

View File

@@ -1,79 +0,0 @@
# Postgres StatefulSet.
---
apiVersion: v1
kind: StatefulSet
metadata:
name: '{{ meta.name }}-postgres'
namespace: '{{ meta.namespace }}'
labels:
app: awx-postgres
spec:
selector:
matchLabels:
app: awx-postgres
serviceName: '{{ meta.name }}'
replicas: 1
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: awx-postgres
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 }}'
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:
requests:
storage: '{{ tower_postgres_storage_request }}'
# Postgres Service.
---
apiVersion: v1
kind: Service
metadata:
name: '{{ meta.name }}-postgres'
namespace: '{{ meta.namespace }}'
labels:
app: awx-postgres
spec:
ports:
- port: 5432
clusterIP: None
selector:
app: awx-postgres

View File

@@ -1,13 +0,0 @@
# Postgres Secret.
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-postgres-configuration'
namespace: '{{ meta.namespace }}'
stringData:
password: '{{ lookup('password', 'p' + meta.name + 'pg length=32 chars=ascii_letters,digits') }}'
username: 'awx'
database: 'awx'
port: '5432'
host: {{ meta.name }}-postgres

View File

@@ -1,8 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-secret-key'
namespace: '{{ meta.namespace }}'
stringData:
secret_key: '{{ lookup('password', 'ts' + meta.name + 'pg length=32 chars=ascii_letters,digits') }}'

View File

@@ -1,36 +0,0 @@
---
- name: Check for existing secret key
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-secret-key'
register: secret_key_resources
- name: Check for existing postgres configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-postgres-configuration'
register: postgres_config_resources
- name: Remove ownerReferences from PG configuration if it exists
k8s:
definition:
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-postgres-configuration'
namespace: '{{ meta.namespace }}'
ownerReferences: null
when: postgres_config_resources['resources'] | length > 0
- name: Remove ownerReferences from Tower Secret if it exists
k8s:
definition:
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-secret-key'
namespace: '{{ meta.namespace }}'
ownerReferences: null
when: secret_key_resources['resources'] | length > 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:
- community.kubernetes
- operator_sdk.util

View File

@@ -0,0 +1,33 @@
---
- 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: "{{ _awx_cro['resources'][0] }}"
- name: Set user specified spec
set_fact:
awx_spec: "{{ _awx['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 | 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,69 @@
---
- 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) }}"
- name: Create PVC for backup
k8s:
kind: PersistentVolumeClaim
template: "backup_pvc.yml.j2"
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,33 @@
---
- 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
- ldap_cacert_secret
- image_pull_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

@@ -0,0 +1,214 @@
---
deployment_type: awx
kind: '{{ deployment_type | upper }}'
api_version: '{{ deployment_type }}.ansible.com/v1beta1'
database_name: "{{ deployment_type }}"
database_username: "{{ deployment_type }}"
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.:
# ingress_annotations: |
# kubernetes.io/ingress.class: nginx
# nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s
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.
ingress_tls_secret: ''
loadbalancer_protocol: 'http'
loadbalancer_port: '80'
loadbalancer_annotations: ''
# The TLS termination mechanism to use to access
# the services. Supported mechanism are: edge, passthrough
#
route_tls_termination_mechanism: edge
# Secret to lookup that provide the TLS specific
# credentials to deploy
#
route_tls_secret: ''
# Host to create the root with.
# If not specific will default to <instance-name>-<namespace>-<routerCanonicalHostname>
#
route_host: ''
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.:
# node_selector: |
# disktype: ssd
# kubernetes.io/arch: amd64
# kubernetes.io/os: linux
node_selector: ''
# Add node tolerations for the AWX pods. Specify as literal block. E.g.:
# tolerations: |
# - key: "dedicated"
# operator: "Equal"
# value: "AWX"
# effect: "NoSchedule"
tolerations: ''
admin_user: admin
admin_email: test@example.com
# Secret to lookup that provide the admin password
#
admin_password_secret: ''
# Secret to lookup that provide the broadcast websocket key
#
broadcast_websocket_secret: ''
# Secret to lookup that provide the secret key
#
secret_key_secret: ''
# Secret to lookup that provide the PostgreSQL configuration
#
postgres_configuration_secret: ''
# Secret to lookup that provides old database credentials (for migration)
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.:
# extra_volumes: |
# - name: my-volume
# emptyDir: {}
extra_volumes: ''
# Use these image versions for Ansible AWX.
image: quay.io/ansible/awx
image_version: 19.2.1
redis_image: docker.io/redis
redis_image_version: latest
postgres_image: postgres
postgres_image_version: 12
image_pull_policy: IfNotPresent
image_pull_secret: ''
ee_images:
- name: AWX EE 0.4.0
image: quay.io/ansible/awx-ee:0.4.0
control_plane_ee_image: quay.io/ansible/awx-ee:0.4.0
create_preload_data: true
replicas: "1"
task_args:
- /usr/bin/launch_awx_task.sh
task_command: []
web_args: []
web_command: []
task_resource_requirements:
requests:
cpu: 500m
memory: 1Gi
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.:
# task_extra_env: |
# - name: FOO
# value: bar
# - name: BAZ
# value: bing
task_extra_env: ''
web_extra_env: ''
ee_extra_env: ''
# Mount extra volumes on the AWX task/web containers. Specify as literal block.
# E.g.:
# task_extra_volume_mounts: ''
# - name: my-volume
# mountPath: /some/path
task_extra_volume_mounts: ''
web_extra_volume_mounts: ''
ee_extra_volume_mounts: ''
# 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: ''
# 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
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
projects_persistence: false
#
# Define an existing PersistentVolumeClaim to use
projects_existing_claim: ''
#
# Define the storage_class, size and access_mode
# when not using an existing claim
projects_storage_size: 8Gi
projects_storage_access_mode: ReadWriteMany
ca_trust_bundle: "/etc/pki/tls/certs/ca-bundle.crt"
# Secret to lookup that provides the LDAP CACert trusted bundle
#
ldap_cacert_secret: ''
# Whether secrets should be garbage collected
# on teardown
#
garbage_collect_secrets: false
development_mode: false

View File

@@ -29,3 +29,4 @@ dependencies: []
collections:
- community.kubernetes
- operator_sdk.util

View File

@@ -0,0 +1,42 @@
---
- name: Check for specified admin password configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ admin_password_secret }}'
register: _custom_admin_password
when: admin_password_secret | length
- name: Check for default admin password configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-admin-password'
register: _default_admin_password
- name: Set admin password secret
set_fact:
_admin_password_secret: '{{ _custom_admin_password["resources"] | default([]) | length | ternary(_custom_admin_password, _default_admin_password) }}'
- block:
- name: Create admin password secret
k8s:
apply: true
definition: "{{ lookup('template', 'admin_password_secret.yaml.j2') }}"
- name: Read admin password secret
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-admin-password'
register: _generated_admin_password
when: not _admin_password_secret['resources'] | default([]) | length
- name: Set admin password secret
set_fact:
__admin_password_secret: '{{ _generated_admin_password["resources"] | default([]) | length | ternary(_generated_admin_password, _admin_password_secret) }}'
- name: Store admin password
set_fact:
admin_password: "{{ __admin_password_secret['resources'][0]['data']['password'] | b64decode }}"

View File

@@ -0,0 +1,44 @@
---
- name: Check for specified broadcast websocket secret configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ broadcast_websocket_secret }}'
register: _custom_broadcast_websocket
when: broadcast_websocket_secret | length
- name: Check for default broadcast websocket secret configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-broadcast-websocket'
register: _default_broadcast_websocket
- name: Set broadcast websocket secret
set_fact:
# yamllint disable-line rule:line-length
_broadcast_websocket_secret: '{{ _custom_broadcast_websocket["resources"] | default([]) | length | ternary(_custom_broadcast_websocket, _default_broadcast_websocket) }}' # noqa 204
- block:
- name: Create broadcast websocket secret
k8s:
apply: true
definition: "{{ lookup('template', 'broadcast_websocket_secret.yaml.j2') }}"
- name: Read broadcast websocket secret
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-broadcast-websocket'
register: _generated_broadcast_websocket
when: not _broadcast_websocket_secret['resources'] | default([]) | length
- 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
- name: Store broadcast websocket secret name
set_fact:
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

@@ -0,0 +1,129 @@
---
- name: Check for specified PostgreSQL configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ postgres_configuration_secret }}'
register: _custom_pg_config_resources
when: postgres_configuration_secret | length
- name: Check for default PostgreSQL configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-postgres-configuration'
register: _default_pg_config_resources
- name: Check for specified old PostgreSQL configuration secret
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ old_postgres_configuration_secret }}'
register: _custom_old_pg_config_resources
when: old_postgres_configuration_secret | length
- name: Check for default old PostgreSQL configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-old-postgres-configuration'
register: _default_old_pg_config_resources
- name: Set old PostgreSQL configuration
set_fact:
# yamllint disable-line rule:line-length
old_pg_config: '{{ _custom_old_pg_config_resources["resources"] | default([]) | length | ternary(_custom_old_pg_config_resources, _default_old_pg_config_resources) }}' # noqa 204
- name: Set proper database name when migrating from old deployment
set_fact:
database_name: "{{ old_pg_config['resources'][0]['data']['database'] | b64decode }}"
database_username: "{{ old_pg_config['resources'][0]['data']['username'] | b64decode }}"
when:
- old_pg_config['resources'] is defined
- old_pg_config['resources'] | length
- name: Set PostgreSQL configuration
set_fact:
_pg_config: '{{ _custom_pg_config_resources["resources"] | default([]) | length | ternary(_custom_pg_config_resources, _default_pg_config_resources) }}'
- block:
- name: Create Database configuration
k8s:
apply: true
definition: "{{ lookup('template', 'postgres_secret.yaml.j2') }}"
- name: Read Database Configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-postgres-configuration'
register: _generated_pg_config_resources
when: not _pg_config['resources'] | default([]) | length
- name: Set PostgreSQL Configuration
set_fact:
pg_config: '{{ _generated_pg_config_resources["resources"] | default([]) | length | ternary(_generated_pg_config_resources, _pg_config) }}'
- 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
community.kubernetes.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:
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_sslmode: "{{ pg_config['resources'][0]['data']['sslmode'] | default('prefer'|b64encode) | b64decode }}"
- name: Look up details for this deployment
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
register: this_awx
- name: Migrate data from old Openshift instance
import_tasks: migrate_data.yml
when:
- old_pg_config['resources'] is defined
- old_pg_config['resources'] | length
- this_awx['resources'][0]['status']['migratedFromSecret'] is not defined

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 LDAP CA Certificate Secret
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ ldap_cacert_secret }}'
register: ldap_cacert
- name: Load LDAP CA Certificate Secret content
set_fact:
ldap_cacert_ca_crt: '{{ ldap_cacert["resources"][0]["data"]["ldap-ca.crt"] | b64decode }}'
when: '"ldap-ca.crt" in ldap_cacert["resources"][0]["data"]'

View File

@@ -0,0 +1,17 @@
---
- name: Retrieve Route TLS Secret
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ route_tls_secret }}'
register: route_tls
- name: Load Route TLS Secret content
set_fact:
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:
route_ca_crt: '{{ route_tls["resources"][0]["data"]["ca.crt"] | b64decode }}'
when: '"ca.crt" in route_tls["resources"][0]["data"]'

View File

@@ -0,0 +1,75 @@
---
- name: Patching labels to AWX 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: Include secret key configuration tasks
include_tasks: secret_key_configuration.yml
- name: Load LDAP CAcert certificate
include_tasks: load_ldap_cacert_secret.yml
when:
- ldap_cacert_secret != ''
- name: Include admin password configuration tasks
include_tasks: admin_password_configuration.yml
- name: Include broadcast websocket configuration tasks
include_tasks: broadcast_websocket_configuration.yml
- name: Include database configuration tasks
include_tasks: database_configuration.yml
- name: Load Route TLS certificate
include_tasks: load_route_tls_secret.yml
when:
- ingress_type | lower == 'route'
- route_tls_secret != ''
- name: Include resources configuration tasks
include_tasks: resources_configuration.yml
- name: Check for pending migrations
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l"
changed_when: false
register: database_check
- name: Migrate the database if the K8s resources were updated. # noqa 305
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage migrate --noinput"
register: migrate_result
when:
- database_check is defined
- (database_check.stdout|trim) != '0'
- 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

@@ -0,0 +1,73 @@
---
- 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:
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 }}'
name: '{{ meta.name }}-postgres-0' # using name to keep compatibility
field_selectors:
- status.phase=Running
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'] }}"
- name: Scale down Deployment for migration
include_tasks: scale_down_deployment.yml
- name: Set pg_dump command
set_fact:
pgdump: >-
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:
pg_restore: >-
pg_restore --clean --if-exists
-U {{ database_username }}
-d {{ database_name }}
- name: Stream backup from pg_dump to the new postgresql container
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ postgres_pod_name }}"
command: |
bash -c """
set -e -o pipefail
PGPASSWORD={{ awx_old_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ pg_restore }}
echo 'Successful'
"""
register: data_migration
failed_when: "'Successful' not in data_migration.stdout"
- name: Set flag signifying that this instance has been migrated
set_fact:
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
community.kubernetes.k8s_scale:
api_version: v1
kind: Deployment
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
replicas: 0
wait: yes
when: tower_deployment['resources'] | length

View File

@@ -0,0 +1,42 @@
---
- name: Check for specified secret key configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ secret_key_secret }}'
register: _custom_secret_key
when: secret_key_secret | length
- name: Check for default secret key configuration
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-secret-key'
register: _default_secret_key
- name: Set secret key secret
set_fact:
_secret_key_secret: '{{ _custom_secret_key["resources"] | default([]) | length | ternary(_custom_secret_key, _default_secret_key) }}'
- block:
- name: Create secret key secret
k8s:
apply: true
definition: "{{ lookup('template', 'secret_key.yaml.j2') }}"
- name: Read secret key secret
k8s_info:
kind: Secret
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}-secret-key'
register: _generated_secret_key
when: not _secret_key_secret['resources'] | default([]) | length
- name: Set secret key secret
set_fact:
__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'] }}"

View File

@@ -0,0 +1,102 @@
---
- name: Update admin password status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
adminPasswordSecret: "{{ __admin_password_secret['resources'][0]['metadata']['name'] }}"
- name: Update admin user status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
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
k8s_exec:
namespace: "{{ meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ meta.name }}-task"
command: >-
bash -c "awx-manage --version"
register: instance_version
changed_when: false
- name: Update version status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
version: "{{ instance_version.stdout | trim }}"
- name: Update image status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
image: "{{ image }}"
- block:
- name: Retrieve route URL
k8s_info:
kind: Route
namespace: '{{ meta.namespace }}'
name: '{{ meta.name }}'
register: route_url
- name: Update URL status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
URL: "https://{{ route_url['resources'][0]['status']['ingress'][0]['host'] }}"
when: ingress_type | lower == 'route'
- name: Update migratedFromSecret status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ meta.name }}"
namespace: "{{ meta.namespace }}"
status:
migratedFromSecret: "{{ tower_migrated_from_secret }}"
when: tower_migrated_from_secret is defined

View File

@@ -0,0 +1,14 @@
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-admin-password'
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") }}'
stringData:
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -0,0 +1,17 @@
# AWX Secret Configurations
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-app-credentials'
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") }}'
data:
credentials.py: "{{ lookup('template', 'credentials.py.j2') | b64encode }}"
ldap.py: "{{ lookup('template', 'ldap.py.j2') | b64encode }}"
execution_environments.py: "{{ lookup('template', 'execution_environments.py.j2') | b64encode }}"

View File

@@ -0,0 +1,14 @@
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-broadcast-websocket'
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") }}'
stringData:
secret: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -3,17 +3,16 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: '{{ meta.name }}-awx-configmap'
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
namespace: '{{ meta.namespace }}'
labels:
app: awx
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") }}'
data:
environment: |
DATABASE_USER=awx
DATABASE_NAME=awx
DATABASE_HOST='{{ meta.name }}-postgres.{{ meta.namespace }}.svc.cluster.local'
DATABASE_PORT='5432'
DATABASE_PASSWORD={{ tower_postgres_pass | quote }}
AWX_SKIP_MIGRATIONS=true
settings: |
@@ -28,7 +27,9 @@ data:
STATIC_ROOT = '/var/lib/awx/public/static'
PROJECTS_ROOT = '/var/lib/awx/projects'
JOBOUTPUT_ROOT = '/var/lib/awx/job_status'
IS_K8S = True
SECRET_KEY = get_secret()
ALLOWED_HOSTS = ['*']
@@ -64,6 +65,7 @@ data:
'()': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'simple',
'filters': ['guid'],
}
LOGGING['loggers']['django.request']['handlers'] = ['console']
@@ -76,33 +78,25 @@ 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'}
LOGGING['handlers']['rbac_migrations'] = {'class': 'logging.NullHandler'}
LOGGING['handlers']['system_tracking_migrations'] = {'class': 'logging.NullHandler'}
LOGGING['handlers']['management_playbooks'] = {'class': 'logging.NullHandler'}
DATABASES = {
'default': {
'ATOMIC_REQUESTS': True,
'ENGINE': 'awx.main.db.profiled_pg',
'NAME': 'awx',
'USER': 'awx',
'PASSWORD': '{{ tower_postgres_pass | quote }}',
'HOST': '{{ meta.name }}-postgres.{{ meta.namespace }}.svc.cluster.local',
'PORT': '5432',
}
}
if os.getenv("DATABASE_SSLMODE", False):
DATABASES['default']['OPTIONS'] = {'sslmode': os.getenv("DATABASE_SSLMODE")}
USE_X_FORWARDED_PORT = True
BROADCAST_WEBSOCKET_PORT = 8052
BROADCAST_WEBSOCKET_PROTOCOL = 'http'
{% for item in extra_settings | default([]) %}
{% if item.value is string %}
{{ item.setting }} = '{{ item.value }}'
{% else %}
{{ item.setting }} = {{ item.value }}
{% endif %}
{% endfor %}
nginx_conf: |
worker_processes 1;
pid /tmp/nginx.pid;
@@ -139,17 +133,38 @@ data:
server 127.0.0.1:8051;
}
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
server {
listen 8052 default_server;
server_name _;
# Redirect all HTTP links to the matching HTTPS page
return 301 https://$host$request_uri;
}
{% endif %}
server {
{% 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 %}
# If you have a domain name, this is where to add it
server_name _;
keepalive_timeout 65;
# 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";
@@ -166,7 +181,7 @@ data:
}
location /favicon.ico {
alias /var/lib/awx/public/static/favicon.ico;
alias /var/lib/awx/public/static/media/favicon.ico;
}
location /websocket {
@@ -202,6 +217,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";
}
}
}
@@ -210,3 +232,33 @@ data:
unixsocketperm 777
port 0
bind 127.0.0.1
receptor_conf: |
---
- log-level: debug
- control-service:
service: control
filename: /var/run/receptor/receptor.sock
permissions: 0660
- local-only:
- work-command:
worktype: local
command: ansible-runner
params: worker
allowruntimeparams: true
- work-kubernetes:
worktype: kubernetes-runtime-auth
authmethod: runtime
allowruntimeauth: true
allowruntimepod: true
allowruntimeparams: true
- work-kubernetes:
worktype: kubernetes-incluster-auth
authmethod: incluster
allowruntimeauth: true
allowruntimepod: true
allowruntimeparams: true

View File

@@ -7,10 +7,10 @@ DATABASES = {
'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 }}',
},
}
}
BROADCAST_WEBSOCKET_SECRET = "{{ tower_broadcast_websocket_secret | b64encode }}"
BROADCAST_WEBSOCKET_SECRET = "{{ broadcast_websocket_secret_value }}"

View File

@@ -0,0 +1,332 @@
# AWX Deployment.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: '{{ meta.name }}'
namespace: '{{ meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ meta.name }}'
app.kubernetes.io/version: '{{ image_version }}'
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:
replicas: {{ replicas }}
selector:
matchLabels:
app.kubernetes.io/name: '{{ meta.name }}'
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: '{{ image_version }}'
app.kubernetes.io/part-of: '{{ meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
spec:
serviceAccountName: '{{ meta.name }}'
{% if image_pull_secret %}
imagePullSecrets:
- name: {{ image_pull_secret }}
{% endif %}
containers:
- image: '{{ redis_image }}:{{ redis_image_version }}'
imagePullPolicy: '{{ image_pull_policy }}'
name: redis
args: ["redis-server", "/etc/redis.conf"]
volumeMounts:
- name: {{ meta.name }}-redis-config
mountPath: "/etc/redis.conf"
subPath: redis.conf
readOnly: true
- name: {{ meta.name }}-redis-socket
mountPath: "/var/run/redis"
- name: "{{ meta.name }}-redis-data"
mountPath: "/data"
- image: '{{ image }}:{{ image_version }}'
name: '{{ meta.name }}-web'
{% if web_command %}
command: {{ web_command }}
{% endif %}
{% if web_args %}
args: {{ web_args }}
{% endif %}
imagePullPolicy: '{{ image_pull_policy }}'
ports:
- containerPort: 8052
{% 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/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
{% endif %}
{% if ldap_cacert_ca_crt %}
- name: "{{ meta.name }}-ldap-cacert"
mountPath: /etc/openldap/certs/ldap-ca.crt
subPath: ldap-ca.crt
readOnly: true
{% endif %}
- name: "{{ secret_key_secret_name }}"
mountPath: /etc/tower/SECRET_KEY
subPath: SECRET_KEY
readOnly: true
- name: {{ meta.name }}-settings
mountPath: /etc/tower/settings.py
subPath: settings.py
readOnly: true
- name: {{ meta.name }}-nginx-conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
readOnly: true
- name: {{ meta.name }}-redis-socket
mountPath: "/var/run/redis"
- name: supervisor-socket
mountPath: "/var/run/supervisor"
- name: rsyslog-socket
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 web_extra_volume_mounts -%}
{{ web_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% endif %}
env:
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{% if development_mode | bool %}
- name: AWX_KUBE_DEVEL
value: "1"
{% endif %}
{% if web_extra_env -%}
{{ web_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
resources: {{ web_resource_requirements }}
- image: '{{ image }}:{{ image_version }}'
name: '{{ meta.name }}-task'
imagePullPolicy: '{{ image_pull_policy }}'
{% if task_privileged == true %}
securityContext:
privileged: true
{% endif %}
{% if task_command %}
command: {{ task_command }}
{% endif %}
{% if task_args %}
args: {{ task_args }}
{% endif %}
volumeMounts:
- 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
- name: "{{ secret_key_secret_name }}"
mountPath: /etc/tower/SECRET_KEY
subPath: SECRET_KEY
readOnly: true
- name: {{ meta.name }}-settings
mountPath: /etc/tower/settings.py
subPath: settings.py
readOnly: true
- name: {{ meta.name }}-redis-socket
mountPath: "/var/run/redis"
- name: supervisor-socket
mountPath: "/var/run/supervisor"
- name: rsyslog-socket
mountPath: "/var/run/awx-rsyslog"
- name: rsyslog-dir
mountPath: "/var/lib/awx/rsyslog"
- name: receptor-socket
mountPath: "/var/run/receptor"
- name: "{{ meta.name }}-projects"
mountPath: "/var/lib/awx/projects"
{% if development_mode | bool %}
- name: awx-devel
mountPath: "/awx_devel"
{% endif %}
{% if task_extra_volume_mounts -%}
{{ task_extra_volume_mounts | indent(width=12, indentfirst=True) }}
{% endif %}
env:
- name: SUPERVISOR_WEB_CONFIG_PATH
value: "/etc/supervisord.conf"
- name: AWX_SKIP_MIGRATIONS
value: "1"
- name: MY_POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{% if development_mode | bool %}
- name: AWX_KUBE_DEVEL
value: "1"
{% endif %}
{% if task_extra_env -%}
{{ task_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
resources: {{ task_resource_requirements }}
- image: '{{ control_plane_ee_image }}'
name: '{{ meta.name }}-ee'
imagePullPolicy: '{{ image_pull_policy }}'
resources: {{ ee_resource_requirements }}
args: ['receptor', '--config', '/etc/receptor.conf']
volumeMounts:
- name: "{{ meta.name }}-receptor-config"
mountPath: "/etc/receptor.conf"
subPath: receptor.conf
readOnly: true
- name: receptor-socket
mountPath: "/var/run/receptor"
- name: "{{ meta.name }}-projects"
mountPath: "/var/lib/awx/projects"
{% 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 ee_extra_env -%}
{{ ee_extra_env | indent(width=12, indentfirst=True) }}
{% endif %}
{% if node_selector %}
nodeSelector:
{{ node_selector | indent(width=8) }}
{% endif %}
{% if tolerations %}
tolerations:
{{ tolerations | indent(width=8) }}
{% endif %}
volumes:
{% if ingress_type | lower == 'route' and route_tls_termination_mechanism | lower == 'passthrough' %}
- name: "{{ meta.name }}-nginx-certs"
secret:
secretName: "{{ route_tls_secret }}"
items:
- key: tls.key
path: 'web.key'
- key: tls.crt
path: 'web.crt'
{% endif %}
{% if ldap_cacert_ca_crt %}
- name: "{{ meta.name }}-ldap-cacert"
secret:
secretName: "{{ ldap_cacert_secret }}"
items:
- key: ldap-ca.crt
path: 'ldap-ca.crt'
{% endif %}
- name: "{{ meta.name }}-application-credentials"
secret:
secretName: "{{ meta.name }}-app-credentials"
items:
- key: credentials.py
path: 'credentials.py'
- key: ldap.py
path: 'ldap.py'
- key: execution_environments.py
path: 'execution_environments.py'
- name: "{{ secret_key_secret_name }}"
secret:
secretName: '{{ secret_key_secret_name }}'
items:
- key: secret_key
path: SECRET_KEY
- name: {{ meta.name }}-settings
configMap:
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
items:
- key: settings
path: settings.py
- name: {{ meta.name }}-nginx-conf
configMap:
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
items:
- key: nginx_conf
path: nginx.conf
- name: {{ meta.name }}-redis-config
configMap:
name: {{ meta.name }}-{{ deployment_type }}-configmap
items:
- key: redis_conf
path: redis.conf
- name: {{ meta.name }}-redis-socket
emptyDir: {}
- name: {{ meta.name }}-redis-data
emptyDir: {}
- name: supervisor-socket
emptyDir: {}
- name: rsyslog-socket
emptyDir: {}
- name: receptor-socket
emptyDir: {}
- name: rsyslog-dir
emptyDir: {}
- name: {{ meta.name }}-receptor-config
configMap:
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
items:
- key: receptor_conf
path: receptor.conf
- name: "{{ meta.name }}-projects"
{% if projects_persistence|bool %}
persistentVolumeClaim:
{% if projects_existing_claim %}
claimName: {{ projects_existing_claim }}
{% else %}
claimName: '{{ meta.name }}-projects-claim'
{% endif %}
{% else %}
emptyDir: {}
{% endif %}
{% if development_mode | bool %}
- name: awx-devel
hostPath:
path: /awx_devel
{% endif %}
{% if extra_volumes -%}
{{ extra_volumes | indent(width=8, indentfirst=True) }}
{% endif %}

View File

@@ -0,0 +1,6 @@
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,6 @@
AUTH_LDAP_GLOBAL_OPTIONS = {
{% if ldap_cacert_ca_crt %}
ldap.OPT_X_TLS_REQUIRE_CERT: True,
ldap.OPT_X_TLS_CACERTFILE: "/etc/openldap/certs/ldap-ca.crt"
{% 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

@@ -0,0 +1,20 @@
# Postgres Secret.
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ meta.name }}-postgres-configuration'
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") }}'
stringData:
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
username: '{{ database_username }}'
database: '{{ database_name }}'
port: '5432'
host: {{ meta.name }}-postgres
type: 'managed'

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