Compare commits

..

22 Commits

Author SHA1 Message Date
Shane McDonald
7697825944 Merge pull request #983 from shanemcd/ingress_path-test
Add tests around ingress_path feature
2022-07-11 19:55:28 -04:00
Shane McDonald
8a325293b1 Add tests around ingress_path feature 2022-07-11 19:45:11 -04:00
Shane McDonald
dd53a1d415 Merge pull request #980 from sdktr/958_pgdump_command_customization
Fix 958: allow pg_dump backup command customization
2022-07-11 19:30:30 -04:00
Shane McDonald
c5db0e7104 Merge pull request #954 from bewing/helm-namespace
remove namespace from helm chart
2022-07-11 19:18:08 -04:00
Stefan de Kooter
59036fc373 Add free format pg_dump backup parameter 2022-07-10 19:03:32 +00:00
Christian Adams
c45a7bd4d7 Add Docs notes for custom secret keys (#969) 2022-06-28 11:05:49 -04:00
Shane McDonald
34b6354001 Merge pull request #956 from Cl0udius/add_auto_upgrade_parameter
added auto_upgrade flag
2022-06-27 13:39:11 -04:00
Shane McDonald
801f392447 Merge pull request #964 from taishen/devel
Add an example of the nodeport_port in readme
2022-06-27 13:38:24 -04:00
Shane McDonald
779572e8ff Merge pull request #944 from viv-dev/backup-cleanup
Option to delete backup dir on PV when AWXBackup object is deleted
2022-06-27 13:35:57 -04:00
Shane McDonald
e7e48f92a0 Merge pull request #962 from rooftopcellist/operator-resource-defaults
Add default resource requests for operator container
2022-06-27 13:33:32 -04:00
Brandon Ewing
3cd9ddd8c6 remove namespace from helm chart
Helm should be able to set the namespace for the operator at deploy time
via the --namespace option.  Use yq to remove all references to
namespaces in the helm chart prior to publishing.

Update CI process to create namespace during install.

Resolves #907
2022-06-27 12:26:14 -05:00
taishen
4e6be0a82c Add an example of the nodeport_port in readme 2022-06-27 22:02:42 +08:00
Viviana Capote
05943687fe Added option to also delete backup directory on PVC when AWXBackup CRD object is deleted 2022-06-27 15:45:33 +10:00
Shane McDonald
9676ebc008 Merge pull request #955 from doanminhtu/tudoan/fix-ldap-password-secret-usage
Fix ldap bind password secret usage: ldap_password_secret
2022-06-26 10:45:26 -04:00
Christian M. Adams
8352237260 Add default resource requests for operator container 2022-06-24 16:40:45 -04:00
Alexander Stock
35d4954027 added auto_update flag 2022-06-23 15:05:05 +02:00
Shane McDonald
4d6a491766 Merge pull request #959 from mac-chaffee/no-latest
Use specific version of redis image
2022-06-23 08:16:21 -04:00
Shane McDonald
fa9eb53f92 Merge pull request #950 from basecom/feature/nginx-ipv6-support
Enable ipv6 listening in nginx config
2022-06-23 07:51:41 -04:00
Tu Doan
00c9f5fbd1 Fix ldap secret to secret file 2022-06-23 10:49:27 +07:00
Mac Chaffee
fe82e9259e Use specific version of redis image
Signed-off-by: Mac Chaffee <machaffe@renci.org>
2022-06-22 16:14:39 -04:00
Tu Doan
635d530dc9 Fix ldap bind password secret usage 2022-06-20 17:03:38 +07:00
Roger Sikorski
8b3a297086 enable ipv6 on nginx 2022-06-15 17:37:02 +02:00
23 changed files with 310 additions and 139 deletions

View File

@@ -63,4 +63,4 @@ jobs:
- name: Build and install helm chart
run: |
IMG=awx-operator-ci make helm-chart
helm install --wait my-awx-operator ./charts/awx-operator
helm install --wait my-awx-operator --namespace awx --create-namespace ./charts/awx-operator

View File

@@ -272,7 +272,6 @@ charts:
helm-chart: kustomize helm kubectl-slice yq charts
@echo "== KUSTOMIZE (image and namespace) =="
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
cd config/default && $(KUSTOMIZE) edit set namespace ${NAMESPACE}
@echo "== HELM =="
cd charts && \
@@ -293,6 +292,9 @@ helm-chart: kustomize helm kubectl-slice yq charts
--output-dir=charts/$(CHART_NAME)/templates \
--sort-by-kind
@echo "Helm Chart $(VERSION)" > charts/$(CHART_NAME)/templates/NOTES.txt
$(foreach file, $(wildcard charts/$(CHART_NAME)/templates/*),$(YQ) -i 'del(.. | select(has("namespace")).namespace)' $(file);)
$(foreach file, $(wildcard charts/$(CHART_NAME)/templates/*rolebinding*),$(YQ) -i '.subjects[0].namespace = "{{ .Release.Namespace }}"' $(file);)
rm -f charts/$(CHART_NAME)/templates/namespace*.yaml
.PHONY: helm-package

View File

@@ -45,6 +45,8 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
* [Session Cookie Secure Setting](#session-cookie-secure-setting)
* [Extra Settings](#extra-settings)
* [Configure no_log](#no-log)
* [Auto Upgrade](#auto-upgrade)
* [Upgrade of instances without auto upgrade](#upgrade-of-instances-without-auto-upgrade)
* [Service Account](#service-account)
* [Uninstall](#uninstall)
* [Upgrading](#upgrading)
@@ -192,8 +194,12 @@ metadata:
name: awx-demo
spec:
service_type: nodeport
# default nodeport_port is 30080
nodeport_port: <nodeport_port>
```
> It may make sense to create and specify your own secret key for your deployment so that if the k8s secret gets deleted, it can be re-created if needed. If it is not provided, one will be auto-generated, but cannot be recovered if lost. Read more [here](#secret-key-configuration).
Make sure to add this new file to the list of "resources" in your `kustomization.yaml` file:
```yaml
@@ -308,6 +314,41 @@ stringData:
```
### Secret Key Configuration
This key is used to encrypt sensitive data in the database.
| Name | Description | Default |
| ----------------- | ----------------------------------------------------- | ---------------- |
| secret_key_secret | Secret that contains the symmetric key for encryption | Generated |
> :warning: **secret_key_secret must be a Kubernetes secret and not your text clear secret value**.
If `secret_key_secret` is not provided, the operator will look for a secret named `<resourcename>-secret-key` for the secret key. If it is not present, the operator will generate a password and create a Secret from it named `<resourcename>-secret-key`. It is important to not delete this secret as it will be needed for upgrades and if the pods get scaled down at any point. If you are using a GitOps flow, you will want to pass a secret key secret.
The secret should be formatted as follow:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: custom-awx-secret-key
namespace: <target namespace>
stringData:
secret_key: supersecuresecretkey
```
Then specify the secret name on the AWX spec:
```yaml
---
spec:
...
secret_key_secret: custom-awx-secret-key
```
### Network and TLS Configuration
#### Service Type
@@ -1034,6 +1075,42 @@ Example configuration of `no_log` parameter
no_log: 'true'
```
#### Auto upgrade
With this parameter you can influence the behaviour during an operator upgrade.
If set to `true`, the operator will upgrade the specific instance directly.
When the value is set to `false`, and we have a running deployment, the operator will not update the AWX instance.
This can be useful when you have multiple AWX instances which you want to upgrade step by step instead of all at once.
| Name | Description | Default |
| -------------| ---------------------------------- | ------- |
| auto_upgrade | Automatic upgrade of AWX instances | true |
Example configuration of `auto_upgrade` parameter
```yaml
spec:
auto_upgrade: true
```
##### Upgrade of instances without auto upgrade
There are two ways to upgrade instances which are marked with the 'auto_upgrade: false' flag.
Changing flags:
- change the auto_upgrade flag on your AWX object to true
- wait until the upgrade process of that instance is finished
- change the auto_upgrade flag on your AWX object back to false
Delete the deployment:
- delete the deployment object of your AWX instance
```
$ kubectl -n awx delete deployment <yourInstanceName>
```
- wait until the instance gets redeployed
#### Service Account
@@ -1125,4 +1202,3 @@ We welcome your feedback and ideas. The AWX operator uses the same mailing list
- Join the `#ansible-awx` channel on irc.libera.chat
- Join the [mailing list](https://groups.google.com/forum/#!forum/awx-project)

View File

@@ -489,6 +489,10 @@ spec:
description: Key/values that will be set under the pod-level securityContext field
type: object
x-kubernetes-preserve-unknown-fields: true
auto_upgrade:
description: Should AWX instances be automatically upgraded when operator gets upgraded
type: boolean
default: true
type: object
status:
properties:

View File

@@ -43,6 +43,9 @@ spec:
backup_storage_class:
description: Storage class to use when creating PVC for backup
type: string
clean_backup_on_delete:
description: Flag to indicate if backup should be deleted on PVC if AWXBackup object is deleted
type: boolean
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string

View File

@@ -54,6 +54,13 @@ spec:
port: 6789
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "32Mi"
cpu: "50m"
limits:
memory: "4096Mi"
cpu: "2000m"
serviceAccountName: controller-manager
imagePullSecrets:
- name: redhat-operators-pull-secret

View File

@@ -49,13 +49,13 @@
name: Demo Job Template
wait: yes
validate_certs: no
controller_host: localhost
controller_host: localhost/awx/
controller_username: admin
controller_password: "{{ admin_pw_secret.resources[0].data.password | b64decode }}"
rescue:
- name: Get list of project updates and jobs
uri:
url: "http://localhost/api/v2/{{ resource }}/"
url: "http://localhost/awx/api/v2/{{ resource }}/"
user: admin
password: "{{ admin_pw_secret.resources[0].data.password | b64decode }}"
force_basic_auth: yes

View File

@@ -11,6 +11,7 @@ spec:
image_version: {{ awx_version }}
{% endif %}
ingress_type: ingress
ingress_path: /awx
ingress_annotations: |
kubernetes.io/ingress.class: nginx
web_resource_requirements:

0
projects/.gitkeep Executable file → Normal file
View File

View File

@@ -74,7 +74,12 @@ To check the name of this secret, look at the postgresConfigurationSecret status
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.
It is also possible to tie the lifetime of the backup files to that of the AWXBackup resource object. To do that you can set the
`clean_backup_on_delete` value to true. This will delete the `backupDirectory` on the pvc associated with the AWXBackup object deleted.
```
clean_backup_on_delete: true
```
Testing
----------------

View File

@@ -13,3 +13,12 @@ backup_storage_requirements: ''
# Set no_log settings on certain tasks
no_log: 'true'
# Variable to set when you want backups to be cleaned up when the CRD object is deleted
clean_backup_on_delete: false
# Variable to signal that this role is being run as a finalizer
finalizer_run: false
# Allow additional parameters to be added to the pg_dump backup command
pg_dump_suffix: ''

View File

@@ -0,0 +1,47 @@
---
- name: Patching labels to {{ kind }} kind
k8s:
state: present
definition:
apiVersion: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
metadata:
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
labels:
app.kubernetes.io/name: "{{ ansible_operator_meta.name }}"
app.kubernetes.io/part-of: "{{ ansible_operator_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: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_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,7 @@
---
- name: Cleanup backup associated with this option if enabled
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
command: >-
bash -c 'rm -rf {{ backup_dir }}'

View File

@@ -0,0 +1,19 @@
---
- name: Look up details for this backup object
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
register: this_backup
- block:
- include_tasks: init.yml
- include_tasks: delete_backup.yml
- include_tasks: cleanup.yml
vars:
backup_dir: "{{ this_backup['resources'][0]['status']['backupDirectory'] }}"
when:
- clean_backup_on_delete and backup_dir is defined

View File

@@ -1,5 +1,4 @@
---
- name: Delete any existing management pod
k8s:
name: "{{ ansible_operator_meta.name }}-db-management"
@@ -57,8 +56,8 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: '{{ deployment_name }}-backup-claim'
namespace: '{{ backup_pvc_namespace }}'
name: "{{ deployment_name }}-backup-claim"
namespace: "{{ backup_pvc_namespace }}"
ownerReferences: null
when:
- backup_pvc == '' or backup_pvc is not defined

View File

@@ -1,47 +1,8 @@
---
- name: Patching labels to {{ kind }} kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/part-of: '{{ ansible_operator_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: Run creation tasks
include_tasks: creation.yml
when: not finalizer_run
- name: Look up details for this backup object
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_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
- name: Run finalizer tasks
include_tasks: finalizer.yml
when: finalizer_run

View File

@@ -91,6 +91,7 @@
-d {{ awx_postgres_database }}
-p {{ awx_postgres_port }}
-F custom
{{ pg_dump_suffix }}
no_log: "{{ no_log }}"
- name: Write pg_dump to backup on PVC

View File

@@ -127,7 +127,7 @@ extra_volumes: ''
_image: quay.io/ansible/awx
_image_version: "{{ lookup('env', 'DEFAULT_AWX_VERSION') or 'latest' }}"
_redis_image: docker.io/redis
_redis_image_version: latest
_redis_image_version: 7
_postgres_image: postgres
_postgres_image_version: 12
_init_container_image: quay.io/centos/centos
@@ -284,3 +284,7 @@ security_context_settings: {}
# Set no_log settings on certain tasks
no_log: 'true'
# Should AWX instances be automatically upgraded when operator gets upgraded
#
auto_upgrade: true

View File

@@ -0,0 +1,88 @@
---
- name: Patching labels to AWX kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/part-of: '{{ ansible_operator_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: Load ldap bind password
include_tasks: load_ldap_password_secret.yml
when:
- ldap_password_secret != ''
- name: Load bundle certificate authority certificate
include_tasks: load_bundle_cacert_secret.yml
when:
- bundle_cacert_secret != ''
- name: Include admin password configuration tasks
include_tasks: admin_password_configuration.yml
- name: Include broadcast websocket configuration tasks
include_tasks: broadcast_websocket_configuration.yml
- name: Include set_images tasks
include_tasks: set_images.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: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_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: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_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

@@ -1,88 +1,13 @@
---
- name: Patching labels to AWX kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/part-of: '{{ ansible_operator_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: Load ldap bind password
include_tasks: load_ldap_password_secret.yml
when:
- ldap_password_secret != ''
- name: Load bundle certificate authority certificate
include_tasks: load_bundle_cacert_secret.yml
when:
- bundle_cacert_secret != ''
- name: Include admin password configuration tasks
include_tasks: admin_password_configuration.yml
- name: Include broadcast websocket configuration tasks
include_tasks: broadcast_websocket_configuration.yml
- name: Include set_images tasks
include_tasks: set_images.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:
- name: Check for presence of Deployment
k8s_info:
api_version: v1
kind: Deployment
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_meta.name }}-task"
command: >-
bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l"
changed_when: false
register: database_check
register: tower_deployment
- name: Migrate the database if the K8s resources were updated. # noqa 305
k8s_exec:
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_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
# Just execute deployment steps when auto_upgrade is true or when no deployment exists
- name: Start installation
include_tasks: install.yml
when: (tower_deployment['resources'] | length > 0 and auto_upgrade | bool ) or (tower_deployment['resources'] | length == 0)

View File

@@ -145,6 +145,7 @@ data:
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
server {
listen 8052 default_server;
listen [::]:8052 default_server;
server_name _;
# Redirect all HTTP links to the matching HTTPS page
@@ -155,6 +156,7 @@ data:
server {
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
listen 8053 ssl;
listen [::]:8053 ssl;
ssl_certificate /etc/nginx/pki/web.crt;
ssl_certificate_key /etc/nginx/pki/web.key;
@@ -165,6 +167,7 @@ data:
ssl_prefer_server_ciphers on;
{% else %}
listen 8052 default_server;
listen [::]:8052 default_server;
{% endif %}
# If you have a domain name, this is where to add it

View File

@@ -4,3 +4,8 @@ AUTH_LDAP_GLOBAL_OPTIONS = {
ldap.OPT_X_TLS_CACERTFILE: "/etc/openldap/certs/ldap-ca.crt"
{% endif %}
}
# Load LDAP BIND password from Kubernetes secret if define
{% if ldap_password_secret -%}
AUTH_LDAP_BIND_PASSWORD = "{{ ldap_bind_password }}"
{% endif %}

View File

@@ -11,6 +11,11 @@
kind: AWXBackup
role: backup
snakeCaseParameters: False
finalizer:
name: awx.ansible.com/finalizer
role: backup
vars:
finalizer_run: true
- version: v1beta1
group: awx.ansible.com