mirror of
https://github.com/ansible/awx-operator.git
synced 2026-03-27 22:03:11 +00:00
Compare commits
14 Commits
test-pytho
...
uwsgi_conf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a2b42cdde | ||
|
|
bb4f4c2eb4 | ||
|
|
97efcab2a2 | ||
|
|
c08c1027a1 | ||
|
|
3d1ecc19f4 | ||
|
|
5d0f91ec13 | ||
|
|
6ab32a42cf | ||
|
|
9718424483 | ||
|
|
d5683adaf8 | ||
|
|
1bc342258a | ||
|
|
79ab6f0b5e | ||
|
|
3822e32755 | ||
|
|
c30d4c174d | ||
|
|
8a5ec6e19c |
13
.github/workflows/label_pr.yml
vendored
13
.github/workflows/label_pr.yml
vendored
@@ -13,9 +13,17 @@ jobs:
|
|||||||
name: Label PR - Community
|
name: Label PR - Community
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
- name: Install python requests
|
|
||||||
run: pip install requests
|
- name: Create a virtual environment
|
||||||
|
run: python3 -m venv venv
|
||||||
|
|
||||||
|
- name: Activate virtual environment and install dependencies
|
||||||
|
run: |
|
||||||
|
source venv/bin/activate
|
||||||
|
pip3 install requests
|
||||||
|
|
||||||
- name: Check if user is a member of Ansible org
|
- name: Check if user is a member of Ansible org
|
||||||
uses: jannekem/run-python-script-action@v1
|
uses: jannekem/run-python-script-action@v1
|
||||||
id: check_user
|
id: check_user
|
||||||
@@ -32,6 +40,7 @@ jobs:
|
|||||||
print("User is member")
|
print("User is member")
|
||||||
else:
|
else:
|
||||||
print("User is community")
|
print("User is community")
|
||||||
|
|
||||||
- name: Add community label if not a member
|
- name: Add community label if not a member
|
||||||
if: contains(steps.check_user.outputs.stdout, 'community')
|
if: contains(steps.check_user.outputs.stdout, 'community')
|
||||||
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90
|
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Have questions about this document or anything not covered here? Please file a n
|
|||||||
- [Table of contents](#table-of-contents)
|
- [Table of contents](#table-of-contents)
|
||||||
- [Things to know prior to submitting code](#things-to-know-prior-to-submitting-code)
|
- [Things to know prior to submitting code](#things-to-know-prior-to-submitting-code)
|
||||||
- [Submmiting your work](#submmiting-your-work)
|
- [Submmiting your work](#submmiting-your-work)
|
||||||
|
- [Development](#development)
|
||||||
- [Testing](#testing)
|
- [Testing](#testing)
|
||||||
- [Testing in Kind](#testing-in-kind)
|
- [Testing in Kind](#testing-in-kind)
|
||||||
- [Testing in Minikube](#testing-in-minikube)
|
- [Testing in Minikube](#testing-in-minikube)
|
||||||
@@ -42,7 +43,8 @@ Have questions about this document or anything not covered here? Please file a n
|
|||||||
|
|
||||||
**Note**: If you have multiple commits, make sure to `squash` your commits into a single commit which will facilitate our release process.
|
**Note**: If you have multiple commits, make sure to `squash` your commits into a single commit which will facilitate our release process.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
The development environment consists of running an [`up.sh`](./up.sh) and a [`down.sh`](./down.sh) script, which applies or deletes yaml on the Openshift or K8s cluster you are connected to. See the [development.md](docs/development.md) for information on how to deploy and test changes from your branch.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ Please visit [our contributing guidelines](https://github.com/ansible/awx-operat
|
|||||||
|
|
||||||
For docs changes, create PRs on the appropriate files in the `/docs` folder.
|
For docs changes, create PRs on the appropriate files in the `/docs` folder.
|
||||||
|
|
||||||
|
The development environment consists of running an [`up.sh`](https://github.com/ansible/awx-operator/blob/devel/up.sh) and a [`down.sh`](https://github.com/ansible/awx-operator/blob/devel/down.sh) script, which applies or deletes yaml on the Openshift or K8s cluster you are connected to. See the [development.md](https://github.com/ansible/awx-operator/blob/devel/docs/development.md) for information on how to deploy and test changes from your branch.
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
This operator was originally built in 2019 by [Jeff Geerling](https://www.jeffgeerling.com) and is now maintained by the Ansible Team
|
This operator was originally built in 2019 by [Jeff Geerling](https://www.jeffgeerling.com) and is now maintained by the Ansible Team
|
||||||
|
|||||||
@@ -1730,6 +1730,9 @@ spec:
|
|||||||
uwsgi_listen_queue_size:
|
uwsgi_listen_queue_size:
|
||||||
description: Set the socket listen queue size for uwsgi
|
description: Set the socket listen queue size for uwsgi
|
||||||
type: integer
|
type: integer
|
||||||
|
uwsgi_timeout:
|
||||||
|
description: Set the timeout for requests served by uwsgi. (note, graceful exit signal sent 2 seconds prior to timeout)
|
||||||
|
type: integer
|
||||||
nginx_worker_processes:
|
nginx_worker_processes:
|
||||||
description: Set the number of workers for nginx
|
description: Set the number of workers for nginx
|
||||||
type: integer
|
type: integer
|
||||||
@@ -1965,6 +1968,9 @@ spec:
|
|||||||
description: Disable web container's nginx ipv6 listener
|
description: Disable web container's nginx ipv6 listener
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
idle_deployment:
|
||||||
|
description: Scale down deployments to put AWX into an idle state
|
||||||
|
type: boolean
|
||||||
metrics_utility_enabled:
|
metrics_utility_enabled:
|
||||||
description: Enable metrics utility
|
description: Enable metrics utility
|
||||||
type: boolean
|
type: boolean
|
||||||
@@ -2009,8 +2015,12 @@ spec:
|
|||||||
description: Enable metrics utility shipping to Red Hat Hybrid Cloud Console
|
description: Enable metrics utility shipping to Red Hat Hybrid Cloud Console
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
public_base_url:
|
||||||
|
description: Public base URL
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
properties:
|
properties:
|
||||||
URL:
|
URL:
|
||||||
description: URL to access the deployed instance
|
description: URL to access the deployed instance
|
||||||
@@ -2042,6 +2052,9 @@ spec:
|
|||||||
image:
|
image:
|
||||||
description: URL of the image used for the deployed instance
|
description: URL of the image used for the deployed instance
|
||||||
type: string
|
type: string
|
||||||
|
upgradedFrom:
|
||||||
|
description: Last gated version
|
||||||
|
type: string
|
||||||
conditions:
|
conditions:
|
||||||
description: The resulting conditions when a Service Telemetry is instantiated
|
description: The resulting conditions when a Service Telemetry is instantiated
|
||||||
items:
|
items:
|
||||||
@@ -2056,5 +2069,6 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ spec:
|
|||||||
memory: "32Mi"
|
memory: "32Mi"
|
||||||
cpu: "50m"
|
cpu: "50m"
|
||||||
limits:
|
limits:
|
||||||
memory: "960Mi"
|
memory: "4000Mi"
|
||||||
cpu: "1500m"
|
cpu: "2000m"
|
||||||
serviceAccountName: controller-manager
|
serviceAccountName: controller-manager
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
- name: redhat-operators-pull-secret
|
- name: redhat-operators-pull-secret
|
||||||
|
|||||||
@@ -173,6 +173,12 @@ spec:
|
|||||||
path: db_management_pod_node_selector
|
path: db_management_pod_node_selector
|
||||||
x-descriptors:
|
x-descriptors:
|
||||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||||
|
- displayName: Public Base URL
|
||||||
|
path: public_base_url
|
||||||
|
x-descriptors:
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:text
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||||
statusDescriptors:
|
statusDescriptors:
|
||||||
- description: Persistent volume claim name used during backup
|
- description: Persistent volume claim name used during backup
|
||||||
displayName: Backup Claim
|
displayName: Backup Claim
|
||||||
@@ -548,6 +554,12 @@ spec:
|
|||||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||||
- urn:alm:descriptor:com.tectonic.ui:number
|
- urn:alm:descriptor:com.tectonic.ui:number
|
||||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||||
|
- displayName: Uwsgi Timeout
|
||||||
|
path: uwsgi_timeout
|
||||||
|
x-descriptors:
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:number
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||||
- displayName: Uwsgi Processes
|
- displayName: Uwsgi Processes
|
||||||
path: uwsgi_processes
|
path: uwsgi_processes
|
||||||
x-descriptors:
|
x-descriptors:
|
||||||
@@ -1149,6 +1161,13 @@ spec:
|
|||||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:metrics_utility_enabled:true
|
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:metrics_utility_enabled:true
|
||||||
|
- description: Scale down deployments to put AWX into an idle state
|
||||||
|
displayName: Idle AWX
|
||||||
|
path: idle_deployment
|
||||||
|
x-descriptors:
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||||
|
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||||
statusDescriptors:
|
statusDescriptors:
|
||||||
- description: Route to access the instance deployed
|
- description: Route to access the instance deployed
|
||||||
displayName: URL
|
displayName: URL
|
||||||
|
|||||||
24
dev/awx-cr/awx-cr-settings.yml
Normal file
24
dev/awx-cr/awx-cr-settings.yml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
apiVersion: awx.ansible.com/v1beta1
|
||||||
|
kind: AWX
|
||||||
|
metadata:
|
||||||
|
name: awx
|
||||||
|
spec:
|
||||||
|
service_type: clusterip
|
||||||
|
ingress_type: route
|
||||||
|
no_log: false
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
admin_password_secret: custom-admin-password
|
||||||
|
postgres_configuration_secret: custom-pg-configuration
|
||||||
|
secret_key_secret: custom-secret-key
|
||||||
|
|
||||||
|
# Resource Requirements
|
||||||
|
postgres_storage_requirements:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
|
||||||
|
# Extra Settings
|
||||||
|
extra_settings:
|
||||||
|
- setting: MAX_PAGE_SIZE
|
||||||
|
value: "500"
|
||||||
13
dev/awx-cr/awx-k8s-ingress.yml
Normal file
13
dev/awx-cr/awx-k8s-ingress.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
apiVersion: awx.ansible.com/v1beta1
|
||||||
|
kind: AWX
|
||||||
|
metadata:
|
||||||
|
name: awx
|
||||||
|
spec:
|
||||||
|
service_type: nodeport
|
||||||
|
ingress_type: ingress
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
admin_password_secret: custom-admin-password
|
||||||
|
postgres_configuration_secret: custom-pg-configuration
|
||||||
|
secret_key_secret: custom-secret-key
|
||||||
13
dev/awx-cr/awx-openshift-cr.yml
Normal file
13
dev/awx-cr/awx-openshift-cr.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
apiVersion: awx.ansible.com/v1beta1
|
||||||
|
kind: AWX
|
||||||
|
metadata:
|
||||||
|
name: awx
|
||||||
|
spec:
|
||||||
|
service_type: clusterip
|
||||||
|
ingress_type: Route
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
admin_password_secret: custom-admin-password
|
||||||
|
postgres_configuration_secret: custom-pg-configuration
|
||||||
|
secret_key_secret: custom-secret-key
|
||||||
7
dev/secrets/admin-password-secret.yml
Normal file
7
dev/secrets/admin-password-secret.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: custom-admin-password
|
||||||
|
stringData:
|
||||||
|
password: 'password'
|
||||||
7
dev/secrets/custom-secret-key.yml
Normal file
7
dev/secrets/custom-secret-key.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: custom-secret-key
|
||||||
|
stringData:
|
||||||
|
secret_key: 'awxsecret'
|
||||||
12
dev/secrets/external-pg-secret.yml
Normal file
12
dev/secrets/external-pg-secret.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: external-pg-secret
|
||||||
|
stringData:
|
||||||
|
database: 'awx'
|
||||||
|
host: 'awx-postgres'
|
||||||
|
password: 'test'
|
||||||
|
port: '5432'
|
||||||
|
type: 'managed'
|
||||||
|
username: 'awx'
|
||||||
58
docs/development.md
Normal file
58
docs/development.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Development Guide
|
||||||
|
|
||||||
|
There are development scripts and yaml exaples in the [`dev/`](../dev) directory that, along with the up.sh and down.sh scripts in the root of the repo, can be used to build, deploy and test changes made to the awx-operator.
|
||||||
|
|
||||||
|
|
||||||
|
## Build and Deploy
|
||||||
|
|
||||||
|
|
||||||
|
If you clone the repo, and make sure you are logged in at the CLI with oc and your cluster, you can run:
|
||||||
|
|
||||||
|
```
|
||||||
|
export QUAY_USER=username
|
||||||
|
export NAMESPACE=awx
|
||||||
|
export TAG=test
|
||||||
|
./up.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
You can add those variables to your .bashrc file so that you can just run `./up.sh` in the future.
|
||||||
|
|
||||||
|
> Note: the first time you run this, it will create quay.io repos on your fork. You will need to either make those public, or create a global pull secret on your Openshift cluster.
|
||||||
|
|
||||||
|
To get the URL, if on **Openshift**, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ oc get route
|
||||||
|
```
|
||||||
|
|
||||||
|
On **k8s with ingress**, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl get ing
|
||||||
|
```
|
||||||
|
|
||||||
|
On **k8s with nodeport**, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl get svc
|
||||||
|
```
|
||||||
|
|
||||||
|
The URL is then `http://<Node-IP>:<NodePort>`
|
||||||
|
|
||||||
|
> Note: NodePort will only work if you expose that port on your underlying k8s node, or are accessing it from localhost.
|
||||||
|
|
||||||
|
By default, the usename and password will be admin and password if using the `up.sh` script because it pre-creates a custom admin password k8s secret and specifies it on the AWX custom resource spec. Without that, a password would have been generated and stored in a k8s secret named <deployment-name>-admin-password.
|
||||||
|
|
||||||
|
## Clean up
|
||||||
|
|
||||||
|
|
||||||
|
Same thing for cleanup, just run ./down.sh and it will clean up your namespace on that cluster
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
./down.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running CI tests locally
|
||||||
|
|
||||||
|
More tests coming soon...
|
||||||
@@ -70,15 +70,16 @@ spec:
|
|||||||
|
|
||||||
## Custom UWSGI Configuration
|
## Custom UWSGI Configuration
|
||||||
|
|
||||||
We allow the customization of two UWSGI parameters:
|
We allow the customization of three UWSGI parameters:
|
||||||
|
|
||||||
* [processes](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#processes) with `uwsgi_processes` (default 5)
|
* [processes](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#processes) with `uwsgi_processes` (default 5)
|
||||||
* [listen](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#listen) with `uwsgi_listen_queue_size` (default 128)
|
* [listen](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#listen) with `uwsgi_listen_queue_size` (default 128)
|
||||||
|
* [harakiri](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#harakiri) with `uwsgi_timeout` (default 30)
|
||||||
|
|
||||||
**Note:** Increasing the listen queue beyond 128 requires that the sysctl setting net.core.somaxconn be set to an equal value or higher.
|
**Note:** Increasing the listen queue beyond 128 requires that the sysctl setting net.core.somaxconn be set to an equal value or higher.
|
||||||
The operator will set the appropriate securityContext sysctl value for you, but it is a required that this sysctl be added to an allowlist on the kubelet level. [See kubernetes docs about allowing this sysctl setting](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#enabling-unsafe-sysctls).
|
The operator will set the appropriate securityContext sysctl value for you, but it is a required that this sysctl be added to an allowlist on the kubelet level. [See kubernetes docs about allowing this sysctl setting](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#enabling-unsafe-sysctls).
|
||||||
|
|
||||||
These vars relate to the vertical and horizontal scalibility of the web service.
|
The `processes` and `listen` vars relate to the vertical and horizontal scalibility of the web service.
|
||||||
|
|
||||||
Increasing the number of processes allows more requests to be actively handled
|
Increasing the number of processes allows more requests to be actively handled
|
||||||
per web pod, but will consume more CPU and Memory and the resource requests
|
per web pod, but will consume more CPU and Memory and the resource requests
|
||||||
@@ -89,6 +90,12 @@ requests (more than 128) tend to come in a short period of time, but can all be
|
|||||||
handled before any other time outs may apply. Also see related nginx
|
handled before any other time outs may apply. Also see related nginx
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
|
The `uwsgi_timeout` variable determines after how many seconds a request will
|
||||||
|
be forecibly killed by uwsgi. A "graceful" timeout signal is sent to the worker
|
||||||
|
2 seconds prior to attempt to get a traceback of what may be causing the
|
||||||
|
request to hang.
|
||||||
|
|
||||||
|
|
||||||
## Custom Nginx Configuration
|
## Custom Nginx Configuration
|
||||||
|
|
||||||
Using the [extra_volumes feature](#custom-volume-and-volume-mount-options), it is possible to extend the nginx.conf.
|
Using the [extra_volumes feature](#custom-volume-and-volume-mount-options), it is possible to extend the nginx.conf.
|
||||||
|
|||||||
36
down.sh
Executable file
36
down.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# AWX Operator down.sh
|
||||||
|
# Purpose:
|
||||||
|
# Cleanup and delete the namespace you deployed in
|
||||||
|
|
||||||
|
# -- Usage
|
||||||
|
# NAMESPACE=awx ./down.sh
|
||||||
|
|
||||||
|
# -- Variables
|
||||||
|
TAG=${TAG:-dev}
|
||||||
|
AWX_CR=${AWX_CR:-awx}
|
||||||
|
CLEAN_DB=${CLEAN_DB:-false}
|
||||||
|
|
||||||
|
|
||||||
|
# -- Check for required variables
|
||||||
|
# Set the following environment variables
|
||||||
|
# export NAMESPACE=awx
|
||||||
|
|
||||||
|
if [ -z "$NAMESPACE" ]; then
|
||||||
|
echo "Error: NAMESPACE env variable is not set. Run the following with your namespace:"
|
||||||
|
echo " export NAMESPACE=developer"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -- Delete Backups
|
||||||
|
kubectl delete awxbackup --all
|
||||||
|
|
||||||
|
# -- Delete Restores
|
||||||
|
kubectl delete awxrestore --all
|
||||||
|
|
||||||
|
# Deploy Operator
|
||||||
|
make undeploy NAMESPACE=$NAMESPACE
|
||||||
|
|
||||||
|
# Remove PVCs
|
||||||
|
kubectl delete pvc postgres-15-$AWX_CR-postgres-15-0
|
||||||
|
|
||||||
@@ -4,4 +4,6 @@ collections:
|
|||||||
- name: kubernetes.core
|
- name: kubernetes.core
|
||||||
- name: operator_sdk.util
|
- name: operator_sdk.util
|
||||||
- name: community.docker
|
- name: community.docker
|
||||||
- name: awx.awx
|
- name: https://github.com/ansible/awx.git#/awx_collection/
|
||||||
|
type: git
|
||||||
|
version: devel
|
||||||
|
|||||||
@@ -497,6 +497,7 @@ uwsgi_processes: 5
|
|||||||
# Also see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#enabling-unsafe-sysctls for how
|
# Also see https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#enabling-unsafe-sysctls for how
|
||||||
# to allow setting this sysctl, which requires kubelet configuration to add to allowlist
|
# to allow setting this sysctl, which requires kubelet configuration to add to allowlist
|
||||||
uwsgi_listen_queue_size: 128
|
uwsgi_listen_queue_size: 128
|
||||||
|
uwsgi_timeout: 30
|
||||||
|
|
||||||
# NGINX default values
|
# NGINX default values
|
||||||
nginx_worker_processes: 1
|
nginx_worker_processes: 1
|
||||||
@@ -505,3 +506,6 @@ nginx_worker_cpu_affinity: 'auto'
|
|||||||
nginx_listen_queue_size: "{{ uwsgi_listen_queue_size }}"
|
nginx_listen_queue_size: "{{ uwsgi_listen_queue_size }}"
|
||||||
|
|
||||||
extra_settings_files: {}
|
extra_settings_files: {}
|
||||||
|
|
||||||
|
# idle_deployment - Scale down deployments to put AWX into an idle state
|
||||||
|
idle_deployment: false
|
||||||
|
|||||||
35
roles/installer/tasks/check_existing.yml
Normal file
35
roles/installer/tasks/check_existing.yml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Check for presence of Deployment
|
||||||
|
kubernetes.core.k8s_info:
|
||||||
|
api_version: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
label_selectors:
|
||||||
|
- 'app.kubernetes.io/part-of={{ ansible_operator_meta.name }}'
|
||||||
|
- 'app.kubernetes.io/managed-by={{ deployment_type }}-operator'
|
||||||
|
- 'app.kubernetes.io/component={{ deployment_type }}'
|
||||||
|
register: _deployments
|
||||||
|
|
||||||
|
- name: Set previous_version if deployment exists
|
||||||
|
when: _deployments.resources | length > 0
|
||||||
|
block:
|
||||||
|
- name: Check for existing deployment
|
||||||
|
kubernetes.core.k8s_info:
|
||||||
|
api_version: "{{ api_version }}"
|
||||||
|
kind: "{{ kind }}"
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
name: "{{ ansible_operator_meta.name }}"
|
||||||
|
register: existing_cr
|
||||||
|
|
||||||
|
- name: Set previous_version version based on AWX CR version status
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
previous_version: "{{ existing_cr.resources[0].status.version }}"
|
||||||
|
when: existing_cr['resources'] | length
|
||||||
|
|
||||||
|
- name: If previous_version is less than or equal to gating_version, set upgraded_from to previous_version
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
upgraded_from: "{{ previous_version }}"
|
||||||
|
when:
|
||||||
|
- previous_version is defined
|
||||||
|
- previous_version is version_compare(gating_version, '<')
|
||||||
167
roles/installer/tasks/database.yml
Normal file
167
roles/installer/tasks/database.yml
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
---
|
||||||
|
- name: Get database configuration
|
||||||
|
include_tasks: database_configuration.yml
|
||||||
|
|
||||||
|
# It is possible that N-2 postgres pods may still be present in the namespace from previous upgrades.
|
||||||
|
# So we have to take that into account and preferentially set the most recent one.
|
||||||
|
- name: Get the old postgres pod (N-1)
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
field_selectors:
|
||||||
|
- status.phase=Running
|
||||||
|
register: _running_pods
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Filter pods by name
|
||||||
|
set_fact:
|
||||||
|
filtered_old_postgres_pods: "{{ _running_pods.resources |
|
||||||
|
selectattr('metadata.name', 'match', ansible_operator_meta.name + '-postgres.*-0') |
|
||||||
|
rejectattr('metadata.name', 'search', '-' + supported_pg_version | string + '-0') |
|
||||||
|
list }}"
|
||||||
|
|
||||||
|
# Sort pods by name in reverse order (most recent PG version first) and set
|
||||||
|
- name: Set info for previous postgres pod
|
||||||
|
set_fact:
|
||||||
|
sorted_old_postgres_pods: "{{ filtered_old_postgres_pods |
|
||||||
|
sort(attribute='metadata.name') |
|
||||||
|
reverse | list }}"
|
||||||
|
when: filtered_old_postgres_pods | length
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set info for previous postgres pod
|
||||||
|
set_fact:
|
||||||
|
old_postgres_pod: "{{ sorted_old_postgres_pods | first }}"
|
||||||
|
when: filtered_old_postgres_pods | length
|
||||||
|
when: _running_pods.resources | length
|
||||||
|
|
||||||
|
- name: Look up details for this deployment
|
||||||
|
k8s_info:
|
||||||
|
api_version: "{{ api_version }}"
|
||||||
|
kind: "{{ kind }}"
|
||||||
|
name: "{{ ansible_operator_meta.name }}"
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
register: this_awx
|
||||||
|
|
||||||
|
# If this deployment has been upgraded before or if upgrade has already been started, set this var
|
||||||
|
- name: Set previous PG version var
|
||||||
|
set_fact:
|
||||||
|
_previous_upgraded_pg_version: "{{ this_awx['resources'][0]['status']['upgradedPostgresVersion'] | default(false) }}"
|
||||||
|
when:
|
||||||
|
- this_awx['resources'][0] is defined
|
||||||
|
- "'upgradedPostgresVersion' in this_awx['resources'][0]['status']"
|
||||||
|
|
||||||
|
- name: Check if postgres pod is running an older version
|
||||||
|
block:
|
||||||
|
- name: Get old PostgreSQL version
|
||||||
|
k8s_exec:
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
pod: "{{ old_postgres_pod['metadata']['name'] }}"
|
||||||
|
command: |
|
||||||
|
bash -c """
|
||||||
|
if [ -f "{{ _postgres_data_path }}/PG_VERSION" ]; then
|
||||||
|
cat "{{ _postgres_data_path }}/PG_VERSION"
|
||||||
|
elif [ -f '/var/lib/postgresql/data/pgdata/PG_VERSION' ]; then
|
||||||
|
cat '/var/lib/postgresql/data/pgdata/PG_VERSION'
|
||||||
|
fi
|
||||||
|
"""
|
||||||
|
register: _old_pg_version
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: "--- Upgrading from {{ old_postgres_pod['metadata']['name'] | default('NONE')}} Pod ---"
|
||||||
|
|
||||||
|
- name: Upgrade data dir from old Postgres to {{ supported_pg_version }} if applicable
|
||||||
|
include_tasks: upgrade_postgres.yml
|
||||||
|
when:
|
||||||
|
- (_old_pg_version.stdout | default(0) | int ) < supported_pg_version
|
||||||
|
when:
|
||||||
|
- managed_database
|
||||||
|
- (_previous_upgraded_pg_version | default(false)) | ternary(_previous_upgraded_pg_version | int < supported_pg_version, true)
|
||||||
|
- old_postgres_pod | length # If empty, then old pg pod has been removed and we can assume the upgrade is complete
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Create Database if no database is specified
|
||||||
|
k8s:
|
||||||
|
apply: true
|
||||||
|
definition: "{{ lookup('template', 'statefulsets/postgres.yaml.j2') }}"
|
||||||
|
register: create_statefulset_result
|
||||||
|
|
||||||
|
- name: Scale down Deployment for migration
|
||||||
|
include_tasks: scale_down_deployment.yml
|
||||||
|
when: create_statefulset_result.changed
|
||||||
|
|
||||||
|
rescue:
|
||||||
|
- name: Scale down Deployment for migration
|
||||||
|
include_tasks: scale_down_deployment.yml
|
||||||
|
|
||||||
|
- name: Scale down PostgreSQL statefulset for migration
|
||||||
|
kubernetes.core.k8s_scale:
|
||||||
|
api_version: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
name: "{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}"
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
replicas: 0
|
||||||
|
wait: yes
|
||||||
|
|
||||||
|
- name: Remove PostgreSQL statefulset for upgrade
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
api_version: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
name: "{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}"
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
wait: yes
|
||||||
|
when: create_statefulset_result.error == 422
|
||||||
|
|
||||||
|
- name: Recreate PostgreSQL statefulset with updated values
|
||||||
|
k8s:
|
||||||
|
apply: true
|
||||||
|
definition: "{{ lookup('template', 'statefulsets/postgres.yaml.j2') }}"
|
||||||
|
when: managed_database
|
||||||
|
|
||||||
|
- name: Set Default label selector for custom resource generated postgres
|
||||||
|
set_fact:
|
||||||
|
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}"
|
||||||
|
when: postgres_label_selector is not defined
|
||||||
|
|
||||||
|
- name: Get the postgres pod information
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
label_selectors:
|
||||||
|
- "{{ postgres_label_selector }}"
|
||||||
|
field_selectors:
|
||||||
|
- status.phase=Running
|
||||||
|
register: postgres_pod
|
||||||
|
|
||||||
|
- name: Wait for Database to initialize if managed DB
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- "{{ postgres_label_selector }}"
|
||||||
|
field_selectors:
|
||||||
|
- status.phase=Running
|
||||||
|
register: postgres_pod
|
||||||
|
until:
|
||||||
|
- "postgres_pod['resources'] | length"
|
||||||
|
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
|
||||||
|
- "postgres_pod['resources'][0]['status']['containerStatuses'][0]['ready'] == true"
|
||||||
|
delay: 5
|
||||||
|
retries: 60
|
||||||
|
when: managed_database
|
||||||
|
|
||||||
|
- name: Look up details for this deployment
|
||||||
|
k8s_info:
|
||||||
|
api_version: "{{ api_version }}"
|
||||||
|
kind: "{{ kind }}"
|
||||||
|
name: "{{ ansible_operator_meta.name }}"
|
||||||
|
namespace: "{{ ansible_operator_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
|
||||||
@@ -51,6 +51,14 @@
|
|||||||
set_fact:
|
set_fact:
|
||||||
_default_postgres_image: "{{ _postgres_image }}:{{_postgres_image_version }}"
|
_default_postgres_image: "{{ _postgres_image }}:{{_postgres_image_version }}"
|
||||||
|
|
||||||
|
- name: Fail if PostgreSQL secret is specified, but not found
|
||||||
|
fail:
|
||||||
|
msg: "PostgreSQL configuration {{ postgres_configuration_secret }} not found in namespace {{ ansible_operator_meta.namespace }}"
|
||||||
|
when:
|
||||||
|
- postgres_configuration_secret | length
|
||||||
|
- _custom_pg_config_resources is defined
|
||||||
|
- _custom_pg_config_resources['resources'] | length == 0
|
||||||
|
|
||||||
- name: Set PostgreSQL configuration
|
- name: Set PostgreSQL configuration
|
||||||
set_fact:
|
set_fact:
|
||||||
_pg_config: '{{ _custom_pg_config_resources["resources"] | default([]) | length | ternary(_custom_pg_config_resources, _default_pg_config_resources) }}'
|
_pg_config: '{{ _custom_pg_config_resources["resources"] | default([]) | length | ternary(_custom_pg_config_resources, _default_pg_config_resources) }}'
|
||||||
@@ -106,167 +114,3 @@
|
|||||||
- name: Set database as managed
|
- name: Set database as managed
|
||||||
set_fact:
|
set_fact:
|
||||||
managed_database: "{{ pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed' }}"
|
managed_database: "{{ pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed' }}"
|
||||||
|
|
||||||
# It is possible that N-2 postgres pods may still be present in the namespace from previous upgrades.
|
|
||||||
# So we have to take that into account and preferentially set the most recent one.
|
|
||||||
- name: Get the old postgres pod (N-1)
|
|
||||||
k8s_info:
|
|
||||||
kind: Pod
|
|
||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
|
||||||
field_selectors:
|
|
||||||
- status.phase=Running
|
|
||||||
register: _running_pods
|
|
||||||
|
|
||||||
- block:
|
|
||||||
- name: Filter pods by name
|
|
||||||
set_fact:
|
|
||||||
filtered_old_postgres_pods: "{{ _running_pods.resources |
|
|
||||||
selectattr('metadata.name', 'match', ansible_operator_meta.name + '-postgres.*-0') |
|
|
||||||
rejectattr('metadata.name', 'search', '-' + supported_pg_version | string + '-0') |
|
|
||||||
list }}"
|
|
||||||
|
|
||||||
# Sort pods by name in reverse order (most recent PG version first) and set
|
|
||||||
- name: Set info for previous postgres pod
|
|
||||||
set_fact:
|
|
||||||
sorted_old_postgres_pods: "{{ filtered_old_postgres_pods |
|
|
||||||
sort(attribute='metadata.name') |
|
|
||||||
reverse | list }}"
|
|
||||||
when: filtered_old_postgres_pods | length
|
|
||||||
|
|
||||||
|
|
||||||
- name: Set info for previous postgres pod
|
|
||||||
set_fact:
|
|
||||||
old_postgres_pod: "{{ sorted_old_postgres_pods | first }}"
|
|
||||||
when: filtered_old_postgres_pods | length
|
|
||||||
when: _running_pods.resources | length
|
|
||||||
|
|
||||||
- name: Look up details for this deployment
|
|
||||||
k8s_info:
|
|
||||||
api_version: "{{ api_version }}"
|
|
||||||
kind: "{{ kind }}"
|
|
||||||
name: "{{ ansible_operator_meta.name }}"
|
|
||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
|
||||||
register: this_awx
|
|
||||||
|
|
||||||
# If this deployment has been upgraded before or if upgrade has already been started, set this var
|
|
||||||
- name: Set previous PG version var
|
|
||||||
set_fact:
|
|
||||||
_previous_upgraded_pg_version: "{{ this_awx['resources'][0]['status']['upgradedPostgresVersion'] | default(false) }}"
|
|
||||||
when:
|
|
||||||
- this_awx['resources'][0] is defined
|
|
||||||
- "'upgradedPostgresVersion' in this_awx['resources'][0]['status']"
|
|
||||||
|
|
||||||
- name: Check if postgres pod is running an older version
|
|
||||||
block:
|
|
||||||
- name: Get old PostgreSQL version
|
|
||||||
k8s_exec:
|
|
||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
|
||||||
pod: "{{ old_postgres_pod['metadata']['name'] }}"
|
|
||||||
command: |
|
|
||||||
bash -c """
|
|
||||||
if [ -f "{{ _postgres_data_path }}/PG_VERSION" ]; then
|
|
||||||
cat "{{ _postgres_data_path }}/PG_VERSION"
|
|
||||||
elif [ -f '/var/lib/postgresql/data/pgdata/PG_VERSION' ]; then
|
|
||||||
cat '/var/lib/postgresql/data/pgdata/PG_VERSION'
|
|
||||||
fi
|
|
||||||
"""
|
|
||||||
register: _old_pg_version
|
|
||||||
|
|
||||||
- debug:
|
|
||||||
msg: "--- Upgrading from {{ old_postgres_pod['metadata']['name'] | default('NONE')}} Pod ---"
|
|
||||||
|
|
||||||
- name: Upgrade data dir from old Postgres to {{ supported_pg_version }} if applicable
|
|
||||||
include_tasks: upgrade_postgres.yml
|
|
||||||
when:
|
|
||||||
- (_old_pg_version.stdout | default(0) | int ) < supported_pg_version
|
|
||||||
when:
|
|
||||||
- managed_database
|
|
||||||
- (_previous_upgraded_pg_version | default(false)) | ternary(_previous_upgraded_pg_version | int < supported_pg_version, true)
|
|
||||||
- old_postgres_pod | length # If empty, then old pg pod has been removed and we can assume the upgrade is complete
|
|
||||||
|
|
||||||
- block:
|
|
||||||
- name: Create Database if no database is specified
|
|
||||||
k8s:
|
|
||||||
apply: true
|
|
||||||
definition: "{{ lookup('template', 'statefulsets/postgres.yaml.j2') }}"
|
|
||||||
register: create_statefulset_result
|
|
||||||
|
|
||||||
- name: Scale down Deployment for migration
|
|
||||||
include_tasks: scale_down_deployment.yml
|
|
||||||
when: create_statefulset_result.changed
|
|
||||||
|
|
||||||
rescue:
|
|
||||||
- name: Scale down Deployment for migration
|
|
||||||
include_tasks: scale_down_deployment.yml
|
|
||||||
|
|
||||||
- name: Scale down PostgreSQL statefulset for migration
|
|
||||||
kubernetes.core.k8s_scale:
|
|
||||||
api_version: apps/v1
|
|
||||||
kind: StatefulSet
|
|
||||||
name: "{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}"
|
|
||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
|
||||||
replicas: 0
|
|
||||||
wait: yes
|
|
||||||
|
|
||||||
- name: Remove PostgreSQL statefulset for upgrade
|
|
||||||
k8s:
|
|
||||||
state: absent
|
|
||||||
api_version: apps/v1
|
|
||||||
kind: StatefulSet
|
|
||||||
name: "{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}"
|
|
||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
|
||||||
wait: yes
|
|
||||||
when: create_statefulset_result.error == 422
|
|
||||||
|
|
||||||
- name: Recreate PostgreSQL statefulset with updated values
|
|
||||||
k8s:
|
|
||||||
apply: true
|
|
||||||
definition: "{{ lookup('template', 'statefulsets/postgres.yaml.j2') }}"
|
|
||||||
when: managed_database
|
|
||||||
|
|
||||||
- name: Set Default label selector for custom resource generated postgres
|
|
||||||
set_fact:
|
|
||||||
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}"
|
|
||||||
when: postgres_label_selector is not defined
|
|
||||||
|
|
||||||
- name: Get the postgres pod information
|
|
||||||
k8s_info:
|
|
||||||
kind: Pod
|
|
||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
|
||||||
label_selectors:
|
|
||||||
- "{{ postgres_label_selector }}"
|
|
||||||
field_selectors:
|
|
||||||
- status.phase=Running
|
|
||||||
register: postgres_pod
|
|
||||||
|
|
||||||
- name: Wait for Database to initialize if managed DB
|
|
||||||
k8s_info:
|
|
||||||
kind: Pod
|
|
||||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
|
||||||
label_selectors:
|
|
||||||
- "{{ postgres_label_selector }}"
|
|
||||||
field_selectors:
|
|
||||||
- status.phase=Running
|
|
||||||
register: postgres_pod
|
|
||||||
until:
|
|
||||||
- "postgres_pod['resources'] | length"
|
|
||||||
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
|
|
||||||
- "postgres_pod['resources'][0]['status']['containerStatuses'][0]['ready'] == true"
|
|
||||||
delay: 5
|
|
||||||
retries: 60
|
|
||||||
when: managed_database
|
|
||||||
|
|
||||||
- name: Look up details for this deployment
|
|
||||||
k8s_info:
|
|
||||||
api_version: "{{ api_version }}"
|
|
||||||
kind: "{{ kind }}"
|
|
||||||
name: "{{ ansible_operator_meta.name }}"
|
|
||||||
namespace: "{{ ansible_operator_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
|
|
||||||
|
|||||||
34
roles/installer/tasks/idle_deployment.yml
Normal file
34
roles/installer/tasks/idle_deployment.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
- name: Scale down AWX Deployments
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
definition:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: "{{ item }}"
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
spec:
|
||||||
|
replicas: 0
|
||||||
|
loop:
|
||||||
|
- '{{ ansible_operator_meta.name }}-task'
|
||||||
|
- '{{ ansible_operator_meta.name }}-web'
|
||||||
|
|
||||||
|
- name: Get database configuration
|
||||||
|
include_tasks: database_configuration.yml
|
||||||
|
|
||||||
|
- name: Scale down PostgreSQL Statefulset
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
definition:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: "{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}"
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
spec:
|
||||||
|
replicas: 0
|
||||||
|
when: managed_database
|
||||||
|
|
||||||
|
- name: End Playbook
|
||||||
|
ansible.builtin.meta: end_play
|
||||||
@@ -18,13 +18,11 @@
|
|||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
pod: "{{ awx_web_pod_name }}"
|
pod: "{{ awx_web_pod_name }}"
|
||||||
container: "{{ ansible_operator_meta.name }}-web"
|
container: "{{ ansible_operator_meta.name }}-web"
|
||||||
command: awx-manage createsuperuser --username={{ admin_user | quote }} --email={{ admin_email | quote }} --noinput
|
command: bash -c "ANSIBLE_REVERSE_RESOURCE_SYNC=false awx-manage createsuperuser --username={{ admin_user | quote }} --email={{ admin_email | quote }} --noinput"
|
||||||
register: result
|
register: result
|
||||||
changed_when: "'That username is already taken' not in result.stderr"
|
changed_when: "'That username is already taken' not in result.stderr"
|
||||||
failed_when: "'That username is already taken' not in result.stderr and 'Superuser created successfully' not in result.stdout"
|
failed_when: "'That username is already taken' not in result.stderr and 'Superuser created successfully' not in result.stdout"
|
||||||
no_log: "{{ no_log }}"
|
no_log: "{{ no_log }}"
|
||||||
environment:
|
|
||||||
ANSIBLE_REVERSE_RESOURCE_SYNC: "false"
|
|
||||||
when: users_result.return_code > 0
|
when: users_result.return_code > 0
|
||||||
|
|
||||||
- name: Update Django super user password
|
- name: Update Django super user password
|
||||||
@@ -116,9 +114,7 @@
|
|||||||
pod: "{{ awx_web_pod_name }}"
|
pod: "{{ awx_web_pod_name }}"
|
||||||
container: "{{ ansible_operator_meta.name }}-web"
|
container: "{{ ansible_operator_meta.name }}-web"
|
||||||
command: >-
|
command: >-
|
||||||
bash -c "awx-manage create_preload_data"
|
bash -c "ANSIBLE_REVERSE_RESOURCE_SYNC=false awx-manage create_preload_data"
|
||||||
register: cdo
|
register: cdo
|
||||||
changed_when: "'added' in cdo.stdout"
|
changed_when: "'added' in cdo.stdout"
|
||||||
environment:
|
|
||||||
ANSIBLE_REVERSE_RESOURCE_SYNC: "false"
|
|
||||||
when: create_preload_data | bool
|
when: create_preload_data | bool
|
||||||
|
|||||||
@@ -44,6 +44,12 @@
|
|||||||
- name: Include secret key configuration tasks
|
- name: Include secret key configuration tasks
|
||||||
include_tasks: secret_key_configuration.yml
|
include_tasks: secret_key_configuration.yml
|
||||||
|
|
||||||
|
- name: Apply Redirect Page Configmap
|
||||||
|
k8s:
|
||||||
|
apply: true
|
||||||
|
definition: "{{ lookup('template', 'configmaps/redirect-page.configmap.html.j2') }}"
|
||||||
|
when: public_base_url is defined
|
||||||
|
|
||||||
- name: Load LDAP CAcert certificate (Deprecated)
|
- name: Load LDAP CAcert certificate (Deprecated)
|
||||||
include_tasks: load_ldap_cacert_secret.yml
|
include_tasks: load_ldap_cacert_secret.yml
|
||||||
when:
|
when:
|
||||||
@@ -68,8 +74,8 @@
|
|||||||
- name: Include set_images tasks
|
- name: Include set_images tasks
|
||||||
include_tasks: set_images.yml
|
include_tasks: set_images.yml
|
||||||
|
|
||||||
- name: Include database configuration tasks
|
- name: Include Database tasks
|
||||||
include_tasks: database_configuration.yml
|
include_tasks: database.yml
|
||||||
|
|
||||||
- name: Load Route TLS certificate
|
- name: Load Route TLS certificate
|
||||||
include_tasks: load_route_tls_secret.yml
|
include_tasks: load_route_tls_secret.yml
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
---
|
---
|
||||||
|
- name: Idle AWX
|
||||||
|
include_tasks: idle_deployment.yml
|
||||||
|
when: idle_deployment | bool
|
||||||
|
|
||||||
- name: Check for presence of old awx Deployment
|
- name: Check for presence of old awx Deployment
|
||||||
k8s_info:
|
k8s_info:
|
||||||
api_version: apps/v1
|
api_version: apps/v1
|
||||||
@@ -23,6 +27,10 @@
|
|||||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
register: awx_web_deployment
|
register: awx_web_deployment
|
||||||
|
|
||||||
|
- name: Check for existing deployment for previous version
|
||||||
|
include_tasks: check_existing.yml
|
||||||
|
when: gating_version | length
|
||||||
|
|
||||||
- name: Start installation if auto_upgrade is true
|
- name: Start installation if auto_upgrade is true
|
||||||
include_tasks: install.yml
|
include_tasks: install.yml
|
||||||
when:
|
when:
|
||||||
|
|||||||
@@ -55,6 +55,16 @@
|
|||||||
changed_when: false
|
changed_when: false
|
||||||
when: awx_web_pod_name != ''
|
when: awx_web_pod_name != ''
|
||||||
|
|
||||||
|
- name: Update upgradedFrom status
|
||||||
|
operator_sdk.util.k8s_status:
|
||||||
|
api_version: '{{ api_version }}'
|
||||||
|
kind: "{{ kind }}"
|
||||||
|
name: "{{ ansible_operator_meta.name }}"
|
||||||
|
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||||
|
status:
|
||||||
|
upgradedFrom: "{{ upgraded_from }}"
|
||||||
|
when: upgraded_from is defined
|
||||||
|
|
||||||
- name: Update version status
|
- name: Update version status
|
||||||
operator_sdk.util.k8s_status:
|
operator_sdk.util.k8s_status:
|
||||||
api_version: '{{ api_version }}'
|
api_version: '{{ api_version }}'
|
||||||
|
|||||||
@@ -304,8 +304,8 @@ data:
|
|||||||
max-requests = 1000
|
max-requests = 1000
|
||||||
buffer-size = 32768
|
buffer-size = 32768
|
||||||
|
|
||||||
harakiri = 120
|
harakiri = {{ uwsgi_timeout|int }}
|
||||||
harakiri-graceful-timeout = 115
|
harakiri-graceful-timeout = {{ [(uwsgi_timeout|int - 2), 1] | max }}
|
||||||
harakiri-graceful-signal = 6
|
harakiri-graceful-signal = 6
|
||||||
py-call-osafterfork = true
|
py-call-osafterfork = true
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ ansible_operator_meta.name }}-redirect-page
|
||||||
|
namespace: {{ ansible_operator_meta.namespace }}
|
||||||
|
data:
|
||||||
|
redirect-page.html: |
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="refresh" content="15; url={{ public_base_url }}">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Redirecting to Ansible Automation Platform</title>
|
||||||
|
|
||||||
|
<!-- Favicon links -->
|
||||||
|
<link rel="icon" type="image/x-icon" href="static/media/favicon.ico">
|
||||||
|
|
||||||
|
<!-- Link to DRF's CSS -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="static/rest_framework/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="static/rest_framework/css/bootstrap-theme.min.css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 0px;
|
||||||
|
/* background-color: rgb(34, 34, 34); */
|
||||||
|
}
|
||||||
|
.banner {
|
||||||
|
background-color: #151414;
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
min-height: 70px; /* Ensure the banner is tall enough to fit the logo */
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
width: 150px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #007BFF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.doc-note {
|
||||||
|
font-size: 0.7em; /* Makes the text smaller */
|
||||||
|
color: #555; /* Optional: Change text color to a lighter shade */
|
||||||
|
background-color: #f9f9f9; /* Optional: Light background color */
|
||||||
|
padding: 10px; /* Optional: Add some padding */
|
||||||
|
margin: 10px 0; /* Optional: Add some margin */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Banner Section with Brand Logo -->
|
||||||
|
<div class="banner">
|
||||||
|
<img src="/static/media/aap-logo.svg" alt="Brand Logo">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Redirecting to Ansible Automation Platform...</h2>
|
||||||
|
<p>If you are not redirected automatically, <a href="{{ public_base_url }}">click here</a> to go to AAP.</p>
|
||||||
|
<p class="doc-note">
|
||||||
|
The API endpoints for this platform service will temporarily remain available at the URL for this service.
|
||||||
|
Please use the Ansible Automation Platform API endpoints corresponding to this component in the future.
|
||||||
|
These can be found at <a href="{{ public_base_url }}/api/{{ deployment_type }}" target="_blank">{{ public_base_url }}/api/{{ deployment_type }}</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Include any additional scripts if needed -->
|
||||||
|
<script src="static/rest_framework/js/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="static/rest_framework/js/bootstrap.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -28,12 +28,15 @@ spec:
|
|||||||
annotations:
|
annotations:
|
||||||
kubectl.kubernetes.io/default-container: '{{ ansible_operator_meta.name }}-web'
|
kubectl.kubernetes.io/default-container: '{{ ansible_operator_meta.name }}-web'
|
||||||
{% for template in [
|
{% for template in [
|
||||||
"configmaps/config",
|
"configmaps/config.yaml",
|
||||||
"secrets/app_credentials",
|
"secrets/app_credentials.yaml",
|
||||||
"storage/persistent",
|
"storage/persistent.yaml",
|
||||||
] %}
|
] %}
|
||||||
checksum-{{ template | replace('/', '-') }}: "{{ lookup('template', template + '.yaml.j2') | sha1 }}"
|
checksum-{{ template | replace('/', '-') }}: "{{ lookup('template', template + '.j2') | sha1 }}"
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% if public_base_url is defined %}
|
||||||
|
checksum-configmaps-redirect-page.configmap.html: "{{ lookup('template', 'configmaps/redirect-page.configmap.html.j2') | sha1 }}"
|
||||||
|
{% endif %}
|
||||||
{% for secret in [
|
{% for secret in [
|
||||||
"bundle_cacert",
|
"bundle_cacert",
|
||||||
"route_tls",
|
"route_tls",
|
||||||
@@ -197,6 +200,11 @@ spec:
|
|||||||
timeoutSeconds: {{ web_readiness_timeout }}
|
timeoutSeconds: {{ web_readiness_timeout }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
{% if public_base_url is defined %}
|
||||||
|
- name: redirect-page
|
||||||
|
mountPath: '/var/lib/awx/venv/awx/lib/python3.11/site-packages/awx/ui/build/index.html'
|
||||||
|
subPath: redirect-page.html
|
||||||
|
{% endif %}
|
||||||
{% if bundle_ca_crt %}
|
{% if bundle_ca_crt %}
|
||||||
- name: "ca-trust-extracted"
|
- name: "ca-trust-extracted"
|
||||||
mountPath: "/etc/pki/ca-trust/extracted"
|
mountPath: "/etc/pki/ca-trust/extracted"
|
||||||
@@ -375,6 +383,14 @@ spec:
|
|||||||
{{ security_context_settings | to_nice_yaml | indent(8) }}
|
{{ security_context_settings | to_nice_yaml | indent(8) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
volumes:
|
volumes:
|
||||||
|
{% if public_base_url is defined %}
|
||||||
|
- name: redirect-page
|
||||||
|
configMap:
|
||||||
|
name: '{{ ansible_operator_meta.name }}-redirect-page'
|
||||||
|
items:
|
||||||
|
- key: redirect-page.html
|
||||||
|
path: redirect-page.html
|
||||||
|
{% endif %}
|
||||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||||
secret:
|
secret:
|
||||||
secretName: "{{ ansible_operator_meta.name }}-receptor-ca"
|
secretName: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||||
|
|||||||
@@ -21,3 +21,6 @@ _metrics_utility_pvc_claim: "{{ metrics_utility_pvc_claim | default(deployment_t
|
|||||||
_metrics_utility_pvc_claim_size: "{{ metrics_utility_pvc_claim_size | default('5Gi') }}"
|
_metrics_utility_pvc_claim_size: "{{ metrics_utility_pvc_claim_size | default('5Gi') }}"
|
||||||
_metrics_utility_cronjob_gather_schedule: "{{ metrics_utility_cronjob_gather_schedule | default('@hourly') }}"
|
_metrics_utility_cronjob_gather_schedule: "{{ metrics_utility_cronjob_gather_schedule | default('@hourly') }}"
|
||||||
_metrics_utility_cronjob_report_schedule: "{{ metrics_utility_cronjob_report_schedule | default('@monthly') }}"
|
_metrics_utility_cronjob_report_schedule: "{{ metrics_utility_cronjob_report_schedule | default('@monthly') }}"
|
||||||
|
|
||||||
|
# version check
|
||||||
|
gating_version: ''
|
||||||
|
|||||||
134
up.sh
Executable file
134
up.sh
Executable file
@@ -0,0 +1,134 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# AWX Operator up.sh
|
||||||
|
# Purpose:
|
||||||
|
# Build operator image from your local checkout, push to quay.io/youruser/awx-operator:dev, and deploy operator
|
||||||
|
|
||||||
|
# -- Usage
|
||||||
|
# NAMESPACE=awx TAG=dev QUAY_USER=developer ./up.sh
|
||||||
|
|
||||||
|
# -- User Variables
|
||||||
|
NAMESPACE=${NAMESPACE:-awx}
|
||||||
|
QUAY_USER=${QUAY_USER:-developer}
|
||||||
|
TAG=${TAG:-$(git rev-parse --short HEAD)}
|
||||||
|
DEV_TAG=${DEV_TAG:-dev}
|
||||||
|
DEV_TAG_PUSH=${DEV_TAG_PUSH:-true}
|
||||||
|
|
||||||
|
# -- Check for required variables
|
||||||
|
# Set the following environment variables
|
||||||
|
# export NAMESPACE=awx
|
||||||
|
# export QUAY_USER=developer
|
||||||
|
|
||||||
|
if [ -z "$QUAY_USER" ]; then
|
||||||
|
echo "Error: QUAY_USER env variable is not set."
|
||||||
|
echo " export QUAY_USER=developer"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$NAMESPACE" ]; then
|
||||||
|
echo "Error: NAMESPACE env variable is not set. Run the following with your namespace:"
|
||||||
|
echo " export NAMESPACE=developer"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -- Container Build Engine (podman or docker)
|
||||||
|
ENGINE=${ENGINE:-podman}
|
||||||
|
|
||||||
|
# -- Variables
|
||||||
|
IMG=quay.io/$QUAY_USER/awx-operator
|
||||||
|
KUBE_APPLY="kubectl apply -n $NAMESPACE -f"
|
||||||
|
|
||||||
|
# -- Wait for existing project to be deleted
|
||||||
|
# Function to check if the namespace is in terminating state
|
||||||
|
is_namespace_terminating() {
|
||||||
|
kubectl get namespace $NAMESPACE 2>/dev/null | grep -q 'Terminating'
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the namespace exists and is in terminating state
|
||||||
|
if kubectl get namespace $NAMESPACE 2>/dev/null; then
|
||||||
|
echo "Namespace $NAMESPACE exists."
|
||||||
|
|
||||||
|
if is_namespace_terminating; then
|
||||||
|
echo "Namespace $NAMESPACE is in terminating state. Waiting for it to be fully terminated..."
|
||||||
|
while is_namespace_terminating; do
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
echo "Namespace $NAMESPACE has been terminated."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -- Create namespace
|
||||||
|
kubectl create namespace $NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
# -- Prepare
|
||||||
|
|
||||||
|
# Set imagePullPolicy to Always
|
||||||
|
files=(
|
||||||
|
config/manager/manager.yaml
|
||||||
|
)
|
||||||
|
for file in "${files[@]}"; do
|
||||||
|
if grep -qF 'imagePullPolicy: IfNotPresent' ${file}; then
|
||||||
|
sed -i -e "s|imagePullPolicy: IfNotPresent|imagePullPolicy: Always|g" ${file};
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Delete old operator deployment
|
||||||
|
kubectl delete deployment awx-operator-controller-manager
|
||||||
|
|
||||||
|
# Create secrets
|
||||||
|
$KUBE_APPLY dev/secrets/custom-secret-key.yml
|
||||||
|
$KUBE_APPLY dev/secrets/admin-password-secret.yml
|
||||||
|
|
||||||
|
# (Optional) Create external-pg-secret
|
||||||
|
# $KUBE_APPLY dev/secrets/external-pg-secret.yml
|
||||||
|
|
||||||
|
|
||||||
|
# -- Login to Quay.io
|
||||||
|
$ENGINE login quay.io
|
||||||
|
|
||||||
|
if [ $ENGINE = 'podman' ]; then
|
||||||
|
if [ -f "$XDG_RUNTIME_DIR/containers/auth.json" ] ; then
|
||||||
|
REGISTRY_AUTH_CONFIG=$XDG_RUNTIME_DIR/containers/auth.json
|
||||||
|
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
|
||||||
|
elif [ -f $HOME/.config/containers/auth.json ] ; then
|
||||||
|
REGISTRY_AUTH_CONFIG=$HOME/.config/containers/auth.json
|
||||||
|
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
|
||||||
|
elif [ -f "/home/$USER/.docker/config.json" ] ; then
|
||||||
|
REGISTRY_AUTH_CONFIG=/home/$USER/.docker/config.json
|
||||||
|
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
|
||||||
|
else
|
||||||
|
echo "No Podman configuration files were found."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $ENGINE = 'docker' ]; then
|
||||||
|
if [ -f "/home/$USER/.docker/config.json" ] ; then
|
||||||
|
REGISTRY_AUTH_CONFIG=/home/$USER/.docker/config.json
|
||||||
|
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
|
||||||
|
else
|
||||||
|
echo "No Docker configuration files were found."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# -- Build & Push Operator Image
|
||||||
|
echo "Preparing to build $IMG:$TAG ($IMG:$DEV_TAG) with $ENGINE..."
|
||||||
|
sleep 3
|
||||||
|
make docker-build docker-push IMG=$IMG:$TAG
|
||||||
|
|
||||||
|
# Tag and Push DEV_TAG Image when DEV_TAG_PUSH is 'True'
|
||||||
|
if $DEV_TAG_PUSH ; then
|
||||||
|
$ENGINE tag $IMG:$TAG $IMG:$DEV_TAG
|
||||||
|
make docker-push IMG=$IMG:$DEV_TAG
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -- Deploy Operator
|
||||||
|
make deploy IMG=$IMG:$TAG NAMESPACE=$NAMESPACE
|
||||||
|
|
||||||
|
# -- Create CR
|
||||||
|
# uncomment the CR you want to use
|
||||||
|
$KUBE_APPLY dev/awx-cr/awx-openshift-cr.yml
|
||||||
|
# $KUBE_APPLY dev/awx-cr/awx-cr-settings.yml
|
||||||
|
# $KUBE_APPLY dev/awx-cr/awx-k8s-ingress.yml
|
||||||
|
|
||||||
Reference in New Issue
Block a user