Compare commits

...

65 Commits

Author SHA1 Message Date
Rick Elrod
0d55f9e80d Revert "[checkpoint_v1] Pin Cython for tests, so that PyYAML can build (#1493)" (#1495) 2023-07-17 15:30:43 -05:00
Rick Elrod
ef3c95b6b3 [checkpoint_v1] Pin Cython for tests, so that PyYAML can build (#1493)
Signed-off-by: Rick Elrod <rick@elrod.me>
2023-07-17 12:43:57 -05:00
Rick Elrod
a5ef262f3c [ci] pin ansible-compat for molecule
https://github.com/ansible-community/molecule/issues/3903

Signed-off-by: Rick Elrod <rick@elrod.me>
2023-05-23 18:12:00 -05:00
Seth Foster
2b3fd833a3 Allow TLS 1.2 for Receptor connections (#1300)
- Required for FIPS environment where TLS 1.3 is
not supported
- TLS 1.3 can still be used if the nodes
both agree to use during handshake.
2023-03-29 19:19:40 -04:00
Guillaume Lefevre
c76ad2cff1 Change ansible k8s_info tasks api_version for Deployment kind to apps/v1 (#1299)
Co-authored-by: Guillaume Lefevre <guillaume.lefevre@agoda.com>
2023-03-29 15:39:41 -04:00
John Westcott IV
aa673de25d Merge pull request #1305 from john-westcott-iv/no_jmes
Modifying stage playbook to not need jmespath
2023-03-27 21:08:32 -04:00
John Westcott IV
f1512e9405 Modifying stage playbook to not need jmespath 2023-03-27 20:56:56 -04:00
John Westcott IV
d853e050cd Merge pull request #1304 from john-westcott-iv/fix_jmes_path
Adding jmespath to workflow for using json_query
2023-03-27 20:40:10 -04:00
John Westcott IV
9f0c5c8ba9 Adding jmespath to workflow for using json_query 2023-03-27 20:26:14 -04:00
John Westcott IV
1d34d86f32 Merge pull request #1303 from john-westcott-iv/fix-playbook
Making helm release playbook more idempotent
2023-03-27 16:18:56 -04:00
John Westcott IV
7164c412f0 Making helm release playbook more idempotent 2023-03-27 16:02:21 -04:00
John Westcott IV
a8a05bb113 Merge pull request #1302 from john-westcott-iv/fix_release
Adding missing \ in promote workflow
2023-03-27 14:40:19 -04:00
John Westcott IV
bf91f32f79 Adding missing \ in promote workflow 2023-03-27 14:28:18 -04:00
Dimitri Savineau
1e453aefd3 Merge pull request #1297 from dsavineau/restore_requires_deployment_name
restore: Set deployment_name as required
2023-03-23 11:14:32 -04:00
Dimitri Savineau
71b950c243 Merge pull request #1298 from dsavineau/fix_restore_backup_source_enum
restore: Fix enum value for backup_source
2023-03-23 11:14:13 -04:00
Dimitri Savineau
b00137cc3e restore: Fix enum value for backup_source
The choice for backup_source are:
- Backup CR
- PVC

This current prevents to create an AWXRestore CR with the Backup CR value
from the OLM UI.

Error "Unsupported value: "Backup CR": supported values: "CR", "PVC"" for
field "spec.backup_source".

Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>
2023-03-22 18:18:51 -04:00
Dimitri Savineau
2cc398d8d4 restore: Set deployment_name as required
The deployment_name from the AWXRestore CR doesn't requires to set a
value for this parameter.
That parameter is already required for the AWXBackup CR so it should be
the same for AWXRestore.

Creating an AWXRestore CR without deployment_name set results in a failure
during the Secrets restoration.

"reason":"FieldValueInvalid","message":"Invalid value: \\"-receptor-ca\\":
a lowercase RFC 1123 subdomain must consist of lower case alphanumeric
characters, \'-\' or \'.\', and must start and end with an alphanumeric
character (e.g. \'example.com\', regex used for validation is
\'[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\')"

Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>
2023-03-22 17:59:49 -04:00
Joel
5c91bbd65e restore use k8s_cp module to read backup files (#1212) 2023-03-22 14:27:58 -04:00
Gene Tomilko
88b1a8c125 Add loadbalancerip (#1265)
* Add ability to configure loadbalancerip on service
* Add docs for configuring loadbalancerip
2023-03-22 18:27:17 +00:00
Christian Adams
6fd969633e Document the need for quotes on pg secret port value (#1288) 2023-03-22 14:17:40 -04:00
Christian Adams
9c788ba3bd Add more suggestions to Debugging doc (#1285) 2023-03-16 17:52:29 -04:00
Seth Foster
c2fd14e39a Merge pull request #1281 from trippinnik/patch-1
Update README.md
2023-03-15 14:29:57 -04:00
Seth Foster
6513e93e7f Merge pull request #1287 from sugitk/patch-1
fixes #1286 expand client_max_body_size to 5Mb
2023-03-15 14:17:18 -04:00
Takashi Sugimura
d0f4898aaa fix #1286 2023-03-15 08:20:16 +09:00
trippinnik
3d849d9179 Update README.md
documentation is incorrect for AUTH_LDAP_GROUP_TYPE and paramaters need to be noted with AUTH_LDAP_GROUP_TYPE_PARAMS
2023-03-09 09:46:46 -05:00
aurel333
fe77f1deae Fix awx-manager-role bad match between some apiGroups and resources (#1262)
Co-authored-by: Aurelien Potin <aurelien.potin@michelin.com>
2023-03-08 16:24:03 -05:00
Hao Liu
9156909023 Merge pull request #1263 from rh-dluong/date-format
change date format to avoid :
2023-03-08 15:58:58 -05:00
Christian Adams
03e3b68eeb Helm Release: Need to use shell, not command for multi-line (#1280) 2023-03-08 15:55:30 -05:00
Ravi Teja
6cae8dfa32 fix: use sha1 instead of md5 to make the installer work in FIPS (#1260)
Co-authored-by: RaviTeja Buddabathuni (rbuddaba) <rbuddaba@cisco.com>
2023-03-08 15:10:27 -05:00
Hao Liu
b1ecc89759 Merge pull request #1274 from TheRealHaoLiu/feature-branch-build
Add github workflow for publishing feature branch images
2023-03-07 17:05:08 -05:00
Hao Liu
bb85b31411 Add github workflow to publish feature branch img 2023-03-07 16:50:28 -05:00
Christian Adams
7e7c23e176 Fix helm-release task to work in ansible, not GHA env (#1267) 2023-03-06 15:25:04 -05:00
John Westcott IV
8442cc7ae8 Merge pull request #1268 from john-westcott-iv/ubuntu-change
Changing github actions from ubuntu-18 to ubuntu-latest
2023-03-06 15:06:02 -05:00
John Westcott IV
3faf76d7c9 Changing github actions from ubuntu-18 to ubuntu-latest
See https://github.com/actions/runner-images/issues/6002 for deprication warnings
2023-03-06 14:55:32 -05:00
David Luong
61ef5ef005 change date format to avoid : 2023-03-02 13:54:00 -05:00
Peter Hoffmann
86043361c6 Small fix/adjustment in README (#1257)
* Fix minor typo
2023-02-28 16:20:47 -05:00
Ravi Teja
06194960e9 Bump ansible operator SDK version to v1.26.0 (#1258)
Co-authored-by: RaviTeja Buddabathuni (rbuddaba) <rbuddaba@cisco.com>
2023-02-28 15:45:02 -05:00
Hao Liu
46da413585 Merge pull request #1193 from stanislav-zaprudskiy/add_termination_grace_period_seconds
AWX: Add `termination_grace_period_seconds`
2023-02-28 15:37:51 -05:00
Hao Liu
b5f255cf00 add nodeport_port to instantiate playbook (#1252) 2023-02-22 21:18:12 +00:00
Maxence Button
f328b0adb6 Customization of the init_projects_container_image is now possible (#1248) 2023-02-22 15:05:23 -05:00
Shane McDonald
1bfd3b2028 Merge pull request #1201 from thedoubl3j/debugging_doc_update
Update Installer Debugging Documentation
2023-02-22 14:51:05 -05:00
Christian Adams
edf01f009e Stage and push helm index where gitconfig is set (#1251) 2023-02-22 14:09:35 -05:00
Joel
a3c28be98a [enhancement] restore postgres database if external db (#1211)
* restore postgres fix resolvable_db_host

set the resolvable_db_host ansible variable based on the db deployment
2023-02-22 13:56:38 -05:00
Stanislav Zaprudskiy
49d1f00dbd Do not keep web container running during termination
We could let the web container terminate as usual, as there are no
reasons to keep it running as it doesn't participate in
job control. Additionally, it stops receiving traffic with the beginning
of termination

> At the same time as the kubelet is starting graceful shutdown, the
> control plane removes that shutting-down Pod from EndpointSlice (and
> Endpoints) objects where these represent a Service with a configured
> selector

@ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination
2023-02-22 10:40:40 +01:00
Christian Adams
81939cb521 K8s cpu value example in README.md needs quotes to be valid (#1220) 2023-02-20 17:37:53 -05:00
Shane McDonald
6b10a8141c Merge pull request #1231 from rooftopcellist/auto-assign-nodeport 2023-02-09 20:27:26 -05:00
Christian M. Adams
1ef1f00b3d Auto-assign NodePort port by default rather than hardcoding a default value
- previously, there was no way to auto-assign a port by default
   which led to conflicts with other deployments at times
 - nodeport_port param can still be used to specify a port if desired
2023-02-09 19:49:46 -05:00
Stanislav Zaprudskiy
336ea58a0a AWX: Add termination_grace_period_seconds 2023-02-07 16:33:00 +01:00
Stanislav Zaprudskiy
f042cb3d00 Fix lint warnings 2023-02-07 16:31:26 +01:00
Stanislav Zaprudskiy
94d68bf382 Make Deployment to be rolled out on CM and Secrets changes
With the previous approach, not all associated (mounted) CM/Secrets
changes caused the Deployment to be rolled out, but also the Deployment
could have been rolled out unnecessary during e.g. Ingress or Service
changes (which do not require Pod restarts).

Previously existing Pod removal (state: absent) was not complete as
other pods continued to exist, but also is not needed with this commit
change due to added Pods annotations.

The added Deployment Pod annotations now cause the new ReplicaSet
version to be rolled out, effectively causing replacement of the
previously existing Pods in accordance with the deployment `strategy`
(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#deploymentstrategy-v1-apps,
`RollingUpdate`) whenever there is a change in the associated CMs or
Secrets referenced in annotations. This implementation is quite standard
and widely used for Helm workflows -
https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
2023-02-07 11:58:47 +01:00
Stanislav Zaprudskiy
b3a74362af Make AWX Pod variable to be calculated respecting creationTimestamp and deletionTimestamp
Do not consider Pods marked for deletion when calculating tower_pod to
address replicas scale down case - where normally Pods spawned recently
are being taken for removal. As well as the case when operator kicked
off but some old replicas are still terminating.

Respect `creationTimestamp` so to make sure that the newest Pod is taken
after Deployment application, in which case multiple RS Pods (from old
RS and new RS) could be running simultaneously while the rollout is
happening.
2023-02-07 11:47:49 +01:00
Stanislav Zaprudskiy
ad531c8dce Do not wait for a new Pod name after Deployment change
Proper waiting is already performed earlier during Deplyment{apply: yes, wait: yes} -
e6ac874098/plugins/module_utils/k8s/waiter.py (L27).

And also not every Deployment change produces new RS/Pods. For example,
changing Deployment labels won't cause new rollout, but will cause
`until` loop to be invoked unnecessarily (when replicas=1).
2023-02-07 11:43:34 +01:00
Stanislav Zaprudskiy
e589ceb661 When applying Deployment wait up to (timeout * replicas)
There are cases when having a new Deployment may be taking above the
default timeout of 120s.
For instance, when a Deployment has multiple replicas, and each replica
starts on a separate node, and the Deployment specifies new images, then
just pulling these new images for each replica may be taking above the
default timeout of 120s.

Having the default time multiplied by the number of replicas should
provide generally enough time for all replicas to start
2023-02-07 11:41:32 +01:00
Christian Adams
234a10d185 Add a more descriptive AWX CRD description (#1208) 2023-01-31 10:50:12 -05:00
Christian Adams
e0fa1610ca Fix minor typos in test task names (#1209) 2023-01-31 00:05:37 +00:00
Stanislav Zaprudskiy
5a856eeba8 Add additional_labels parameter (#1160)
* Move label templates into `common` role

So that there is single source of labels management, and labels are
unified across the other roles

* Introduce `additional_labels`
* Fix paths for labels templates
* Return `additional_labels_items` as list
* Add molecule tests
2023-01-30 18:51:08 -05:00
Christian Adams
d26a6bf641 Fix minor helm make target syntax error (#1206) 2023-01-27 09:56:40 -05:00
janorn
8d6db0934f Fix helm chart URLs (#1204) 2023-01-27 09:32:46 -05:00
John Westcott IV
c1b2e73123 Merge pull request #1202 from john-westcott-iv/security_requested_change
Nominal change to the pr body check
2023-01-25 17:29:50 -05:00
John Westcott IV
6ac8668ead Nominal change to the pr body check 2023-01-25 17:12:08 -05:00
thedoubl3j
d0516bcdc1 update vars file entry to include over ride examples 2023-01-25 14:41:18 -05:00
Christian Adams
ac5a2538bc Fix helm index.yaml generation error (#1199) 2023-01-24 21:40:42 -05:00
Christian Adams
2bdc87d0a8 Add docs for ingress resource apiVersion configuration (#1198) 2023-01-24 22:42:02 +00:00
Joel
ab566c2530 backup role use k8s_cp module to write files (#1111) 2023-01-24 17:02:05 -05:00
rakesh561
6a7c3ca2de Add docs for disabling IPv6
* Added procedure to disable ipv6 for AWX deployments when needed.
2023-01-24 04:26:25 +00:00
67 changed files with 957 additions and 280 deletions

View File

@@ -11,7 +11,7 @@ on:
jobs:
molecule:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
name: molecule
env:
DOCKER_API_VERSION: "1.38"
@@ -40,7 +40,7 @@ jobs:
make kustomize
KUSTOMIZE_PATH=$(readlink -f bin/kustomize) molecule test -s kind
helm:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
name: helm
steps:
- uses: actions/checkout@v2

View File

@@ -8,7 +8,7 @@ on:
jobs:
release:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
name: Push devel image
steps:
- uses: actions/checkout@v2

75
.github/workflows/feature.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
---
name: Feature Branch Image Build and Push
on:
push:
branches: [feature_*]
jobs:
release:
runs-on: ubuntu-18.04
name: Push devel image
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # needed so that git describe --tag works
- name: Set VERSION
run: |
echo "VERSION=$(git describe --tags)" >>${GITHUB_ENV}
- name: Set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: '${{ github.repository_owner }}'
- name: Set IMAGE_TAG_BASE
run: |
echo "IMAGE_TAG_BASE=ghcr.io/${OWNER_LC}/awx-operator" >>${GITHUB_ENV}
- name: Set ARCH environment variable
run: |
echo "ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)" >>${GITHUB_ENV}
- name: Set OS environment variable
run: |
echo "OS=$(uname | awk '{print tolower($0)}')" >>${GITHUB_ENV}
- name: Install operator-sdk
run: |
echo "Installing operator-sdk ${OPERATOR_SDK_DL_URL}" && \
curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH} && \
chmod +x operator-sdk_${OS}_${ARCH} && \
sudo mkdir -p /usr/local/bin/ && \
sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk && \
operator-sdk version
env:
OPERATOR_SDK_DL_URL: https://github.com/operator-framework/operator-sdk/releases/download/v1.26.0
- name: Log in to registry
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build and Push awx-operator Image
run: |
make docker-build docker-push
docker tag ${IMAGE_TAG_BASE}:${VERSION} ${IMAGE_TAG_BASE}:${GITHUB_REF##*/}
docker push ${IMAGE_TAG_BASE}:${GITHUB_REF##*/}
- name: Build bundle manifests
run: |
make bundle
- name: Build and Push awx-operator Bundle
run: |
make bundle-build bundle-push
docker tag ${IMAGE_TAG_BASE}-bundle:v${VERSION} ${IMAGE_TAG_BASE}-bundle:${GITHUB_REF##*/}
docker push ${IMAGE_TAG_BASE}-bundle:${GITHUB_REF##*/}
- name: Build and Push awx-operator Catalog
run: |
make catalog-build catalog-push
docker tag ${IMAGE_TAG_BASE}-catalog:v${VERSION} ${IMAGE_TAG_BASE}-catalog:${GITHUB_REF##*/}
docker push ${IMAGE_TAG_BASE}-catalog:${GITHUB_REF##*/}

View File

@@ -17,9 +17,9 @@ jobs:
env:
PR_BODY: ${{ github.event.pull_request.body }}
run: |
echo $PR_BODY | grep "Bug, Docs Fix or other nominal change" > Z
echo $PR_BODY | grep "New or Enhanced Feature" > Y
echo $PR_BODY | grep "Breaking Change" > X
echo "$PR_BODY" | grep "Bug, Docs Fix or other nominal change" > Z
echo "$PR_BODY" | grep "New or Enhanced Feature" > Y
echo "$PR_BODY" | grep "Breaking Change" > X
exit 0
# We exit 0 and set the shell to prevent the returns from the greps from failing this step
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference

View File

@@ -33,15 +33,11 @@ jobs:
docker push quay.io/${{ github.repository }}:${{ github.event.release.tag_name }}
docker push quay.io/${{ github.repository }}:latest
- name: Configure git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Release Helm chart
run: |
ansible-playbook ansible/helm-release.yml -v \
-e operator_image=quay.io/${{ github.repository }} \
-e chart_owner=${{ github.repository_owner }} \
-e tag=${{ github.event.release.tag_name }} \
-e gh_token=${{ secrets.GITHUB_TOKEN }}
-e gh_token=${{ secrets.GITHUB_TOKEN }} \
-e gh_user=${{ github.actor }}

View File

@@ -1,4 +1,4 @@
FROM quay.io/operator-framework/ansible-operator:v1.25.3
FROM quay.io/operator-framework/ansible-operator:v1.26.0
USER 0

View File

@@ -156,7 +156,7 @@ ifeq (,$(shell which ansible-operator 2>/dev/null))
@{ \
set -e ;\
mkdir -p $(dir $(ANSIBLE_OPERATOR)) ;\
curl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.25.3/ansible-operator_$(OS)_$(ARCHA) ;\
curl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.26.0/ansible-operator_$(OS)_$(ARCHA) ;\
chmod +x $(ANSIBLE_OPERATOR) ;\
}
else
@@ -187,7 +187,7 @@ ifeq (,$(shell which opm 2>/dev/null))
@{ \
set -e ;\
mkdir -p $(dir $(OPM)) ;\
curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.25.3/$(OS)-$(ARCHA)-opm ;\
curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.26.0/$(OS)-$(ARCHA)-opm ;\
chmod +x $(OPM) ;\
}
else
@@ -377,25 +377,21 @@ helm-index:
for tag in $(TAGS); do\
dl_url="https://github.com/$(CHART_OWNER)/$(CHART_REPO)/releases/download/$${tag}/$(CHART_REPO)-$${tag}.tgz";\
echo "Downloading $${tag} from $${dl_url}";\
curl -RLOs -z ".cr-release-packages/$(CHART_REPO)-$${tag}.tgz" --fail $${dl_url};\
curl -RLOs -z "$(CHART_REPO)-$${tag}.tgz" --fail $${dl_url};\
result=$$?;\
if [ $${result} -eq 0 ]; then\
echo "Downloaded $${dl_url}";\
mkdir -p .cr-release-packages/$${tag};\
mv ./$(CHART_REPO)-$${tag}.tgz .cr-release-packages/$${tag};\
else\
echo "Skipping release $${tag}; No helm chart present";\
rm -rf ".cr-release-packages/$(CHART_REPO)-$${tag}.tgz";\
rm -rf "$(CHART_REPO)-$${tag}.tgz";\
fi;\
done;\
# generate the index file in the root of the gh-pages branch
# --merge will leave any values in index.yaml that don't get generated by this command, but
# it is likely that all values are overridden
$(HELM) repo index .cr-release-packages --url https://$(CHART_OWNER).github.io/awx-operator/ --merge gh-pages/index.yaml
$(HELM) repo index .cr-release-packages --url https://github.com/$(CHART_OWNER)/$(CHART_REPO)/releases/download/ --merge gh-pages/index.yaml
mv .cr-release-packages/index.yaml gh-pages/index.yaml
@echo "== PUSH INDEX FILE =="
cd gh-pages;\
git add index.yaml;\
git commit -m "Updated index.yaml latest release";\
git push;\

102
README.md
View File

@@ -48,6 +48,8 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
* [Auto Upgrade](#auto-upgrade)
* [Upgrade of instances without auto upgrade](#upgrade-of-instances-without-auto-upgrade)
* [Service Account](#service-account)
* [Labeling operator managed objects](#labeling-operator-managed-objects)
* [Pods termination grace period](#pods-termination-grace-period)
* [Uninstall](#uninstall)
* [Upgrading](#upgrading)
* [Backup](#backup)
@@ -55,6 +57,7 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
* [Cluster-scope to Namespace-scope considerations](#cluster-scope-to-namespace-scope-considerations)
* [Project is now based on v1.x of the operator-sdk project](#project-is-now-based-on-v1x-of-the-operator-sdk-project)
* [Steps to upgrade](#steps-to-upgrade)
* [Disable IPV6](#disable-ipv6)
* [Add Execution Nodes](#adding-execution-nodes)
* [Custom Receptor CA](#custom-receptor-ca)
* [Contributing](#contributing)
@@ -197,8 +200,6 @@ 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).
@@ -269,7 +270,7 @@ yDL2Cx5Za94g9MvBP6B73nzVLlmfgPjR
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).
For an example using the Nginx Ingress Controller in Minikube, don't miss our [demo video](https://asciinema.org/a/416946).
### Helm Install on existing cluster
@@ -402,12 +403,14 @@ The following variables are customizable only when `service_type=LoadBalancer`
| --------------------- | ---------------------------------------- | ------- |
| loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
| loadbalancer_port | Port used for Loadbalancer ingress | 80 |
| loadbalancer_ip | Assign Loadbalancer IP | '' |
```yaml
---
spec:
...
service_type: LoadBalancer
loadbalancer_ip: '192.168.10.25'
loadbalancer_protocol: https
loadbalancer_port: 443
service_annotations: |
@@ -462,6 +465,7 @@ The following variables are customizable when `ingress_type=ingress`. The `ingre
| hostname | Define the FQDN | {{ meta.name }}.example.com |
| ingress_path | Define the ingress path to the service | / |
| ingress_path_type | Define the type of the path (for LBs) | Prefix |
| ingress_api_version | Define the Ingress resource apiVersion | 'networking.k8s.io/v1' |
```yaml
---
@@ -482,6 +486,7 @@ The following variables are customizable when `ingress_type=route`
| 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 |
| route_api_version | Define the Route resource apiVersion | 'route.openshift.io/v1' |
```yaml
---
@@ -572,7 +577,7 @@ spec:
cpu: 500m
memory: 2Gi
limits:
cpu: 1
cpu: '1'
memory: 4Gi
postgres_storage_requirements:
requests:
@@ -867,7 +872,7 @@ A sample of extra settings can be found as below. All possible options can be fo
value: 'LDAPSearch("OU=Groups,DC=abc,DC=com",ldap.SCOPE_SUBTREE,"(objectClass=group)",)'
- setting: AUTH_LDAP_GROUP_TYPE
value: 'GroupOfNamesType(name_attr="cn")'
value: 'GroupOfNamesType'
- setting: AUTH_LDAP_USER_ATTR_MAP
value: '{"first_name": "givenName","last_name": "sn","email": "mail"}'
@@ -1215,6 +1220,74 @@ Example configuration of environment variables
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME>
```
#### Labeling operator managed objects
In certain situations labeling of Kubernetes objects managed by the operator
might be desired (e.g. for owner identification purposes). For that
`additional_labels` parameter could be used
| Name | Description | Default |
| --------------------------- | ---------------------------------------------------------------------------------------- | ------- |
| additional_labels | Additional labels defined on the resource, which should be propagated to child resources | [] |
Example configuration where only `my/team` and `my/service` labels will be
propagated to child objects (`Deployment`, `Secret`s, `ServiceAccount`, etc):
```yaml
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx-demo
labels:
my/team: "foo"
my/service: "bar"
my/do-not-inherit: "yes"
spec:
additional_labels:
- my/team
- my/service
...
```
#### Pods termination grace period
During deployment restarts or new rollouts, when old ReplicaSet Pods are being
terminated, the corresponding jobs which are managed (executed or controlled)
by old AWX Pods may end up in `Error` state as there is no mechanism to
transfer them to the newly spawned AWX Pods. To work around the problem one
could set `termination_grace_period_seconds` in AWX spec, which does the
following:
* It sets the corresponding
[`terminationGracePeriodSeconds`](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)
Pod spec of the AWX Deployment to the value provided
> The grace period is the duration in seconds after the processes running in
> the pod are sent a termination signal and the time when the processes are
> forcibly halted with a kill signal
* It adds a
[`PreStop`](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution)
hook script, which will keep AWX Pods in terminating state until it finished,
up to `terminationGracePeriodSeconds`.
> This grace period applies to the total time it takes for both the PreStop
> hook to execute and for the Container to stop normally
While the hook script just waits until the corresponding AWX Pod (instance)
no longer has any managed jobs, in which case it finishes with success and
hands over the overall Pod termination process to normal AWX processes.
One may want to set this value to the maximum duration they accept to wait for
the affected Jobs to finish. Keeping in mind that such finishing jobs may
increase Pods termination time in such situations as `kubectl rollout restart`,
AWX upgrade by the operator, or Kubernetes [API-initiated
evictions](https://kubernetes.io/docs/concepts/scheduling-eviction/api-eviction/).
| Name | Description | Default |
| -------------------------------- | --------------------------------------------------------------- | ------- |
| termination_grace_period_seconds | Optional duration in seconds pods needs to terminate gracefully | not set |
### Uninstall ###
@@ -1285,6 +1358,25 @@ Then install the new AWX Operator by following the instructions in [Basic Instal
Once the new AWX Operator is up and running, your AWX deployment will also be upgraded.
### Disable IPV6
Starting with AWX Operator release 0.24.0,[IPV6 was enabled in ngnix configuration](https://github.com/ansible/awx-operator/pull/950) which causes
upgrades and installs to fail in environments where IPv6 is not allowed. Starting in 1.1.1 release, you can set the `ipv6_disabled` flag on the AWX
spec. If you need to use an AWX operator version between 0.24.0 and 1.1.1 in an IPv6 disabled environment, it is suggested to enabled ipv6 on worker
nodes.
In order to disable ipv6 on ngnix configuration (awx-web container), add following to the AWX spec.
The following variables are customizable
| Name | Description | Default |
| ------------- | ---------------------- | ------- |
| ipv6_disabled | Flag to disable ipv6 | false |
```yaml
spec:
ipv6_disabled: true
```
### Adding Execution Nodes
Starting with AWX Operator v0.30.0 and AWX v21.7.0, standalone execution nodes can be added to your deployments.
See [AWX execution nodes docs](https://github.com/ansible/awx/blob/devel/docs/execution_nodes.md) for information about this feature.

View File

@@ -14,34 +14,78 @@
Release must exist before running this playbook
when: release is not success
- name: Build and package helm chart
command: |
make helm-package
environment:
VERSION: "{{ tag }}"
IMAGE_TAG_BASE: "{{ operator_image }}"
args:
chdir: "{{ playbook_dir }}/../"
- name: Set helm filename and commit message
set_fact:
asset_already_attached: False
helm_file_name: "awx-operator-{{ tag }}.tgz"
commit_message: "Updated index.yaml for release {{ release.json.tag_name }}"
# Move to chart releaser after https://github.com/helm/chart-releaser/issues/122 exists
- name: Upload helm chart
uri:
url: "https://uploads.github.com/repos/{{ chart_owner }}/{{ chart_repo }}/releases/{{ release.json.id }}/assets?name=awx-operator-{{ tag }}.tgz"
src: "{{ playbook_dir }}/../.cr-release-packages/awx-operator-{{ tag }}.tgz"
headers:
Authorization: "token {{ gh_token }}"
Content-Type: "application/octet-stream"
status_code:
- 200
- 201
register: asset_upload
changed_when: asset_upload.json.state == "uploaded"
- name: See if file is already attached
set_fact:
asset_already_attached: True
loop: "{{ release.json.get('assets', []) }}"
loop_control:
label: "{{ item.name }}"
when: item.name == helm_file_name
- name: Publish helm index
command: |
make helm-index
environment:
CHART_OWNER: "{{ chart_owner }}"
CR_TOKEN: "{{ gh_token }}"
args:
chdir: "{{ playbook_dir }}/../"
- when: not asset_already_attached
block:
- name: Build and package helm chart
command: |
make helm-package
environment:
VERSION: "{{ tag }}"
IMAGE_TAG_BASE: "{{ operator_image }}"
args:
chdir: "{{ playbook_dir }}/../"
# Move to chart releaser after https://github.com/helm/chart-releaser/issues/122 exists
- name: Upload helm chart
uri:
url: "https://uploads.github.com/repos/{{ chart_owner }}/{{ chart_repo }}/releases/{{ release.json.id }}/assets?name={{ helm_file_name }}"
src: "{{ playbook_dir }}/../.cr-release-packages/awx-operator-{{ tag }}.tgz"
headers:
Authorization: "token {{ gh_token }}"
Content-Type: "application/octet-stream"
status_code:
- 200
- 201
register: asset_upload
changed_when: asset_upload.json.state == "uploaded"
- name: Ensure gh-pages exists
file:
state: directory
path: "{{ playbook_dir }}/../gh-pages"
- name: Check if we have published the release
command:
cmd: "git log --grep='{{ commit_message }}'"
chdir: "{{ playbook_dir }}/../gh-pages"
register: commits_for_release
- when: commits_for_release.stdout == ''
block:
- name: Configure git config
shell: |
git config user.name {{ gh_user }}
git config user.email {{ gh_user }}@users.noreply.github.com
args:
chdir: "{{ playbook_dir }}/../gh-pages"
- name: Publish helm index
command: |
make helm-index
environment:
CHART_OWNER: "{{ chart_owner }}"
CR_TOKEN: "{{ gh_token }}"
args:
chdir: "{{ playbook_dir }}/../"
- name: Stage and Push commit to gh-pages branch
shell: |
git add index.yaml
git commit -m "{{ commit_message }}"
git push
args:
chdir: "{{ playbook_dir }}/../gh-pages"

View File

@@ -26,6 +26,7 @@
image_version: "{{ image_version | default(omit) }}"
development_mode: "{{ development_mode | default(omit) | bool }}"
image_pull_policy: "{{ image_pull_policy | default(omit) }}"
nodeport_port: "{{ nodeport_port | default(omit) }}"
# ee_images:
# - name: test-ee
# image: quay.io/<user>/awx-ee

View File

@@ -94,6 +94,11 @@ spec:
description: Configure no_log for no_log tasks
type: boolean
default: true
additional_labels:
description: Additional labels defined on the resource, which should be propagated to child resources
type: array
items:
type: string
set_self_labels:
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
type: boolean

View File

@@ -39,12 +39,14 @@ spec:
spec:
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- deployment_name
properties:
backup_source:
description: Backup source
type: string
enum:
- CR
- Backup CR
- PVC
deployment_name:
description: Name of the restored deployment. This should be different from the original deployment name
@@ -96,6 +98,11 @@ spec:
description: Configure no_log for no_log tasks
type: boolean
default: true
additional_labels:
description: Additional labels defined on the resource, which should be propagated to child resources
type: array
items:
type: string
set_self_labels:
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
type: boolean

View File

@@ -132,6 +132,10 @@ spec:
description: Port to use for the loadbalancer
type: integer
default: 80
loadbalancer_ip:
description: Assign LoadBalancer IP address
type: string
default: ''
route_host:
description: The DNS to use to points to the instance
type: string
@@ -153,7 +157,6 @@ spec:
nodeport_port:
description: Port to use for the nodeport
type: integer
default: 30080
node_selector:
description: nodeSelector for the pods
type: string
@@ -526,6 +529,10 @@ spec:
type: array
type: object
type: object
termination_grace_period_seconds:
description: Optional duration in seconds pods needs to terminate gracefully
type: integer
format: int32
service_labels:
description: Additional labels to apply to the service
type: string
@@ -759,6 +766,9 @@ spec:
init_container_extra_volume_mounts:
description: Specify volume mounts to be added to the init container
type: string
init_projects_container_image:
description: Registry path to the init projects container to use
type: string
postgres_image:
description: Registry path to the PostgreSQL container to use
type: string
@@ -890,6 +900,11 @@ spec:
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
type: boolean
default: true
additional_labels:
description: Additional labels defined on the resource, which should be propagated to child resources
type: array
items:
type: string
ipv6_disabled:
description: Disable web container's nginx ipv6 listener
type: boolean

View File

@@ -151,7 +151,7 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
version: v1beta1
- description: Deploy a new instance of AWX
- description: Deploy a new instance of AWX. A standardized way to define, operate and scale automation with Ansible.
displayName: AWX
kind: AWX
name: awxs.awx.ansible.com
@@ -270,6 +270,12 @@ spec:
- 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: LoadBalancer IP
path: loadbalancer_ip
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:string
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:service_type:LoadBalancer
- displayName: Route API Version
path: route_api_version
x-descriptors:
@@ -622,6 +628,11 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Termination Grace Period Seconds
path: termination_grace_period_seconds
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Service Labels
path: service_labels
x-descriptors:
@@ -687,6 +698,12 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Init Projects Container image to use
displayName: Init Projects Container Image
path: init_projects_container_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Secret where can be found the trusted Certificate Authority Bundle
path: bundle_cacert_secret
x-descriptors:
@@ -707,6 +724,12 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- displayName: Additional labels defined on the resource, which should be
propagated to child resources
path: additional_labels
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Disable IPv6 listener?
path: ipv6_disabled
x-descriptors:

View File

@@ -20,7 +20,6 @@ rules:
- watch
- apiGroups:
- ""
- "rbac.authorization.k8s.io"
resources:
- pods
- services
@@ -31,6 +30,17 @@ rules:
- events
- configmaps
- secrets
verbs:
- get
- list
- create
- delete
- patch
- update
- watch
- apiGroups:
- "rbac.authorization.k8s.io"
resources:
- roles
- rolebindings
verbs:
@@ -43,12 +53,22 @@ rules:
- watch
- apiGroups:
- apps
- networking.k8s.io
resources:
- deployments
- daemonsets
- replicasets
- statefulsets
verbs:
- get
- list
- create
- delete
- patch
- update
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get

View File

@@ -4,7 +4,7 @@
entrypoint:
- scorecard-test
- basic-check-spec
image: quay.io/operator-framework/scorecard-test:v1.25.3
image: quay.io/operator-framework/scorecard-test:v1.26.0
labels:
suite: basic
test: basic-check-spec-test

View File

@@ -4,7 +4,7 @@
entrypoint:
- scorecard-test
- olm-bundle-validation
image: quay.io/operator-framework/scorecard-test:v1.25.3
image: quay.io/operator-framework/scorecard-test:v1.26.0
labels:
suite: olm
test: olm-bundle-validation-test
@@ -14,7 +14,7 @@
entrypoint:
- scorecard-test
- olm-crds-have-validation
image: quay.io/operator-framework/scorecard-test:v1.25.3
image: quay.io/operator-framework/scorecard-test:v1.26.0
labels:
suite: olm
test: olm-crds-have-validation-test
@@ -24,7 +24,7 @@
entrypoint:
- scorecard-test
- olm-crds-have-resources
image: quay.io/operator-framework/scorecard-test:v1.25.3
image: quay.io/operator-framework/scorecard-test:v1.26.0
labels:
suite: olm
test: olm-crds-have-resources-test
@@ -34,7 +34,7 @@
entrypoint:
- scorecard-test
- olm-spec-descriptors
image: quay.io/operator-framework/scorecard-test:v1.25.3
image: quay.io/operator-framework/scorecard-test:v1.26.0
labels:
suite: olm
test: olm-spec-descriptors-test
@@ -44,7 +44,7 @@
entrypoint:
- scorecard-test
- olm-status-descriptors
image: quay.io/operator-framework/scorecard-test:v1.25.3
image: quay.io/operator-framework/scorecard-test:v1.26.0
labels:
suite: olm
test: olm-status-descriptors-test

View File

@@ -1,4 +1,67 @@
# Iterating on the installer without deploying the operator
# Debugging the AWX Operator
## General Debugging
When the operator is deploying AWX, it is running the `installer` role inside the operator container. If the AWX CR's status is `Failed`, it is often useful to look at the awx-operator container logs, which shows the output of the installer role. To see these logs, run:
```
kubectl logs deployments/awx-operator-controller-manager -c awx-manager -f
```
### Inspect k8s Resources
Past that, it is often useful to inspect various resources the AWX Operator manages like:
* awx
* awxbackup
* awxrestore
* pod
* deployment
* pvc
* service
* ingress
* route
* secrets
* serviceaccount
And if installing via OperatorHub and OLM:
* subscription
* csv
* installPlan
* catalogSource
To inspect these resources you can use these commands
```
# Inspecting k8s resources
kubectl describe -n <namespace> <resource> <resource-name>
kubectl get -n <namespace> <resource> <resource-name> -o yaml
kubectl logs -n <namespace> <resource> <resource-name>
# Inspecting Pods
kubectl exec -it -n <namespace> <pod> <pod-name>
```
### Configure No Log
It is possible to show task output for debugging by setting no_log to false on the AWX CR spec.
This will show output in the awx-operator logs for any failed tasks where no_log was set to true.
For example:
```
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx-demo
spec:
service_type: nodeport
no_log: false # <------------
```
## Iterating on the installer without deploying the operator
Go through the [normal basic install](https://github.com/ansible/awx-operator/blob/devel/README.md#basic-install) steps.
@@ -35,6 +98,19 @@ ansible_operator_meta:
namespace: awx
service_type: nodeport
```
The vars file will replace the awx resource so any value that you wish to over ride using the awx resource, put in the vars file. For example, if you wish to use your own image, version and pull policy, you can specify it like below:
```yaml
# vars.yml
---
ansible_operator_meta:
name: awx
namespace: awx
service_type: nodeport
image: $DEV_DOCKER_TAG_BASE/awx_kube_devel
image_pull_policy: Always
image_version: $COMPOSE_TAG
```
Run the installer:

View File

@@ -34,7 +34,7 @@ metadata:
namespace: <target namespace>
stringData:
host: <external ip or url resolvable by the cluster>
port: <external port, this usually defaults to 5432>
port: "<external port, this usually defaults to 5432>" # quotes are required
database: <desired database name>
username: <username to connect as>
password: <password to connect with>

View File

@@ -28,7 +28,7 @@
register: awx_pod
when: not awx_version
- name: Exract tags from images
- name: Extract tags from images
set_fact:
image_tags: |
{{ awx_pod.resources[0].spec.containers |
@@ -83,3 +83,61 @@
result: '{{ ansible_failed_result }}'
fail:
msg: '{{ failed_task }}'
- block:
- name: Look up details for this deployment
k8s_info:
namespace: "{{ namespace }}"
api_version: "awx.ansible.com/v1beta1"
kind: AWX
name: example-awx
register: this_awx
- name: Get pod details
k8s_info:
namespace: '{{ namespace }}'
kind: Pod
label_selectors:
- app.kubernetes.io/name = example-awx
register: awx_pod
- name: Extract additional_labels from AWX spec
set_fact:
awx_additional_labels: >-
{{ this_awx.resources[0].metadata.labels
| dict2items | selectattr('key', 'in', this_awx.resources[0].spec.additional_labels)
| list
}}
- name: Extract additional_labels from AWX Pod
set_fact:
pod_additional_labels: >-
{{ awx_pod.resources[0].metadata.labels
| dict2items | selectattr('key', 'in', this_awx.resources[0].spec.additional_labels)
| list
}}
- name: AWX Pod contains additional_labels
ansible.builtin.assert:
that:
- pod_additional_labels == awx_additional_labels
- name: Extract Pod labels which shouldn't have been propagated to it from AWX
set_fact:
pod_extra_labels: >-
{{ awx_pod.resources[0].metadata.labels
| dict2items | selectattr('key', 'in', ["my/do-not-inherit"])
| list
}}
- name: AWX Pod doesn't contain AWX labels not in additional_labels
ansible.builtin.assert:
that:
- pod_extra_labels == []
rescue:
- name: Re-emit failure
vars:
failed_task:
result: '{{ ansible_failed_result }}'
fail:
msg: '{{ failed_task }}'

View File

@@ -3,6 +3,10 @@ apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: example-awx
labels:
my/team: "foo"
my/service: "bar"
my/do-not-inherit: "yes"
spec:
{% if awx_image %}
image: {{ awx_image }}
@@ -30,3 +34,6 @@ spec:
postgres_resource_requirements: {}
postgres_init_container_resource_requirements: {}
redis_resource_requirements: {}
additional_labels:
- my/team
- my/service

View File

@@ -5,3 +5,4 @@ ansible-lint
openshift!=0.13.0
jmespath
ansible-core
ansible-compat<4 # https://github.com/ansible-community/molecule/issues/3903

View File

@@ -31,6 +31,9 @@ backup_resource_requirements:
# Allow additional parameters to be added to the pg_dump backup command
pg_dump_suffix: ''
# Labels defined on the resource, which should be propagated to child resources
additional_labels: []
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
set_self_labels: true
...

View File

@@ -24,7 +24,8 @@ galaxy_info:
- backup
- automation
dependencies: []
dependencies:
- role: common
collections:
- kubernetes.core

View File

@@ -28,8 +28,8 @@
previous_deployment_name: "{{ this_awx['resources'][0]['metadata']['name'] }}"
- name: Write awx object to pvc
k8s_exec:
k8s_cp:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
command: >-
bash -c 'echo "$0" > {{ backup_dir }}/awx_object' {{ awx_spec | to_yaml | quote }}
remote_path: "{{ backup_dir }}/awx_object"
content: "{{ awx_spec | to_yaml }}"

View File

@@ -10,12 +10,7 @@
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") }}'
labels: '{{ lookup("template", "../common/templates/labels/common.yaml.j2") | from_yaml }}'
when: set_self_labels | bool
- name: Look up details for this backup object
@@ -26,23 +21,33 @@
namespace: "{{ ansible_operator_meta.namespace }}"
register: this_backup
- name: Build `additional_labels_items` labels from `additional_labels`
set_fact:
additional_labels_items: >-
{{ this_backup['resources'][0]['metadata']['labels']
| dict2items | selectattr('key', 'in', additional_labels)
}}
when:
- additional_labels | length
- this_backup['resources'][0]['metadata']['labels']
- block:
- include_tasks: init.yml
- include_tasks: init.yml
- include_tasks: postgres.yml
- include_tasks: postgres.yml
- include_tasks: awx-cro.yml
- include_tasks: awx-cro.yml
- include_tasks: secrets.yml
- include_tasks: secrets.yml
- name: Set flag signifying this backup was successful
set_fact:
backup_complete: true
- name: Set flag signifying this backup was successful
set_fact:
backup_complete: true
- include_tasks: cleanup.yml
- include_tasks: cleanup.yml
when:
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
- name: Update status variables
include_tasks: update_status.yml

View File

@@ -50,7 +50,7 @@
- name: Determine the timestamp for the backup once for all nodes
set_fact:
now: '{{ lookup("pipe", "date +%F-%T") }}'
now: '{{ lookup("pipe", "date +%F-%H%M%S") }}'
- name: Set backup directory name
set_fact:

View File

@@ -42,9 +42,9 @@
no_log: "{{ no_log }}"
- name: Write postgres configuration to pvc
k8s_exec:
k8s_cp:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
command: >-
bash -c "echo '{{ secrets | to_yaml }}' > {{ backup_dir }}/secrets.yml"
remote_path: "{{ backup_dir }}/secrets.yml"
content: "{{ secrets | to_yaml }}"
no_log: "{{ no_log }}"

View File

@@ -6,11 +6,7 @@ metadata:
namespace: {{ backup_pvc_namespace }}
ownerReferences: null
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
spec:
accessModes:
- ReadWriteOnce

View File

@@ -5,11 +5,7 @@ metadata:
name: {{ ansible_operator_meta.name }}-db-management
namespace: {{ backup_pvc_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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
spec:
containers:
- name: {{ ansible_operator_meta.name }}-db-management

View File

@@ -0,0 +1,3 @@
{% for item in additional_labels_items | default([]) %}
{{ item.key }}: '{{ item.value }}'
{% endfor %}

View File

@@ -4,3 +4,4 @@ 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") }}'
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") }}

View File

@@ -40,7 +40,9 @@ loadbalancer_protocol: 'http'
loadbalancer_port: '80'
service_annotations: ''
nodeport_port: '30080'
# Port to be used for NodePort configuration, default is to auto-assign a port between 30000-32768
#nodeport_port: '30080'
# The TLS termination mechanism to use to access
# the services. Supported mechanism are: edge, passthrough
#
@@ -303,6 +305,9 @@ no_log: true
#
auto_upgrade: true
# Labels defined on the resource, which should be propagated to child resources
additional_labels: []
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
set_self_labels: true

View File

@@ -0,0 +1,66 @@
# file, which when exists, indicates that `master` script has successfully
# completed pre-stop script execution
marker_file="${PRE_STOP_MARKER_FILE:-/var/lib/pre-stop/.termination_marker}"
# file which the running `master` script continuously updates (mtime) to
# indicate it's still running. this file is then read by `watcher`s to
# understand if they still have to wait for `termination_marker`
heartbeat_file="${PRE_STOP_HEARTBEAT_FILE:-/var/lib/pre-stop/.heartbeat}"
# file which:
# * `watcher`s create when they bail out because they didn't see the
# `heartbeat_file` to be updated within `$heartbeat_failed_threshold`;
# * `master` creates when its handler command fails;
# when scripts see such file, they also give up
bailout_file="${PRE_STOP_BAILOUT_FILE:-/var/lib/pre-stop/.bailout}"
heartbeat_threshold="${PRE_STOP_HEARTBEAT_THRESHOLD:-60}"
# where the scripts' stdout/stderr are streamed
stdout="${PRE_STOP_STDOUT:-/proc/1/fd/1}"
stderr="${PRE_STOP_STDERR:-/proc/1/fd/2}"
# command the `master` script executes, which when successfully finishes,
# causes the script to create the `marker_file`
handler="${PRE_STOP_HANDLER:-bash -c \"PYTHONUNBUFFERED=x awx-manage disable_instance --wait --retry=inf\"}"
log_prefix="${PRE_STOP_LOG_PREFIX:-preStop.exec}"
[[ -n ${PRE_STOP_LOG_ROLE} ]] && log_prefix="${log_prefix}] [$PRE_STOP_LOG_ROLE"
# interval at which `watcher`s check for `marker_file` presence
recheck_sleep="${PRE_STOP_RECHECK_SLEEP:-1}"
# interval at which `watcher`s report into $stdout that they are still watching
report_every="${PRE_STOP_REPORT_EVERY:-30}"
function log {
printf "[%s] $1\n" "$log_prefix" "${@:2}"
}
function parameters_string {
for param in "$@"; do
printf "%s=\"%s\"\n" "$param" "${!param}"
done | paste -s -d ' '
}
function check_bailout {
if [[ -f $bailout_file ]]; then
log "\"%s\" file has been detected, accepting bail out signal and failing the hook script" \
"$bailout_file"
exit 1
fi
}
function check_heartbeat {
if [[ -f $heartbeat_file ]]; then
delta=$(( $(date +%s) - $(stat -c %Y "$heartbeat_file") ))
else
delta=$(( $(date +%s) - $1 ))
fi
if [[ $delta -gt $heartbeat_threshold ]]; then
log "The heartbeat file hasn't been updated since %ss, which is above the threshold of %ds, assuming the master is not operating and failing the hook script" \
$delta
$heartbeat_threshold
touch "$bailout_file"
exit 1
fi
}

View File

@@ -0,0 +1,50 @@
#/usr/bin/env bash
PRE_STOP_LOG_ROLE="${PRE_STOP_LOG_ROLE:-master}"
source $(dirname "$0")/termination-env
{
log "The hook has started: %s" \
"$(parameters_string \
"marker_file" \
"heartbeat_file" \
"bailout_file" \
"handler" \
)"
touch "$heartbeat_file"
set -o pipefail
eval "$handler" 2>&1 | while IFS= read -r line; do
# we check the files here and break early, but overall script termination
# happens later - as we need to distinguish between files detection and
# command failure, while bash doesn't offer a simple way to do this here
# inside the loop (`exit` does not terminate the script)
[[ -f $bailout_file ]] && break
[[ -f $marker_file ]] && break
log "[handler] %s" "$line"
touch "$heartbeat_file"
done
ec=$?
set +o pipefail
# process various cases in specific order
check_bailout
if [[ -f $marker_file ]]; then
log "Done! The marker file has been detected, assuming some other instance of the script has run to completion"
exit 0
elif [[ $ec -ne 0 ]]; then
log "The handler has failed with \"%d\" exit code, failing the hook script too" \
$ec
# signal others to bail out
touch "$bailout_file"
exit $ec
else
log "Done! Generating the marker file allowing to proceed to termination"
touch "$marker_file"
fi
} > "$stdout" 2> "$stderr"

View File

@@ -0,0 +1,33 @@
#/usr/bin/env bash
PRE_STOP_LOG_ROLE="${PRE_STOP_LOG_ROLE:-waiter}"
source $(dirname "$0")/termination-env
{
log "The hook has started: %s" \
"$(parameters_string \
"marker_file" \
"heartbeat_file" \
"bailout_file" \
"recheck_sleep" \
"report_every" \
)"
n=0
checks_started=$(date +%s)
while ! [[ -f $marker_file ]]; do
check_bailout
check_heartbeat $checks_started
if [[ $(($n % $report_every)) -eq 0 ]]; then
log "Waiting for the marker file to be accessible..."
fi
n=$(($n + 1))
sleep $recheck_sleep
done
log "The marker file found, exiting to proceed to termination"
} > "$stdout" 2> "$stderr"

View File

@@ -10,26 +10,46 @@
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels: '{{ lookup("template", "labels/common.yaml.j2") | from_yaml }}'
labels: '{{ lookup("template", "../common/templates/labels/common.yaml.j2") | from_yaml }}'
when: set_self_labels | bool
- name: Build `additional_labels_items` labels from `additional_labels`
block:
- 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: Select resource labels which are in `additional_labels`
set_fact:
additional_labels_items: >-
{{ this_awx['resources'][0]['metadata']['labels']
| dict2items | selectattr('key', 'in', additional_labels)
| list
}}
when: this_awx['resources'][0]['metadata']['labels']
when: additional_labels | length
- 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 != ''
- ldap_cacert_secret != ''
- name: Load ldap bind password
include_tasks: load_ldap_password_secret.yml
when:
- ldap_password_secret != ''
- ldap_password_secret != ''
- name: Load bundle certificate authority certificate
include_tasks: load_bundle_cacert_secret.yml
when:
- bundle_cacert_secret != ''
- bundle_cacert_secret != ''
- name: Include admin password configuration tasks
include_tasks: admin_password_configuration.yml
@@ -46,8 +66,8 @@
- name: Load Route TLS certificate
include_tasks: load_route_tls_secret.yml
when:
- ingress_type | lower == 'route'
- route_tls_secret != ''
- ingress_type | lower == 'route'
- route_tls_secret != ''
- name: Include resources configuration tasks
include_tasks: resources_configuration.yml
@@ -71,8 +91,8 @@
bash -c "awx-manage migrate --noinput"
register: migrate_result
when:
- database_check is defined
- (database_check.stdout|trim) != '0'
- database_check is defined
- (database_check.stdout|trim) != '0'
- name: Initialize Django
include_tasks: initialize_django.yml

View File

@@ -1,7 +1,7 @@
---
- name: Check for presence of Deployment
k8s_info:
api_version: v1
api_version: apps/v1
kind: Deployment
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"

View File

@@ -13,9 +13,17 @@
- status.phase=Running
register: tower_pod
- name: Set the resource pod as a variable.
set_fact:
tower_pod: >-
{{ tower_pod['resources']
| rejectattr('metadata.deletionTimestamp', 'defined')
| sort(attribute='metadata.creationTimestamp')
| first | default({}) }}
- name: Set the resource pod name as a variable.
set_fact:
tower_pod_name: "{{ tower_pod['resources'][0]['metadata']['name'] | default('') }}"
tower_pod_name: "{{ tower_pod['metadata']['name'] | default('') }}"
- name: Set user provided control plane ee image
set_fact:
@@ -32,13 +40,13 @@
kind: Secret
namespace: '{{ ansible_operator_meta.namespace }}'
name: '{{ ansible_operator_meta.name }}-receptor-ca'
register: _receptor_ca
register: receptor_ca
no_log: "{{ no_log }}"
- name: Migrate Receptor CA Secret
when:
- _receptor_ca['resources'] | default([]) | length
- _receptor_ca['resources'][0]['type'] != "kubernetes.io/tls"
- receptor_ca['resources'] | default([]) | length
- receptor_ca['resources'][0]['type'] != "kubernetes.io/tls"
block:
- name: Delete old Receptor CA Secret
k8s:
@@ -53,7 +61,7 @@
register: _receptor_ca_key_file
- name: Copy Receptor CA key from old secret to tempfile
copy:
content: "{{ _receptor_ca['resources'][0]['data']['receptor-ca.key'] | b64decode }}"
content: "{{ receptor_ca['resources'][0]['data']['receptor-ca.key'] | b64decode }}"
dest: "{{ _receptor_ca_key_file.path }}"
no_log: "{{ no_log }}"
- name: Create tempfile for receptor-ca.crt
@@ -63,7 +71,7 @@
register: _receptor_ca_crt_file
- name: Copy Receptor CA cert from old secret to tempfile
copy:
content: "{{ _receptor_ca['resources'][0]['data']['receptor-ca.crt'] | b64decode }}"
content: "{{ receptor_ca['resources'][0]['data']['receptor-ca.crt'] | b64decode }}"
dest: "{{ _receptor_ca_crt_file.path }}"
no_log: "{{ no_log }}"
- name: Create New Receptor CA secret
@@ -71,6 +79,17 @@
apply: true
definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}"
no_log: "{{ no_log }}"
- name: Read New Receptor CA Secret
k8s_info:
kind: Secret
namespace: '{{ ansible_operator_meta.namespace }}'
name: '{{ ansible_operator_meta.name }}-receptor-ca'
register: _receptor_ca
no_log: "{{ no_log }}"
- name: Set receptor_ca variable
set_fact:
receptor_ca: '{{ _receptor_ca }}'
no_log: "{{ no_log }}"
- name: Remove tempfiles
file:
path: "{{ item }}"
@@ -106,6 +125,17 @@
apply: true
definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}"
no_log: "{{ no_log }}"
- name: Read Receptor CA secret
k8s_info:
kind: Secret
namespace: '{{ ansible_operator_meta.namespace }}'
name: '{{ ansible_operator_meta.name }}-receptor-ca'
register: _receptor_ca
no_log: "{{ no_log }}"
- name: Set receptor_ca variable
set_fact:
receptor_ca: '{{ _receptor_ca }}'
no_log: "{{ no_log }}"
- name: Remove tempfiles
file:
path: "{{ item }}"
@@ -113,14 +143,14 @@
loop:
- "{{ _receptor_ca_key_file.path }}"
- "{{ _receptor_ca_crt_file.path }}"
when: not _receptor_ca['resources'] | default([]) | length
when: not receptor_ca['resources'] | default([]) | length
- name: Check for Receptor work signing Secret
k8s_info:
kind: Secret
namespace: '{{ ansible_operator_meta.namespace }}'
name: '{{ ansible_operator_meta.name }}-receptor-work-signing'
register: _receptor_work_signing
register: receptor_work_signing
no_log: "{{ no_log }}"
- name: Generate Receptor work signing RSA key pair
@@ -151,6 +181,17 @@
apply: true
definition: "{{ lookup('template', 'secrets/receptor_work_signing_secret.yaml.j2') }}"
no_log: "{{ no_log }}"
- name: Read Receptor work signing Secret
k8s_info:
kind: Secret
namespace: '{{ ansible_operator_meta.namespace }}'
name: '{{ ansible_operator_meta.name }}-receptor-work-signing'
register: _receptor_work_signing
no_log: "{{ no_log }}"
- name: Set receptor_work_signing variable
set_fact:
receptor_work_signing: '{{ _receptor_work_signing }}'
no_log: "{{ no_log }}"
- name: Remove tempfiles
file:
path: "{{ item }}"
@@ -158,16 +199,16 @@
loop:
- "{{ _receptor_work_signing_private_key_file.path }}"
- "{{ _receptor_work_signing_public_key_file.path }}"
when: not _receptor_work_signing['resources'] | default([]) | length
when: not receptor_work_signing['resources'] | default([]) | length
- name: Apply Resources
k8s:
apply: yes
definition: "{{ lookup('template', item + '.yaml.j2') }}"
wait: yes
register: tower_resources_result
loop:
- 'configmaps/config'
- 'configmaps/pre_stop_scripts'
- 'secrets/app_credentials'
- 'rbac/service_account'
- 'storage/persistent'
@@ -210,21 +251,10 @@
apply: yes
definition: "{{ lookup('template', 'deployments/deployment.yaml.j2') }}"
wait: yes
wait_timeout: "{{ 120 * replicas or 120 }}"
register: this_deployment_result
- block:
- name: Delete pod to reload a resource configuration
k8s:
api_version: v1
state: absent
kind: Pod
namespace: '{{ ansible_operator_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
@@ -236,17 +266,20 @@
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 as a variable.
set_fact:
tower_pod: >-
{{ _new_pod['resources']
| rejectattr('metadata.deletionTimestamp', 'defined')
| sort(attribute='metadata.creationTimestamp')
| last | default({}) }}
- name: Update new resource pod name as a variable.
set_fact:
tower_pod_name: '{{ _new_pod["resources"][0]["metadata"]["name"] }}'
tower_pod_name: '{{ tower_pod["metadata"]["name"] | default("")}}'
when:
- tower_resources_result.changed or this_deployment_result.changed
- this_deployment_result.changed
- name: Verify the resource pod name is populated.
assert:

View File

@@ -2,7 +2,7 @@
- name: Check for presence of Deployment
k8s_info:
api_version: v1
api_version: apps/v1
kind: Deployment
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
@@ -10,7 +10,7 @@
- name: Scale down Deployment for migration
kubernetes.core.k8s_scale:
api_version: v1
api_version: apps/v1
kind: Deployment
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"

View File

@@ -40,10 +40,10 @@
- name: Set secret key secret
set_fact:
__secret_key_secret: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}'
secret_key: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}'
no_log: "{{ no_log }}"
- name: Store secret key secret name
set_fact:
secret_key_secret_name: "{{ __secret_key_secret['resources'][0]['metadata']['name'] }}"
secret_key_secret_name: "{{ secret_key['resources'][0]['metadata']['name'] }}"
no_log: "{{ no_log }}"

View File

@@ -17,3 +17,20 @@
{{ _custom_init_container_image |
default(lookup('env', 'RELATED_IMAGE_AWX_INIT_CONTAINER')) |
default(_default_init_container_image, true) }}
- name: Set default awx init projects container image
set_fact:
_default_init_projects_container_image: "{{ _init_projects_container_image }}"
- name: Set user provided awx init projects image
set_fact:
_custom_init_projects_container_image: "{{ init_projects_container_image }}"
when:
- init_projects_container_image | default([]) | length
- name: Set Init projects image URL
set_fact:
_init_projects_container_image: >-
{{ _custom_init_projects_container_image |
default(lookup('env', 'RELATED_IMAGE_AWX_INIT_PROJECTS_CONTAINER')) |
default(_default_init_projects_container_image, true) }}

View File

@@ -6,11 +6,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-{{ deployment_type }}-configmap'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
data:
environment: |
AWX_SKIP_MIGRATIONS=true
@@ -104,6 +100,7 @@ data:
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
client_max_body_size 5M;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
@@ -272,6 +269,7 @@ data:
key: /etc/receptor/tls/receptor.key
name: tlsclient
rootcas: /etc/receptor/tls/ca/receptor-ca.crt
mintls13: false
- work-signing:
privatekey: /etc/receptor/signing/work-private-key.pem
tokenexpiration: 1m

View File

@@ -0,0 +1,16 @@
{% if termination_grace_period_seconds is defined %}
apiVersion: v1
kind: ConfigMap
metadata:
name: '{{ ansible_operator_meta.name }}-{{ deployment_type }}-pre-stop-scripts'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
data:
termination-master: |
{{ lookup("file", "files/pre-stop/termination-master") | indent(width=4) | trim }}
termination-waiter: |
{{ lookup("file", "files/pre-stop/termination-waiter") | indent(width=4) | trim }}
termination-env: |
{{ lookup("file", "files/pre-stop/termination-env") | indent(width=4) | trim }}
{% endif %}

View File

@@ -6,8 +6,8 @@ metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
{{ lookup("template", "labels/common.yaml.j2") | indent(width=4) | trim }}
{{ lookup("template", "labels/version.yaml.j2") | indent(width=4) | trim }}
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
{{ lookup("template", "../common/templates/labels/version.yaml.j2") | indent(width=4) | trim }}
spec:
replicas: {{ replicas }}
selector:
@@ -18,10 +18,28 @@ spec:
template:
metadata:
labels:
{{ lookup("template", "labels/common.yaml.j2") | indent(width=8) | trim }}
{{ lookup("template", "labels/version.yaml.j2") | indent(width=8) | trim }}
{% if annotations %}
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=8) | trim }}
{{ lookup("template", "../common/templates/labels/version.yaml.j2") | indent(width=8) | trim }}
annotations:
{% for template in [
"configmaps/config",
"configmaps/pre_stop_scripts",
"secrets/app_credentials",
"storage/persistent",
] %}
checksum-{{ template | replace('/', '-') }}: "{{ lookup('template', template + '.yaml.j2') | sha1 }}"
{% endfor %}
{% for secret in [
"bundle_cacert",
"route_tls",
"ldap_cacert",
"secret_key",
"receptor_ca",
"receptor_work_signing",
] %}
checksum-secret-{{ secret }}: "{{ lookup('ansible.builtin.vars', secret, default='')["resources"][0]["data"] | default('') | sha1 }}"
{% endfor %}
{% if annotations %}
{{ annotations | indent(width=8) }}
{% endif %}
spec:
@@ -122,6 +140,23 @@ spec:
mountPath: "/var/run/redis"
- name: "{{ ansible_operator_meta.name }}-redis-data"
mountPath: "/data"
{% if termination_grace_period_seconds is defined %}
- name: pre-stop-data
mountPath: /var/lib/pre-stop
- name: pre-stop-scripts
mountPath: /var/lib/pre-stop/scripts
lifecycle:
preStop:
exec:
command:
- bash
- -c
# redis image doesn't support writing to `/proc/1/fd/*`
- >
PRE_STOP_STDOUT=/dev/stdout
PRE_STOP_STDERR=/dev/stderr
/var/lib/pre-stop/scripts/termination-waiter
{% endif %}
resources: {{ redis_resource_requirements }}
- image: '{{ _image }}'
name: '{{ ansible_operator_meta.name }}-web'
@@ -291,6 +326,18 @@ spec:
{% endif %}
{% if task_extra_volume_mounts -%}
{{ task_extra_volume_mounts | indent(width=12, first=True) }}
{% endif %}
{% if termination_grace_period_seconds is defined %}
- name: pre-stop-data
mountPath: /var/lib/pre-stop
- name: pre-stop-scripts
mountPath: /var/lib/pre-stop/scripts
lifecycle:
preStop:
exec:
command:
- bash
- /var/lib/pre-stop/scripts/termination-master
{% endif %}
env:
- name: SUPERVISOR_WEB_CONFIG_PATH
@@ -360,6 +407,18 @@ spec:
mountPath: "/var/lib/awx/projects"
{% if ee_extra_volume_mounts -%}
{{ ee_extra_volume_mounts | indent(width=12, first=True) }}
{% endif %}
{% if termination_grace_period_seconds is defined %}
- name: pre-stop-data
mountPath: /var/lib/pre-stop
- name: pre-stop-scripts
mountPath: /var/lib/pre-stop/scripts
lifecycle:
preStop:
exec:
command:
- bash
- /var/lib/pre-stop/scripts/termination-waiter
{% endif %}
env:
{% if development_mode | bool %}
@@ -395,6 +454,9 @@ spec:
{% if security_context_settings|length %}
{{ security_context_settings | to_nice_yaml | indent(8) }}
{% endif %}
{% endif %}
{% if termination_grace_period_seconds is defined %}
terminationGracePeriodSeconds: {{ termination_grace_period_seconds }}
{% endif %}
volumes:
{% if bundle_ca_crt %}
@@ -424,6 +486,14 @@ spec:
items:
- key: ldap-ca.crt
path: 'ldap-ca.crt'
{% endif %}
{% if termination_grace_period_seconds is defined %}
- name: pre-stop-data
emptyDir: {}
- name: pre-stop-scripts
configMap:
name: '{{ ansible_operator_meta.name }}-{{ deployment_type }}-pre-stop-scripts'
defaultMode: 0775
{% endif %}
- name: "{{ ansible_operator_meta.name }}-application-credentials"
secret:

View File

@@ -8,11 +8,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-ingress'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
{% if ingress_annotations %}
annotations:
{{ ingress_annotations | indent(width=4) }}
@@ -52,11 +48,7 @@ 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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
spec:
{% if route_host != '' %}
host: {{ route_host }}

View File

@@ -5,11 +5,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-service'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
{{ service_labels | indent(width=4) }}
{% if service_annotations %}
annotations:
@@ -23,7 +19,9 @@ spec:
protocol: TCP
targetPort: 8052
name: http
{% if nodeport_port is defined %}
nodePort: {{ nodeport_port }}
{% endif %}
{% elif service_type | lower != 'loadbalancer' and loadbalancer_protocol | lower != 'https' %}
- port: 80
protocol: TCP
@@ -55,6 +53,9 @@ spec:
type: NodePort
{% elif service_type | lower == "loadbalancer" %}
type: LoadBalancer
{% if variable is defined and variable|length %}
loadbalancerip: '{{ loadbalancer_ip }}'
{% endif %}
{% else %}
type: ClusterIP
{% endif %}

View File

@@ -5,11 +5,7 @@ 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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
{% if service_account_annotations %}
annotations:
{{ service_account_annotations | indent(width=4) }}
@@ -20,6 +16,8 @@ kind: Role
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
@@ -40,6 +38,8 @@ apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
subjects:
- kind: ServiceAccount
name: '{{ ansible_operator_meta.name }}'

View File

@@ -5,10 +5,6 @@ metadata:
name: '{{ ansible_operator_meta.name }}-admin-password'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
stringData:
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -6,11 +6,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-app-credentials'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
data:
credentials.py: "{{ lookup('template', 'settings/credentials.py.j2') | b64encode }}"
ldap.py: "{{ lookup('template', 'settings/ldap.py.j2') | b64encode }}"

View File

@@ -5,10 +5,6 @@ metadata:
name: '{{ ansible_operator_meta.name }}-broadcast-websocket'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
stringData:
secret: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -6,11 +6,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-postgres-configuration'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
stringData:
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
username: '{{ database_username }}'

View File

@@ -6,11 +6,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-postgres-configuration'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
stringData:
password: '{{ awx_postgres_pass }}'
username: '{{ awx_postgres_user }}'

View File

@@ -5,11 +5,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-receptor-ca'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
type: kubernetes.io/tls
data:
tls.crt: '{{ lookup('file', '{{ _receptor_ca_crt_file.path }}') | b64encode }}'

View File

@@ -5,11 +5,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-receptor-work-signing'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
data:
work-private-key.pem: '{{ lookup('file', '{{ _receptor_work_signing_private_key_file.path }}') | b64encode }}'
work-public-key.pem: '{{ lookup('file', '{{ _receptor_work_signing_public_key_file.path }}') | b64encode }}'

View File

@@ -5,10 +5,6 @@ metadata:
name: '{{ ansible_operator_meta.name }}-secret-key'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
stringData:
secret_key: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'

View File

@@ -6,6 +6,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") | indent(width=4) | trim }}
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'
@@ -27,6 +28,7 @@ spec:
template:
metadata:
labels:
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") | indent(width=8) | trim }}
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'
@@ -127,6 +129,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") | indent(width=4) | trim }}
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'

View File

@@ -5,11 +5,7 @@ metadata:
name: '{{ ansible_operator_meta.name }}-projects-claim'
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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
spec:
accessModes:
- {{ projects_storage_access_mode }}

View File

@@ -26,6 +26,9 @@ restore_resource_requirements:
cpu: "25m"
memory: "32Mi"
# Labels defined on the resource, which should be propagated to child resources
additional_labels: []
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
set_self_labels: true
...

View File

@@ -24,7 +24,8 @@ galaxy_info:
- restore
- automation
dependencies: []
dependencies:
- role: common
collections:
- kubernetes.core

View File

@@ -2,24 +2,19 @@
- name: Import awx_object variables
block:
- name: Get AWX object definition from pvc
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
command: >-
bash -c "cat '{{ backup_dir }}/awx_object'"
register: awx_object
- name: Create temp file for spec dict
tempfile:
state: file
register: tmp_spec
- name: Write spec vars to temp file
copy:
content: "{{ awx_object.stdout }}"
dest: "{{ tmp_spec.path }}"
mode: '0644'
- name: Get AWX object definition from pvc
k8s_cp:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
remote_path: "{{ backup_dir }}/awx_object"
local_path: "{{ tmp_spec.path }}"
state: from_pod
- name: Include spec vars to save them as a dict
include_vars: "{{ tmp_spec.path }}"

View File

@@ -10,12 +10,7 @@
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") }}'
labels: '{{ lookup("template", "../common/templates/labels/common.yaml.j2") | from_yaml }}'
when: set_self_labels | bool
- name: Look up details for this restore object
@@ -26,25 +21,35 @@
namespace: "{{ ansible_operator_meta.namespace }}"
register: this_restore
- name: Build `additional_labels_items` labels from `additional_labels`
set_fact:
additional_labels_items: >-
{{ this_restore['resources'][0]['metadata']['labels']
| dict2items | selectattr('key', 'in', additional_labels)
}}
when:
- additional_labels | length
- this_restore['resources'][0]['metadata']['labels']
- block:
- include_tasks: init.yml
- include_tasks: init.yml
- include_tasks: import_vars.yml
- include_tasks: import_vars.yml
- include_tasks: secrets.yml
- include_tasks: secrets.yml
- include_tasks: deploy_awx.yml
- include_tasks: deploy_awx.yml
- include_tasks: postgres.yml
- include_tasks: postgres.yml
- name: Set flag signifying this restore was successful
set_fact:
tower_restore_complete: True
- name: Set flag signifying this restore was successful
set_fact:
tower_restore_complete: True
- include_tasks: cleanup.yml
- include_tasks: cleanup.yml
when:
- this_restore['resources'][0]['status']['restoreComplete'] is not defined
- this_restore['resources'][0]['status']['restoreComplete'] is not defined
- name: Update status variables
include_tasks: update_status.yml

View File

@@ -48,7 +48,7 @@
- name: Check for presence of AWX Deployment
k8s_info:
api_version: v1
api_version: apps/v1
kind: Deployment
name: "{{ deployment_name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
@@ -56,7 +56,7 @@
- name: Scale down Deployment for migration
k8s_scale:
api_version: v1
api_version: apps/v1
kind: Deployment
name: "{{ deployment_name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
@@ -66,9 +66,8 @@
- name: Set full resolvable host name for postgres pod
set_fact:
resolvable_db_host: "{{ awx_postgres_host }}.{{ ansible_operator_meta.namespace }}.svc.{{ cluster_name }}"
resolvable_db_host: '{{ (awx_postgres_type == "managed") | ternary(awx_postgres_host + "." + ansible_operator_meta.namespace + ".svc." + cluster_name, awx_postgres_host) }}' # yamllint disable-line rule:line-length
no_log: "{{ no_log }}"
when: awx_postgres_type == 'managed'
- name: Set pg_restore command
set_fact:

View File

@@ -1,25 +1,18 @@
---
- name: Get secret definition from pvc
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
command: >-
bash -c "cat '{{ backup_dir }}/secrets.yml'"
register: _secrets
no_log: "{{ no_log }}"
- name: Create Temporary secrets file
tempfile:
state: file
suffix: .json
register: tmp_secrets
- name: Write vars to file locally
copy:
dest: "{{ tmp_secrets.path }}"
content: "{{ _secrets.stdout }}"
mode: 0640
- name: Get secret definition from pvc
k8s_cp:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
remote_path: "{{ backup_dir }}/secrets.yml"
local_path: "{{ tmp_secrets.path }}"
state: from_pod
no_log: "{{ no_log }}"
- name: Include secret vars from backup

View File

@@ -5,11 +5,7 @@ metadata:
name: {{ ansible_operator_meta.name }}-db-management
namespace: {{ backup_pvc_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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
spec:
containers:
- name: {{ ansible_operator_meta.name }}-db-management

View File

@@ -6,11 +6,7 @@ metadata:
name: '{{ secrets[secret]['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") }}'
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
type: '{{ secrets[secret]['type'] }}'
stringData:
{% for key, value in secrets[secret]['data'].items() %}