mirror of
https://github.com/ansible/awx-operator.git
synced 2026-03-27 05:43:11 +00:00
Compare commits
174 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a6040e0cd | ||
|
|
24f3f440f1 | ||
|
|
87b0511997 | ||
|
|
fde4a47a14 | ||
|
|
af2e681f1e | ||
|
|
82ffa3d348 | ||
|
|
db6a5b53ed | ||
|
|
0be17476cd | ||
|
|
f4a781ccc5 | ||
|
|
fcd2c4c023 | ||
|
|
8e30a17a77 | ||
|
|
b3037c1067 | ||
|
|
f7ff132a2e | ||
|
|
5f06e90906 | ||
|
|
36355b6a15 | ||
|
|
bc08c4bbbe | ||
|
|
7697825944 | ||
|
|
8a325293b1 | ||
|
|
dd53a1d415 | ||
|
|
c5db0e7104 | ||
|
|
59036fc373 | ||
|
|
c45a7bd4d7 | ||
|
|
34b6354001 | ||
|
|
801f392447 | ||
|
|
779572e8ff | ||
|
|
e7e48f92a0 | ||
|
|
3cd9ddd8c6 | ||
|
|
4e6be0a82c | ||
|
|
05943687fe | ||
|
|
9676ebc008 | ||
|
|
8352237260 | ||
|
|
35d4954027 | ||
|
|
4d6a491766 | ||
|
|
fa9eb53f92 | ||
|
|
00c9f5fbd1 | ||
|
|
fe82e9259e | ||
|
|
635d530dc9 | ||
|
|
e966e9299f | ||
|
|
683d23dbea | ||
|
|
8b3a297086 | ||
|
|
15830e3536 | ||
|
|
ef46d7f49c | ||
|
|
a5328b1a09 | ||
|
|
0983220fba | ||
|
|
3ac0232e89 | ||
|
|
75c7231afd | ||
|
|
363aa3642b | ||
|
|
bf74d5cc34 | ||
|
|
46586bd7b6 | ||
|
|
191be7bf3c | ||
|
|
b7e5f235ad | ||
|
|
6cbc6a7234 | ||
|
|
beba6a900d | ||
|
|
7f72260445 | ||
|
|
5b7baa106d | ||
|
|
9380686395 | ||
|
|
0de966153d | ||
|
|
efaa4718ec | ||
|
|
e6a473b765 | ||
|
|
859384e9f6 | ||
|
|
b66a16508f | ||
|
|
3da427f31d | ||
|
|
9f2b51a6a9 | ||
|
|
5b73ad172e | ||
|
|
2227301707 | ||
|
|
9f63fc0da5 | ||
|
|
322aea970d | ||
|
|
c4bef95662 | ||
|
|
fa705f6466 | ||
|
|
7fd5083c16 | ||
|
|
daf15a93bf | ||
|
|
dfa0f6d45e | ||
|
|
21062f0708 | ||
|
|
5372771bac | ||
|
|
8df0969e6a | ||
|
|
5af7e7f4b9 | ||
|
|
d8f91d112e | ||
|
|
379552218d | ||
|
|
1686875321 | ||
|
|
1b41d945e6 | ||
|
|
5e81729bc9 | ||
|
|
575e594314 | ||
|
|
5f76d4917e | ||
|
|
94c5c41a24 | ||
|
|
ee84625107 | ||
|
|
add76c159b | ||
|
|
375031e1f8 | ||
|
|
ca6ab0a380 | ||
|
|
236bce6970 | ||
|
|
0a9e9722c5 | ||
|
|
58ac0cc369 | ||
|
|
c3ac2e2cde | ||
|
|
589a3751e1 | ||
|
|
12a58d71fb | ||
|
|
6b873b05ab | ||
|
|
5e97ff7c08 | ||
|
|
86c31a4317 | ||
|
|
487727b454 | ||
|
|
2f47b907fd | ||
|
|
dbaf64efa0 | ||
|
|
5375fec77d | ||
|
|
9980192d9e | ||
|
|
e2fc5f46c0 | ||
|
|
5b3be06e8d | ||
|
|
3c2405f304 | ||
|
|
192611eea8 | ||
|
|
9ca14cef93 | ||
|
|
fbc2d3475c | ||
|
|
58f30fb96c | ||
|
|
c81b78aad6 | ||
|
|
c02e05925e | ||
|
|
479c009716 | ||
|
|
7807bc516e | ||
|
|
3afcd7fd89 | ||
|
|
7002131dda | ||
|
|
877943cc27 | ||
|
|
b59a0c5b80 | ||
|
|
26b1eb6c87 | ||
|
|
39437da72b | ||
|
|
e1645a2f8d | ||
|
|
224dde769a | ||
|
|
536d7dc842 | ||
|
|
eac2328bd3 | ||
|
|
3be986c96c | ||
|
|
768bc2f857 | ||
|
|
f05faaaaa0 | ||
|
|
957566993b | ||
|
|
c95f3299b0 | ||
|
|
1a0e3cf410 | ||
|
|
9368b43614 | ||
|
|
108addc06e | ||
|
|
3a3260ffb7 | ||
|
|
960d1f8a32 | ||
|
|
4d8f84eb74 | ||
|
|
1320c9d175 | ||
|
|
fab71e054e | ||
|
|
3eede3c922 | ||
|
|
d27ce3c34d | ||
|
|
18d17f2485 | ||
|
|
47d3ef57f2 | ||
|
|
8f8336b25a | ||
|
|
4aeeb8db82 | ||
|
|
5b636bb8ea | ||
|
|
83939ec007 | ||
|
|
608478e249 | ||
|
|
cb9e44fd4f | ||
|
|
cbd7da9dcf | ||
|
|
0f07a475b5 | ||
|
|
a2222a9176 | ||
|
|
79152d2417 | ||
|
|
fdbe607189 | ||
|
|
4a43de5101 | ||
|
|
345738cba3 | ||
|
|
f4995afb39 | ||
|
|
35062157e0 | ||
|
|
3150d55af6 | ||
|
|
4c51ee28f5 | ||
|
|
fbd5803f10 | ||
|
|
8972cae1cc | ||
|
|
1d8b3d9b4c | ||
|
|
57aa585a2e | ||
|
|
752813c23e | ||
|
|
48ee59e80f | ||
|
|
78fc099c75 | ||
|
|
5b577603c8 | ||
|
|
e5cfac2ba0 | ||
|
|
5ca536313a | ||
|
|
eaaf55e7f0 | ||
|
|
5d934ff2b5 | ||
|
|
84ab70f779 | ||
|
|
c843194cbd | ||
|
|
b0824acc48 | ||
|
|
782f97c42c | ||
|
|
38ec4a3b00 |
3
.github/CODE_OF_CONDUCT.md
vendored
Normal file
3
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Community Code of Conduct
|
||||
|
||||
Please see the official [Ansible Community Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
|
||||
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,39 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
##### ISSUE TYPE
|
||||
- Bug Report
|
||||
|
||||
##### SUMMARY
|
||||
<!-- Briefly describe the problem. -->
|
||||
|
||||
##### ENVIRONMENT
|
||||
* AWX version: X.Y.Z
|
||||
* Operator version: X.Y.Z
|
||||
* Kubernetes version:
|
||||
* AWX install method: openshift, minishift, docker on linux, docker for mac, boot2docker
|
||||
|
||||
##### STEPS TO REPRODUCE
|
||||
|
||||
<!-- Please describe exactly how to reproduce the problem. -->
|
||||
|
||||
##### EXPECTED RESULTS
|
||||
|
||||
<!-- What did you expect to happen when running the steps above? -->
|
||||
|
||||
##### ACTUAL RESULTS
|
||||
|
||||
<!-- What actually happened? -->
|
||||
|
||||
##### ADDITIONAL INFORMATION
|
||||
|
||||
<!-- Include any links to sosreport, database dumps, screenshots or other
|
||||
information. -->
|
||||
|
||||
##### AWX-OPERATOR LOGS
|
||||
125
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
125
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
name: Bug Report
|
||||
description: "🐞 Create a report to help us improve"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Bug Report issues are for **concrete, actionable bugs** only.
|
||||
For debugging help or technical support, please see the [Get Involved section of our README](https://github.com/ansible/awx-operator#get-involved)
|
||||
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Please confirm the following
|
||||
options:
|
||||
- label: I agree to follow this project's [code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
|
||||
required: true
|
||||
- label: I have checked the [current issues](https://github.com/ansible/awx-operator/issues) for duplicates.
|
||||
required: true
|
||||
- label: I understand that the AWX Operator is open source software provided for free and that I might not receive a timely response.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Bug Summary
|
||||
description: Briefly describe the problem.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: awx-operator-version
|
||||
attributes:
|
||||
label: AWX Operator version
|
||||
description: What version of the AWX Operator are you running?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: awx-version
|
||||
attributes:
|
||||
label: AWX version
|
||||
description: What version of AWX are you running?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: Kubernetes platform
|
||||
description: What platform did you install the Operator in?
|
||||
multiple: false
|
||||
options:
|
||||
- kubernetes
|
||||
- minikube
|
||||
- openshift
|
||||
- minishift
|
||||
- docker development environment
|
||||
- other (please specify in additional information)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: kube-version
|
||||
attributes:
|
||||
label: Kubernetes/Platform version
|
||||
description: What version of your platform/kuberneties are you using?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: modified-architecture
|
||||
attributes:
|
||||
label: Modifications
|
||||
description: >-
|
||||
Have you modified the installation, deployment topology, or container images in any way? If yes, please
|
||||
explain in the "additional information" field at the bottom of the form.
|
||||
multiple: false
|
||||
options:
|
||||
- "no"
|
||||
- "yes"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: >-
|
||||
Starting from a new installation of the system, describe exactly how a developer or quality engineer can reproduce the bug
|
||||
on infrastructure that isn't yours. Include any and all resources created, input values, test users, roles assigned, playbooks used, etc.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected-results
|
||||
attributes:
|
||||
label: Expected results
|
||||
description: What did you expect to happpen when running the steps above?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: actual-results
|
||||
attributes:
|
||||
label: Actual results
|
||||
description: What actually happened?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: additional-information
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Include any relevant log output, links to sosreport, database dumps, screenshots, AWX spec yaml, or other information.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: operator-logs
|
||||
attributes:
|
||||
label: Operator Logs
|
||||
description: Include any relevant logs generated by the operator.
|
||||
validations:
|
||||
required: false
|
||||
12
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
12
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: For debugging help or technical support
|
||||
url: https://github.com/ansible/awx-operator#get-involved
|
||||
about: For general debugging or technical support please see the Get Involved section of our readme.
|
||||
- name: 📝 Ansible Code of Conduct
|
||||
url: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_template_chooser
|
||||
about: AWX uses the Ansible Code of Conduct; ❤ Be nice to other members of the community. ☮ Behave.
|
||||
- name: 💼 For Enterprise
|
||||
url: https://www.ansible.com/products/engine?utm_medium=github&utm_source=issue_template_chooser
|
||||
about: Red Hat offers support for the Ansible Automation Platform
|
||||
29
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
29
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: ✨ Feature request
|
||||
description: Suggest an idea for this project
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Feature Request issues are for **feature requests** only.
|
||||
For debugging help or technical support, please see the [Get Involved section of our README](https://github.com/ansible/awx-operator#get-involved)
|
||||
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Please confirm the following
|
||||
options:
|
||||
- label: I agree to follow this project's [code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
|
||||
required: true
|
||||
- label: I have checked the [current issues](https://github.com/ansible/awx-operator/issues) for duplicates.
|
||||
required: true
|
||||
- label: I understand that AWX Operator is open source software provided for free and that I might not receive a timely response.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Feature Summary
|
||||
description: Briefly describe the desired enhancement.
|
||||
validations:
|
||||
required: true
|
||||
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
##### SUMMARY
|
||||
<!--- Describe the change, including rationale and design decisions -->
|
||||
|
||||
<!---
|
||||
If you are fixing an existing issue, please include "fixes #nnn" in your
|
||||
commit message and your description; but you should still explain what
|
||||
the change does.
|
||||
-->
|
||||
|
||||
##### ISSUE TYPE
|
||||
<!--- Pick one below and delete the rest: -->
|
||||
- Breaking Change
|
||||
- New or Enhanced Feature
|
||||
- Bug, Docs Fix or other nominal change
|
||||
|
||||
##### ADDITIONAL INFORMATION
|
||||
<!---
|
||||
Include additional information to help people understand the change here.
|
||||
For bugs that don't have a linked bug report, a step-by-step reproduction
|
||||
of the problem is helpful.
|
||||
-->
|
||||
|
||||
<!--- Paste verbatim command output below, e.g. before and after your change -->
|
||||
```
|
||||
|
||||
```
|
||||
3
.github/issue_labeler.yml
vendored
Normal file
3
.github/issue_labeler.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
needs_triage:
|
||||
- '.*'
|
||||
47
.github/workflows/ci.yaml
vendored
47
.github/workflows/ci.yaml
vendored
@@ -10,9 +10,9 @@ on:
|
||||
branches: [devel]
|
||||
|
||||
jobs:
|
||||
pull_request:
|
||||
molecule:
|
||||
runs-on: ubuntu-18.04
|
||||
name: pull_request
|
||||
name: molecule
|
||||
env:
|
||||
DOCKER_API_VERSION: "1.38"
|
||||
steps:
|
||||
@@ -39,3 +39,46 @@ jobs:
|
||||
sudo rm -f $(which kustomize)
|
||||
make kustomize
|
||||
KUSTOMIZE_PATH=$(readlink -f bin/kustomize) molecule test -s kind
|
||||
helm:
|
||||
runs-on: ubuntu-18.04
|
||||
name: helm
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Create k8s Kind Cluster
|
||||
uses: helm/kind-action@v1.2.0
|
||||
|
||||
- name: Build operator image and load into kind
|
||||
run: |
|
||||
IMG=awx-operator-ci make docker-build
|
||||
kind load docker-image --name chart-testing awx-operator-ci
|
||||
|
||||
- name: Patch pull policy for tests
|
||||
run: |
|
||||
kustomize edit add patch --path ../testing/pull_policy/Never.yaml
|
||||
working-directory: config/default
|
||||
|
||||
- name: Build and lint helm chart
|
||||
run: |
|
||||
IMG=awx-operator-ci make helm-chart
|
||||
helm lint ./charts/awx-operator
|
||||
|
||||
- name: Install kubeval
|
||||
run: |
|
||||
mkdir tmp && cd tmp
|
||||
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-linux-amd64.tar.gz
|
||||
tar xf kubeval-linux-amd64.tar.gz
|
||||
sudo cp kubeval /usr/local/bin
|
||||
working-directory: ./charts
|
||||
|
||||
- name: Run kubeval
|
||||
run: |
|
||||
helm template -n awx awx-operator > tmp/test.yaml
|
||||
kubeval --strict --force-color --ignore-missing-schemas tmp/test.yaml
|
||||
working-directory: ./charts
|
||||
|
||||
- name: Install helm chart
|
||||
run: |
|
||||
helm install --wait my-awx-operator --namespace awx --create-namespace ./charts/awx-operator
|
||||
|
||||
2
.github/workflows/devel.yaml
vendored
2
.github/workflows/devel.yaml
vendored
@@ -23,5 +23,5 @@ jobs:
|
||||
image: awx-operator
|
||||
tags: devel
|
||||
registry: quay.io/ansible/
|
||||
username: ${{ secrets.QUAY_USERNAME }}
|
||||
username: ${{ secrets.QUAY_USER }}
|
||||
password: ${{ secrets.QUAY_TOKEN }}
|
||||
|
||||
45
.github/workflows/pr_body_check.yml
vendored
Normal file
45
.github/workflows/pr_body_check.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: PR Check
|
||||
env:
|
||||
BRANCH: ${{ github.base_ref || 'devel' }}
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
jobs:
|
||||
pr-check:
|
||||
name: Scan PR description for semantic versioning keywords
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Write PR body to a file
|
||||
run: |
|
||||
cat >> pr.body << __SOME_RANDOM_PR_EOF__
|
||||
${{ github.event.pull_request.body }}
|
||||
__SOME_RANDOM_PR_EOF__
|
||||
|
||||
- name: Display the received body for troubleshooting
|
||||
run: cat pr.body
|
||||
|
||||
# We want to write these out individually just incase the options were joined on a single line
|
||||
- name: Check for each of the lines
|
||||
run: |
|
||||
grep "Bug, Docs Fix or other nominal change" pr.body > Z
|
||||
grep "New or Enhanced Feature" pr.body > Y
|
||||
grep "Breaking Change" pr.body > 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
|
||||
shell: bash {0}
|
||||
|
||||
- name: Check for exactly one item
|
||||
run: |
|
||||
if [ $(cat X Y Z | wc -l) != 1 ] ; then
|
||||
echo "The PR body must contain exactly one of [ 'Bug, Docs Fix or other nominal change', 'New or Enhanced Feature', 'Breaking Change' ]"
|
||||
echo "We counted $(cat X Y Z | wc -l)"
|
||||
echo "See the default PR body for examples"
|
||||
exit 255;
|
||||
else
|
||||
exit 0;
|
||||
fi
|
||||
15
.github/workflows/promote.yaml
vendored
15
.github/workflows/promote.yaml
vendored
@@ -8,6 +8,8 @@ jobs:
|
||||
promote:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: |
|
||||
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
@@ -23,3 +25,16 @@ jobs:
|
||||
docker tag ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }} quay.io/${{ github.repository }}:latest
|
||||
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 }}
|
||||
|
||||
85
.github/workflows/stage.yml
vendored
Normal file
85
.github/workflows/stage.yml
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
---
|
||||
name: Stage Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to stage'
|
||||
required: true
|
||||
default_awx_version:
|
||||
description: 'Will be injected as the DEFAULT_AWX_VERSION build arg.'
|
||||
required: true
|
||||
confirm:
|
||||
description: 'Are you sure? Set this to yes.'
|
||||
required: true
|
||||
default: 'no'
|
||||
|
||||
jobs:
|
||||
stage:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: write
|
||||
steps:
|
||||
- name: Verify inputs
|
||||
run: |
|
||||
set -e
|
||||
|
||||
if [[ ${{ github.event.inputs.confirm }} != "yes" ]]; then
|
||||
>&2 echo "Confirm must be 'yes'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${{ github.event.inputs.version }} == "" ]]; then
|
||||
>&2 echo "Set version to continue."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
- name: Checkout awx
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: ${{ github.repository_owner }}/awx
|
||||
path: awx
|
||||
|
||||
- name: Checkout awx-operator
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: ${{ github.repository_owner }}/awx-operator
|
||||
path: awx-operator
|
||||
|
||||
- name: Install playbook dependencies
|
||||
run: |
|
||||
python3 -m pip install docker
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: |
|
||||
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
- name: Build and stage awx-operator
|
||||
working-directory: awx-operator
|
||||
run: |
|
||||
BUILD_ARGS="--build-arg DEFAULT_AWX_VERSION=${{ github.event.inputs.default_awx_version }} \
|
||||
--build-arg OPERATOR_VERSION=${{ github.event.inputs.version }}" \
|
||||
IMAGE_TAG_BASE=ghcr.io/${{ github.repository_owner }}/awx-operator \
|
||||
VERSION=${{ github.event.inputs.version }} make docker-build docker-push
|
||||
|
||||
- name: Run test deployment
|
||||
working-directory: awx-operator
|
||||
run: |
|
||||
python3 -m pip install -r molecule/requirements.txt
|
||||
ansible-galaxy collection install -r molecule/requirements.yml
|
||||
sudo rm -f $(which kustomize)
|
||||
make kustomize
|
||||
KUSTOMIZE_PATH=$(readlink -f bin/kustomize) molecule test -s kind
|
||||
env:
|
||||
AWX_TEST_VERSION: ${{ github.event.inputs.default_awx_version }}
|
||||
|
||||
- name: Create draft release
|
||||
working-directory: awx
|
||||
run: |
|
||||
ansible-playbook tools/ansible/stage.yml \
|
||||
-e version=${{ github.event.inputs.version }} \
|
||||
-e repo=${{ github.repository_owner }}/awx-operator \
|
||||
-e github_token=${{ secrets.GITHUB_TOKEN }}
|
||||
22
.github/workflows/triage_new.yml
vendored
Normal file
22
.github/workflows/triage_new.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Triage
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
name: Label
|
||||
|
||||
steps:
|
||||
- name: Label issues
|
||||
uses: github/issue-labeler@v2.4.1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
not-before: 2021-12-07T07:00:00Z
|
||||
configuration-path: .github/issue_labeler.yml
|
||||
enable-versioned-regex: 0
|
||||
if: github.event_name == 'issues'
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,3 +4,6 @@
|
||||
/bundle
|
||||
/bundle_tmp*
|
||||
/bundle.Dockerfile
|
||||
/charts
|
||||
/.cr-release-packages
|
||||
.vscode/
|
||||
|
||||
23
.helm/starter/.helmignore
Normal file
23
.helm/starter/.helmignore
Normal file
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
7
.helm/starter/Chart.yaml
Normal file
7
.helm/starter/Chart.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
apiVersion: v2
|
||||
appVersion: 0.1.0
|
||||
description: A Helm chart for Kubernetes
|
||||
name: starter
|
||||
type: application
|
||||
version: 0.1.0
|
||||
56
.helm/starter/README.md
Normal file
56
.helm/starter/README.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# AWX Operator Helm Chart
|
||||
|
||||
This chart installs the AWX Operator resources configured in [this](https://github.com/ansible/awx-operator) repository.
|
||||
|
||||
## Getting Started
|
||||
To configure your AWX resource using this chart, create your own `yaml` values file. The name is up to personal preference since it will explicitly be passed into the helm chart. Helm will merge whatever values you specify in your file with the default `values.yaml`, overriding any settings you've changed while allowing you to fall back on defaults. Because of this functionality, `values.yaml` should not be edited directly.
|
||||
|
||||
In your values config, enable `AWX.enable` and add `AWX.spec` values based on the awx operator's [documentation](https://github.com/ansible/awx-operator/blob/devel/README.md). Consult the docs below for additional functionality.
|
||||
|
||||
### Installing
|
||||
The operator's [helm install](https://github.com/ansible/awx-operator/blob/devel/README.md#helm-install-on-existing-cluster) guide provides key installation instructions.
|
||||
|
||||
Example:
|
||||
```
|
||||
helm install my-awx-operator awx-operator/awx-operator -n awx --create-namespace -f myvalues.yaml
|
||||
```
|
||||
|
||||
Argument breakdown:
|
||||
* `-f` passes in the file with your custom values
|
||||
* `-n` sets the namespace to be installed in
|
||||
* This value is accessed by `{{ $.Release.Namespace }}` in the templates
|
||||
* Acts as the default namespace for all unspecified resources
|
||||
* `--create-namespace` specifies that helm should create the namespace before installing
|
||||
|
||||
To update an existing installation, use `helm upgrade` instead of `install`. The rest of the syntax remains the same.
|
||||
|
||||
## Configuration
|
||||
The goal of adding helm configurations is to abstract out and simplify the creation of multi-resource configs. The `AWX.spec` field maps directly to the spec configs of the `AWX` resource that the operator provides, which are detailed in the [main README](https://github.com/ansible/awx-operator/blob/devel/README.md). Other sub-config can be added with the goal of simplifying more involved setups that require additional resources to be specified.
|
||||
|
||||
These sub-headers aim to be a more intuitive entrypoint into customizing your deployment, and are easier to manage in the long-term. By design, the helm templates will defer to the manually defined specs to avoid configuration conflicts. For example, if `AWX.spec.postgres_configuration_secret` is being used, the `AWX.postgres` settings will not be applied, even if enabled.
|
||||
|
||||
### External Postgres
|
||||
The `AWX.postgres` section simplifies the creation of the external postgres secret. If enabled, the configs provided will automatically be placed in a `postgres-config` secret and linked to the `AWX` resource. For proper secret management, the `AWX.postgres.password` value, and any other sensitive values, can be passed in at the command line rather than specified in code. Use the `--set` argument with `helm install`.
|
||||
|
||||
|
||||
## Values Summary
|
||||
|
||||
### AWX
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `AWX.enabled` | Enable this AWX resource configuration | `false` |
|
||||
| `AWX.name` | The name of the AWX resource and default prefix for other resources | `"awx"` |
|
||||
| `AWX.spec` | specs to directly configure the AWX resource | `{}` |
|
||||
| `AWX.postgres` | configurations for the external postgres secret | - |
|
||||
|
||||
|
||||
# Contributing
|
||||
|
||||
## Adding abstracted sections
|
||||
Where possible, defer to `AWX.spec` configs before applying the abstracted configs to avoid collision. This can be facilitated by the `(hasKey .spec what_i_will_abstract)` check.
|
||||
|
||||
## Building and Testing
|
||||
This chart is built using the Makefile in the [awx-operator repo](https://github.com/ansible/awx-operator). Clone the repo and run `make helm-chart`. This will create the awx-operator chart in the `charts/awx-operator` directory. In this process, the contents of the `.helm/starter` directory will be added to the chart.
|
||||
|
||||
## Future Goals
|
||||
All values under the `AWX` header are focused on configurations that use the operator. Configurations that relate to the Operator itself could be placed under an `Operator` heading, but that may add a layer of complication over current development.
|
||||
6
.helm/starter/templates/_helpers.tpl
Normal file
6
.helm/starter/templates/_helpers.tpl
Normal file
@@ -0,0 +1,6 @@
|
||||
{{/*
|
||||
Generate the name of the postgres secret, expects AWX context passed in
|
||||
*/}}
|
||||
{{- define "postgres.secretName" -}}
|
||||
{{ default (printf "%s-postgres-configuration" .Values.AWX.name) .Values.AWX.postgres.secretName }}
|
||||
{{- end }}
|
||||
24
.helm/starter/templates/awx-deploy.yaml
Normal file
24
.helm/starter/templates/awx-deploy.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
{{- if $.Values.AWX.enabled }}
|
||||
{{- with .Values.AWX }}
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
spec:
|
||||
{{- /* Include raw map from the values file spec */}}
|
||||
{{ .spec | toYaml | indent 2 }}
|
||||
{{- /* Provide security context defaults */}}
|
||||
{{- if not (hasKey .spec "security_context_settings") }}
|
||||
security_context_settings:
|
||||
runAsGroup: 0
|
||||
runAsUser: 0
|
||||
fsGroup: 0
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
{{- end }}
|
||||
{{- /* Postgres configs if enabled and not already present */}}
|
||||
{{- if and .postgres.enabled (not (hasKey .spec "postgres_configuration_secret")) }}
|
||||
postgres_configuration_secret: {{ include "postgres.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
18
.helm/starter/templates/postgres-config.yaml
Normal file
18
.helm/starter/templates/postgres-config.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
{{- if and $.Values.AWX.enabled $.Values.AWX.postgres.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "postgres.secretName" . }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
{{- with $.Values.AWX.postgres }}
|
||||
stringData:
|
||||
host: {{ .host }}
|
||||
port: {{ .port | quote }}
|
||||
database: {{ .dbName }}
|
||||
username: {{ .username }}
|
||||
password: {{ .password }}
|
||||
sslmode: {{ .sslmode }}
|
||||
type: {{ .type }}
|
||||
type: Opaque
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
19
.helm/starter/values.yaml
Normal file
19
.helm/starter/values.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
AWX:
|
||||
# enable use of awx-deploy template
|
||||
enabled: false
|
||||
name: awx
|
||||
spec:
|
||||
admin_user: admin
|
||||
|
||||
# configurations for external postgres instance
|
||||
postgres:
|
||||
enabled: false
|
||||
host: Unset
|
||||
port: 5678
|
||||
dbName: Unset
|
||||
username: admin
|
||||
# for secret management, pass in the password independently of this file
|
||||
# at the command line, use --set AWX.postgres.password
|
||||
password: Unset
|
||||
sslmode: prefer
|
||||
type: unmanaged
|
||||
@@ -6,9 +6,9 @@ ignore: |
|
||||
kustomization.yaml
|
||||
awx-operator.clusterserviceversion.yaml
|
||||
bundle
|
||||
.helm/starter
|
||||
|
||||
rules:
|
||||
truthy: disable
|
||||
line-length:
|
||||
max: 170
|
||||
level: warning
|
||||
|
||||
@@ -2,7 +2,14 @@
|
||||
|
||||
This is a list of high-level changes for each release of `awx-operator`. A full list of commits can be found at `https://github.com/ansible/awx-operator/releases/tag/<version>`.
|
||||
|
||||
# 0.14.0 (TBA)
|
||||
# 0.19.0 (Mar 23, 2022)
|
||||
|
||||
- Fix corrupted spec for the service with nodeport type (kurokobo) - dbaf64e
|
||||
- Add ability to deploy with OLM & added logo (Christian Adams) - 86c31a4
|
||||
- Fix backup & restore issues with special characters in the postgres password (kurokobo) - 589a375
|
||||
- Use centos:stream8 container where applicable (Shane McDonald)- 12a58d7
|
||||
|
||||
# 0.14.0 (Oct 03, 2021)
|
||||
|
||||
- Starting with awx-operator 0.14.0, the project is now based on operator-sdk 1.x.
|
||||
- To avoid a headache, you probably want to delete your existing operator Deployment and follow the README.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
FROM quay.io/operator-framework/ansible-operator:v1.12.0
|
||||
|
||||
ARG DEFAULT_AWX_VERSION
|
||||
ARG OPERATOR_VERSION
|
||||
ENV DEFAULT_AWX_VERSION=${DEFAULT_AWX_VERSION}
|
||||
ENV OPERATOR_VERSION=${OPERATOR_VERSION}
|
||||
|
||||
COPY requirements.yml ${HOME}/requirements.yml
|
||||
RUN ansible-galaxy collection install -r ${HOME}/requirements.yml \
|
||||
|
||||
180
Makefile
180
Makefile
@@ -5,6 +5,15 @@
|
||||
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
|
||||
VERSION ?= $(shell git describe --tags)
|
||||
|
||||
CONTAINER_CMD ?= docker
|
||||
|
||||
# GNU vs BSD in-place sed
|
||||
ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu)
|
||||
SED_I := sed -i
|
||||
else
|
||||
SED_I := sed -i ''
|
||||
endif
|
||||
|
||||
# CHANNELS define the bundle channels used in the bundle.
|
||||
# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable")
|
||||
# To re-generate a bundle for other specific channels without changing the standard setup, you can:
|
||||
@@ -39,6 +48,14 @@ BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)
|
||||
IMG ?= $(IMAGE_TAG_BASE):$(VERSION)
|
||||
NAMESPACE ?= awx
|
||||
|
||||
# Helm variables
|
||||
CHART_NAME ?= awx-operator
|
||||
CHART_DESCRIPTION ?= A Helm chart for the AWX Operator
|
||||
CHART_OWNER ?= $(GH_REPO_OWNER)
|
||||
CHART_REPO ?= awx-operator
|
||||
CHART_BRANCH ?= gh-pages
|
||||
CHART_INDEX ?= index.yaml
|
||||
|
||||
all: docker-build
|
||||
|
||||
##@ General
|
||||
@@ -63,10 +80,10 @@ run: ansible-operator ## Run against the configured Kubernetes cluster in ~/.kub
|
||||
ANSIBLE_ROLES_PATH="$(ANSIBLE_ROLES_PATH):$(shell pwd)/roles" $(ANSIBLE_OPERATOR) run
|
||||
|
||||
docker-build: ## Build docker image with the manager.
|
||||
docker build $(BUILD_ARGS) -t ${IMG} .
|
||||
${CONTAINER_CMD} build $(BUILD_ARGS) -t ${IMG} .
|
||||
|
||||
docker-push: ## Push docker image with the manager.
|
||||
docker push ${IMG}
|
||||
${CONTAINER_CMD} push ${IMG}
|
||||
|
||||
##@ Deployment
|
||||
|
||||
@@ -76,16 +93,23 @@ install: kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/con
|
||||
uninstall: kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
|
||||
$(KUSTOMIZE) build config/crd | kubectl delete -f -
|
||||
|
||||
gen-resources: kustomize ## Generate resources for controller and print to stdout
|
||||
@cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
|
||||
@cd config/default && $(KUSTOMIZE) edit set namespace ${NAMESPACE}
|
||||
@$(KUSTOMIZE) build config/default
|
||||
|
||||
deploy: kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
|
||||
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
|
||||
cd config/default && $(KUSTOMIZE) edit set namespace ${NAMESPACE}
|
||||
$(KUSTOMIZE) build config/default | kubectl apply -f -
|
||||
@cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
|
||||
@cd config/default && $(KUSTOMIZE) edit set namespace ${NAMESPACE}
|
||||
@$(KUSTOMIZE) build config/default | kubectl apply -f -
|
||||
|
||||
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
|
||||
@cd config/default && $(KUSTOMIZE) edit set namespace ${NAMESPACE}
|
||||
$(KUSTOMIZE) build config/default | kubectl delete -f -
|
||||
|
||||
OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
|
||||
ARCH := $(shell uname -m | sed 's/x86_64/amd64/')
|
||||
ARCHA := $(shell uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')
|
||||
ARCHX := $(shell uname -m | sed -e 's/amd64/x86_64/' -e 's/aarch64/arm64/')
|
||||
|
||||
.PHONY: kustomize
|
||||
KUSTOMIZE = $(shell pwd)/bin/kustomize
|
||||
@@ -95,7 +119,7 @@ ifeq (,$(shell which kustomize 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(KUSTOMIZE)) ;\
|
||||
curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.8.7/kustomize_v3.8.7_$(OS)_$(ARCH).tar.gz | \
|
||||
curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v4.5.2/kustomize_v4.5.2_$(OS)_$(ARCHA).tar.gz | \
|
||||
tar xzf - -C bin/ ;\
|
||||
}
|
||||
else
|
||||
@@ -111,7 +135,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.12.0/ansible-operator_$(OS)_$(ARCH) ;\
|
||||
curl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.12.0/ansible-operator_$(OS)_$(ARCHA) ;\
|
||||
chmod +x $(ANSIBLE_OPERATOR) ;\
|
||||
}
|
||||
else
|
||||
@@ -124,12 +148,11 @@ bundle: kustomize ## Generate bundle manifests and metadata, then validate gener
|
||||
operator-sdk generate kustomize manifests -q
|
||||
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
|
||||
$(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
|
||||
cd config/manifests/bases && python inject-csv-config.py
|
||||
operator-sdk bundle validate ./bundle
|
||||
|
||||
.PHONY: bundle-build
|
||||
bundle-build: ## Build the bundle image.
|
||||
docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) .
|
||||
${CONTAINER_CMD} build -f bundle.Dockerfile -t $(BUNDLE_IMG) .
|
||||
|
||||
.PHONY: bundle-push
|
||||
bundle-push: ## Push the bundle image.
|
||||
@@ -143,7 +166,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.15.1/$(OS)-$(ARCH)-opm ;\
|
||||
curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.15.1/$(OS)-$(ARCHA)-opm ;\
|
||||
chmod +x $(OPM) ;\
|
||||
}
|
||||
else
|
||||
@@ -168,9 +191,142 @@ endif
|
||||
# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator
|
||||
.PHONY: catalog-build
|
||||
catalog-build: opm ## Build a catalog image.
|
||||
$(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT)
|
||||
$(OPM) index add --container-tool ${CONTAINER_CMD} --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT)
|
||||
|
||||
# Push the catalog image.
|
||||
.PHONY: catalog-push
|
||||
catalog-push: ## Push a catalog image.
|
||||
$(MAKE) docker-push IMG=$(CATALOG_IMG)
|
||||
|
||||
.PHONY: kubectl-slice
|
||||
KUBECTL_SLICE = $(shell pwd)/bin/kubectl-slice
|
||||
kubectl-slice: ## Download kubectl-slice locally if necessary.
|
||||
ifeq (,$(wildcard $(KUBECTL_SLICE)))
|
||||
ifeq (,$(shell which kubectl-slice 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(KUBECTL_SLICE)) ;\
|
||||
curl -sSLo - https://github.com/patrickdappollonio/kubectl-slice/releases/download/v1.1.0/kubectl-slice_1.1.0_$(OS)_$(ARCHX).tar.gz | \
|
||||
tar xzf - -C bin/ kubectl-slice ;\
|
||||
}
|
||||
else
|
||||
KUBECTL_SLICE = $(shell which kubectl-slice)
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: helm
|
||||
HELM = $(shell pwd)/bin/helm
|
||||
helm: ## Download helm locally if necessary.
|
||||
ifeq (,$(wildcard $(HELM)))
|
||||
ifeq (,$(shell which helm 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(HELM)) ;\
|
||||
curl -sSLo - https://get.helm.sh/helm-v3.8.0-$(OS)-$(ARCHA).tar.gz | \
|
||||
tar xzf - -C bin/ $(OS)-$(ARCHA)/helm ;\
|
||||
mv bin/$(OS)-$(ARCHA)/helm bin/helm ;\
|
||||
rmdir bin/$(OS)-$(ARCHA) ;\
|
||||
}
|
||||
else
|
||||
HELM = $(shell which helm)
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: yq
|
||||
YQ = $(shell pwd)/bin/yq
|
||||
yq: ## Download yq locally if necessary.
|
||||
ifeq (,$(wildcard $(YQ)))
|
||||
ifeq (,$(shell which yq 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(HELM)) ;\
|
||||
curl -sSLo - https://github.com/mikefarah/yq/releases/download/v4.20.2/yq_$(OS)_$(ARCHA).tar.gz | \
|
||||
tar xzf - -C bin/ ;\
|
||||
mv bin/yq_$(OS)_$(ARCHA) bin/yq ;\
|
||||
}
|
||||
else
|
||||
YQ = $(shell which yq)
|
||||
endif
|
||||
endif
|
||||
|
||||
PHONY: cr
|
||||
CR = $(shell pwd)/bin/cr
|
||||
cr: ## Download cr locally if necessary.
|
||||
ifeq (,$(wildcard $(CR)))
|
||||
ifeq (,$(shell which cr 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(CR)) ;\
|
||||
curl -sSLo - https://github.com/helm/chart-releaser/releases/download/v1.3.0/chart-releaser_1.3.0_$(OS)_$(ARCHA).tar.gz | \
|
||||
tar xzf - -C bin/ cr ;\
|
||||
}
|
||||
else
|
||||
CR = $(shell which cr)
|
||||
endif
|
||||
endif
|
||||
|
||||
charts:
|
||||
mkdir -p $@
|
||||
|
||||
.PHONY: helm-chart
|
||||
helm-chart: helm-chart-generate helm-chart-slice
|
||||
|
||||
.PHONY: helm-chart-generate
|
||||
helm-chart-generate: kustomize helm kubectl-slice yq charts
|
||||
@echo "== KUSTOMIZE (image and namespace) =="
|
||||
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
|
||||
|
||||
@echo "== HELM =="
|
||||
cd charts && \
|
||||
$(HELM) create awx-operator --starter $(shell pwd)/.helm/starter ;\
|
||||
$(YQ) -i '.version = "$(VERSION)"' $(CHART_NAME)/Chart.yaml ;\
|
||||
$(YQ) -i '.appVersion = "$(VERSION)" | .appVersion style="double"' $(CHART_NAME)/Chart.yaml ;\
|
||||
$(YQ) -i '.description = "$(CHART_DESCRIPTION)"' $(CHART_NAME)/Chart.yaml ;\
|
||||
|
||||
@cat charts/$(CHART_NAME)/Chart.yaml
|
||||
|
||||
@echo "== KUSTOMIZE (annotation) =="
|
||||
cd config/manager && $(KUSTOMIZE) edit set annotation helm.sh/chart:$(CHART_NAME)-$(VERSION)
|
||||
cd config/default && $(KUSTOMIZE) edit set annotation helm.sh/chart:$(CHART_NAME)-$(VERSION)
|
||||
|
||||
@echo "== SLICE =="
|
||||
$(KUSTOMIZE) build --load-restrictor LoadRestrictionsNone config/default | \
|
||||
$(KUBECTL_SLICE) --input-file=- \
|
||||
--output-dir=charts/$(CHART_NAME)/templates \
|
||||
--sort-by-kind
|
||||
@echo "AWX Operator installed with Helm Chart version $(VERSION)" > charts/$(CHART_NAME)/templates/NOTES.txt
|
||||
mkdir charts/$(CHART_NAME)/crds
|
||||
mv charts/$(CHART_NAME)/templates/customresourcedefinition* charts/$(CHART_NAME)/crds
|
||||
|
||||
.PHONY: helm-chart-edit
|
||||
helm-chart-slice:
|
||||
@echo "== EDIT =="
|
||||
$(foreach file, $(wildcard charts/$(CHART_NAME)/templates/*),$(YQ) -i 'del(.. | select(has("namespace")).namespace)' $(file);)
|
||||
$(foreach file, $(wildcard charts/$(CHART_NAME)/templates/*rolebinding*),$(YQ) -i '.subjects[0].namespace = "{{ .Release.Namespace }}"' $(file);)
|
||||
rm -f charts/$(CHART_NAME)/templates/namespace*.yaml
|
||||
|
||||
|
||||
.PHONY: helm-package
|
||||
helm-package: cr helm-chart
|
||||
@echo "== CHART RELEASER (package) =="
|
||||
$(CR) package ./charts/awx-operator
|
||||
|
||||
# The actual release happens in ansible/helm-release.yml
|
||||
# until https://github.com/helm/chart-releaser/issues/122 happens
|
||||
.PHONY: helm-index
|
||||
helm-index: cr helm-chart
|
||||
@echo "== CHART RELEASER (httpsorigin) =="
|
||||
git remote add httpsorigin "https://github.com/$(CHART_OWNER)/$(CHART_REPO).git"
|
||||
git fetch httpsorigin
|
||||
|
||||
@echo "== CHART RELEASER (index) =="
|
||||
$(CR) index \
|
||||
--owner "$(CHART_OWNER)" \
|
||||
--git-repo "$(CHART_REPO)" \
|
||||
--token "$(CR_TOKEN)" \
|
||||
--pages-branch "$(CHART_BRANCH)" \
|
||||
--index-path "./charts/$(CHART_INDEX)" \
|
||||
--charts-repo "https://$(CHART_OWNER).github.io/$(CHART_REPO)/$(CHART_INDEX)" \
|
||||
--remote httpsorigin \
|
||||
--release-name-template="{{ .Version }}" \
|
||||
--push
|
||||
|
||||
646
README.md
646
README.md
@@ -1,17 +1,24 @@
|
||||
# AWX Operator
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0) [](https://github.com/ansible/awx-operator/actions)
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://github.com/ansible/awx-operator/actions)
|
||||
[](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
|
||||
[](https://groups.google.com/g/awx-project)
|
||||
[](https://libera.chat)
|
||||
|
||||
An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built with [Operator SDK](https://github.com/operator-framework/operator-sdk) and Ansible.
|
||||
|
||||
# Table of Contents
|
||||
|
||||
<!-- Regenerate this table of contents using https://github.com/ekalinin/github-markdown-toc -->
|
||||
<!-- gh-md-toc --insert README.md -->
|
||||
<!--ts-->
|
||||
* [AWX Operator](#awx-operator)
|
||||
* [Table of Contents](#table-of-contents)
|
||||
* [Purpose](#purpose)
|
||||
* [Usage](#usage)
|
||||
* [Creating a minikube cluster for testing](#creating-a-minikube-cluster-for-testing)
|
||||
* [Basic Install](#basic-install)
|
||||
* [Helm Install on existing cluster](#helm-install-on-existing-cluster)
|
||||
* [Admin user account configuration](#admin-user-account-configuration)
|
||||
* [Network and TLS Configuration](#network-and-tls-configuration)
|
||||
* [Service Type](#service-type)
|
||||
@@ -22,37 +29,53 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
|
||||
* [Managed PostgreSQL Service](#managed-postgresql-service)
|
||||
* [Advanced Configuration](#advanced-configuration)
|
||||
* [Deploying a specific version of AWX](#deploying-a-specific-version-of-awx)
|
||||
* [Redis container capabilities](#redis-container-capabilities)
|
||||
* [Privileged Tasks](#privileged-tasks)
|
||||
* [Containers Resource Requirements](#containers-resource-requirements)
|
||||
* [Priority Classes](#priority-classes)
|
||||
* [Assigning AWX pods to specific nodes](#assigning-awx-pods-to-specific-nodes)
|
||||
* [Trusting a Custom Certificate Authority](#trusting-a-custom-certificate-authority)
|
||||
* [Enabling LDAP Integration at AWX bootstrap](#enabling-ldap-integration-at-awx-bootstrap)
|
||||
* [Persisting Projects Directory](#persisting-projects-directory)
|
||||
* [Custom Volume and Volume Mount Options](#custom-volume-and-volume-mount-options)
|
||||
* [Default execution environments from private registries](#default-execution-environments-from-private-registries)
|
||||
* [Control plane ee from private registry](#control-plane-ee-from-private-registry)
|
||||
* [Exporting Environment Variables to Containers](#exporting-environment-variables-to-containers)
|
||||
* [CSRF Cookie Secure Setting](#csrf-cookie-secure-setting)
|
||||
* [Session Cookie Secure Setting](#session-cookie-secure-setting)
|
||||
* [Extra Settings](#extra-settings)
|
||||
* [Configure no_log](#no-log)
|
||||
* [Auto Upgrade](#auto-upgrade)
|
||||
* [Upgrade of instances without auto upgrade](#upgrade-of-instances-without-auto-upgrade)
|
||||
* [Service Account](#service-account)
|
||||
* [Uninstall](#uninstall)
|
||||
* [Upgrading](#upgrading)
|
||||
* [Upgrading](#upgrading)
|
||||
* [Backup](#backup)
|
||||
* [v0.14.0](#v0140)
|
||||
* [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)
|
||||
* [Contributing](#contributing)
|
||||
* [Release Process](#release-process)
|
||||
* [Verifiy Functionality](#verify-functionality)
|
||||
* [Update Version](#update-version)
|
||||
* [Commit / Create Release](#commit--create-release)
|
||||
* [Author](#author)
|
||||
* [Code of Conduct](#code-of-conduct)
|
||||
* [Get Involved](#get-involved)
|
||||
|
||||
<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
|
||||
|
||||
<!--te-->
|
||||
|
||||
## Purpose
|
||||
|
||||
This operator is meant to provide a more Kubernetes-native installation method for AWX via an AWX Custom Resource Definition (CRD).
|
||||
|
||||
> :warning: The operator is not supported by Red Hat, and is in **alpha** status. For now, use it at your own risk!
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Install
|
||||
|
||||
This Kubernetes Operator is meant to be deployed in your Kubernetes cluster(s) and can manage one or more AWX instances in any namespace.
|
||||
|
||||
For testing purposes, the `awx-operator` can be deployed on a [Minikube](https://minikube.sigs.k8s.io/docs/) cluster. Due to different OS and hardware environments, please refer to the official Minikube documentation for further information.
|
||||
### Creating a minikube cluster for testing
|
||||
|
||||
If you do not have an existing cluster, the `awx-operator` can be deployed on a [Minikube](https://minikube.sigs.k8s.io/docs/) cluster for testing purposes. Due to different OS and hardware environments, please refer to the official Minikube documentation for further information.
|
||||
|
||||
```
|
||||
$ minikube start --cpus=4 --memory=6g --addons=ingress
|
||||
@@ -101,26 +124,47 @@ Let's create an alias for easier usage:
|
||||
$ alias kubectl="minikube kubectl --"
|
||||
```
|
||||
|
||||
Now you need to deploy AWX Operator into your cluster. Clone this repo and `git checkout` the latest version from https://github.com/ansible/awx-operator/releases, and then run the following command:
|
||||
### Basic Install
|
||||
|
||||
Once you have a running Kubernetes cluster, you can deploy AWX Operator into your cluster using [Kustomize](https://kubectl.docs.kubernetes.io/guides/introduction/kustomize/). Follow the instructions here to install the latest version of Kustomize: https://kubectl.docs.kubernetes.io/installation/kustomize/
|
||||
|
||||
First, create a file called `kustomization.yaml` with the following content:
|
||||
|
||||
```yaml
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
# Find the latest tag here: https://github.com/ansible/awx-operator/releases
|
||||
- github.com/ansible/awx-operator/config/default?ref=<tag>
|
||||
|
||||
# Set the image tags to match the git version from above
|
||||
images:
|
||||
- name: quay.io/ansible/awx-operator
|
||||
newTag: <tag>
|
||||
|
||||
# Specify a custom namespace in which to install AWX
|
||||
namespace: awx
|
||||
```
|
||||
|
||||
> **TIP:** If you need to change any of the default settings for the operator (such as resources.limits), you can add [patches](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/) at the bottom of your kustomization.yaml file.
|
||||
|
||||
Install the manifests by running this:
|
||||
|
||||
```
|
||||
$ export NAMESPACE=my-namespace
|
||||
$ make deploy
|
||||
cd config/manager && /home/user/awx-operator/bin/kustomize edit set image controller=quay.io/ansible/awx-operator:0.14.0
|
||||
/home/user/awx-operator/bin/kustomize build config/default | kubectl apply -f -
|
||||
namespace/my-namespace created
|
||||
$ kustomize build . | kubectl apply -f -
|
||||
namespace/awx created
|
||||
customresourcedefinition.apiextensions.k8s.io/awxbackups.awx.ansible.com created
|
||||
customresourcedefinition.apiextensions.k8s.io/awxrestores.awx.ansible.com created
|
||||
customresourcedefinition.apiextensions.k8s.io/awxs.awx.ansible.com created
|
||||
serviceaccount/awx-operator-controller-manager created
|
||||
role.rbac.authorization.k8s.io/awx-operator-awx-manager-role created
|
||||
role.rbac.authorization.k8s.io/awx-operator-leader-election-role created
|
||||
role.rbac.authorization.k8s.io/awx-operator-manager-role created
|
||||
clusterrole.rbac.authorization.k8s.io/awx-operator-metrics-reader created
|
||||
clusterrole.rbac.authorization.k8s.io/awx-operator-proxy-role created
|
||||
rolebinding.rbac.authorization.k8s.io/awx-operator-awx-manager-rolebinding created
|
||||
rolebinding.rbac.authorization.k8s.io/awx-operator-leader-election-rolebinding created
|
||||
rolebinding.rbac.authorization.k8s.io/awx-operator-manager-rolebinding created
|
||||
clusterrolebinding.rbac.authorization.k8s.io/awx-operator-proxy-rolebinding created
|
||||
configmap/awx-operator-manager-config created
|
||||
configmap/awx-operator-awx-manager-config created
|
||||
service/awx-operator-controller-manager-metrics-service created
|
||||
deployment.apps/awx-operator-controller-manager created
|
||||
```
|
||||
@@ -128,18 +172,18 @@ deployment.apps/awx-operator-controller-manager created
|
||||
Wait a bit and you should have the `awx-operator` running:
|
||||
|
||||
```
|
||||
$ kubectl get pods -n $NAMESPACE
|
||||
$ kubectl get pods -n awx
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
awx-operator-controller-manager-66ccd8f997-rhd4z 2/2 Running 0 11s
|
||||
```
|
||||
|
||||
So we don't have to keep repeating `-n $NAMESPACE`, let's set the current namespace for `kubectl`:
|
||||
So we don't have to keep repeating `-n awx`, let's set the current namespace for `kubectl`:
|
||||
|
||||
```
|
||||
$ kubectl config set-context --current --namespace=$NAMESPACE
|
||||
$ kubectl config set-context --current --namespace=awx
|
||||
```
|
||||
|
||||
Next, create a file named `awx-demo.yml` with the suggested content below. The `metadata.name` you provide, will be the name of the resulting AWX deployment.
|
||||
Next, create a file named `awx-demo.yaml` in the same folder with the suggested content below. The `metadata.name` you provide will be the name of the resulting AWX deployment.
|
||||
|
||||
**Note:** If you deploy more than one AWX instance to the same namespace, be sure to use unique names.
|
||||
|
||||
@@ -151,13 +195,27 @@ metadata:
|
||||
name: awx-demo
|
||||
spec:
|
||||
service_type: nodeport
|
||||
# default nodeport_port is 30080
|
||||
nodeport_port: <nodeport_port>
|
||||
```
|
||||
|
||||
Finally, use `kubectl` to create the awx instance in your cluster:
|
||||
> It may make sense to create and specify your own secret key for your deployment so that if the k8s secret gets deleted, it can be re-created if needed. If it is not provided, one will be auto-generated, but cannot be recovered if lost. Read more [here](#secret-key-configuration).
|
||||
|
||||
Make sure to add this new file to the list of "resources" in your `kustomization.yaml` file:
|
||||
|
||||
```yaml
|
||||
...
|
||||
resources:
|
||||
- github.com/ansible/awx-operator/config/default?ref=<tag>
|
||||
# Add this extra line:
|
||||
- awx-demo.yaml
|
||||
...
|
||||
```
|
||||
|
||||
Finally, run `kustomize` again to create the AWX instance in your cluster:
|
||||
|
||||
```
|
||||
$ kubectl apply -f awx-demo.yml
|
||||
awx.awx.ansible.com/awx-demo created
|
||||
kustomize build . | kubectl apply -f -
|
||||
```
|
||||
|
||||
After a few minutes, the new AWX instance will be deployed. You can look at the operator pod logs in order to know where the installation process is at:
|
||||
@@ -197,17 +255,46 @@ You just completed the most basic install of an AWX instance via this operator.
|
||||
|
||||
For an example using the Nginx Controller in Minukube, don't miss our [demo video](https://asciinema.org/a/416946).
|
||||
|
||||
[](https://asciinema.org/a/416946)
|
||||
|
||||
### Helm Install on existing cluster
|
||||
|
||||
For those that wish to use [Helm](https://helm.sh/) to install the awx-operator to an existing K8s cluster:
|
||||
|
||||
The helm chart is generated from the `helm-chart` Makefile section using the starter files in `.helm/starter`. Consult [the documentation](.helm/starter/README.md) on how to customize the AWX resource with your own values.
|
||||
|
||||
```bash
|
||||
$ helm repo add awx-operator https://ansible.github.io/awx-operator/
|
||||
"awx-operator" has been added to your repositories
|
||||
|
||||
$ helm repo update
|
||||
Hang tight while we grab the latest from your chart repositories...
|
||||
...Successfully got an update from the "awx-operator" chart repository
|
||||
Update Complete. ⎈Happy Helming!⎈
|
||||
|
||||
$ helm search repo awx-operator
|
||||
NAME CHART VERSION APP VERSION DESCRIPTION
|
||||
awx-operator/awx-operator 0.17.1 0.17.1 A Helm chart for the AWX Operator
|
||||
|
||||
$ helm install -n awx --create-namespace my-awx-operator awx-operator/awx-operator
|
||||
NAME: my-awx-operator
|
||||
LAST DEPLOYED: Thu Feb 17 22:09:05 2022
|
||||
NAMESPACE: default
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
NOTES:
|
||||
Helm Chart 0.17.1
|
||||
```
|
||||
|
||||
### Admin user account configuration
|
||||
|
||||
There are three variables that are customizable for the admin user account creation.
|
||||
|
||||
| Name | Description | Default |
|
||||
| --------------------------- | -------------------------------------------- | ---------------- |
|
||||
| admin_user | Name of the admin user | admin |
|
||||
| admin_email | Email of the admin user | test@example.com |
|
||||
| admin_password_secret | Secret that contains the admin user password | Empty string |
|
||||
| Name | Description | Default |
|
||||
| --------------------- | -------------------------------------------- | ---------------- |
|
||||
| admin_user | Name of the admin user | admin |
|
||||
| admin_email | Email of the admin user | test@example.com |
|
||||
| admin_password_secret | Secret that contains the admin user password | Empty string |
|
||||
|
||||
|
||||
> :warning: **admin_password_secret must be a Kubernetes secret and not your text clear password**.
|
||||
@@ -230,6 +317,41 @@ stringData:
|
||||
```
|
||||
|
||||
|
||||
### Secret Key Configuration
|
||||
|
||||
This key is used to encrypt sensitive data in the database.
|
||||
|
||||
| Name | Description | Default |
|
||||
| ----------------- | ----------------------------------------------------- | ---------------- |
|
||||
| secret_key_secret | Secret that contains the symmetric key for encryption | Generated |
|
||||
|
||||
|
||||
> :warning: **secret_key_secret must be a Kubernetes secret and not your text clear secret value**.
|
||||
|
||||
If `secret_key_secret` is not provided, the operator will look for a secret named `<resourcename>-secret-key` for the secret key. If it is not present, the operator will generate a password and create a Secret from it named `<resourcename>-secret-key`. It is important to not delete this secret as it will be needed for upgrades and if the pods get scaled down at any point. If you are using a GitOps flow, you will want to pass a secret key secret.
|
||||
|
||||
The secret should be formatted as follow:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: custom-awx-secret-key
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
secret_key: supersecuresecretkey
|
||||
```
|
||||
|
||||
Then specify the secret name on the AWX spec:
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
secret_key_secret: custom-awx-secret-key
|
||||
```
|
||||
|
||||
### Network and TLS Configuration
|
||||
|
||||
#### Service Type
|
||||
@@ -240,15 +362,18 @@ The `service_type` supported options are: `ClusterIP`, `LoadBalancer` and `NodeP
|
||||
|
||||
The following variables are customizable for any `service_type`
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------------- | --------------------------------------------- | --------------------------------- |
|
||||
| service_labels | Add custom labels | Empty string |
|
||||
| Name | Description | Default |
|
||||
| ------------------- | ----------------------- | ------------ |
|
||||
| service_labels | Add custom labels | Empty string |
|
||||
| service_annotations | Add service annotations | Empty string |
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
service_type: ClusterIP
|
||||
service_annotations: |
|
||||
environment: testing
|
||||
service_labels: |
|
||||
environment: testing
|
||||
```
|
||||
@@ -257,11 +382,10 @@ spec:
|
||||
|
||||
The following variables are customizable only when `service_type=LoadBalancer`
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------ | ---------------------------------------- | ------------- |
|
||||
| loadbalancer_annotations | LoadBalancer annotations | Empty string |
|
||||
| loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
|
||||
| loadbalancer_port | Port used for Loadbalancer ingress | 80 |
|
||||
| Name | Description | Default |
|
||||
| --------------------- | ---------------------------------------- | ------- |
|
||||
| loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
|
||||
| loadbalancer_port | Port used for Loadbalancer ingress | 80 |
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -270,7 +394,7 @@ spec:
|
||||
service_type: LoadBalancer
|
||||
loadbalancer_protocol: https
|
||||
loadbalancer_port: 443
|
||||
loadbalancer_annotations: |
|
||||
service_annotations: |
|
||||
environment: testing
|
||||
service_labels: |
|
||||
environment: testing
|
||||
@@ -284,9 +408,9 @@ The HTTPS Load Balancer also uses SSL termination at the Load Balancer level and
|
||||
|
||||
The following variables are customizable only when `service_type=NodePort`
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------ | ---------------------------------------- | ------------- |
|
||||
| nodeport_port | Port used for NodePort | 30080 |
|
||||
| Name | Description | Default |
|
||||
| ------------- | ---------------------- | ------- |
|
||||
| nodeport_port | Port used for NodePort | 30080 |
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -314,13 +438,13 @@ spec:
|
||||
|
||||
The following variables are customizable when `ingress_type=ingress`. The `ingress` type creates an Ingress resource as [documented](https://kubernetes.io/docs/concepts/services-networking/ingress/) which can be shared with many other Ingress Controllers as [listed](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/).
|
||||
|
||||
| Name | Description | Default |
|
||||
| -------------------------- | ---------------------------------------- | ---------------------------- |
|
||||
| ingress_annotations | Ingress annotations | Empty string |
|
||||
| ingress_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
| hostname | Define the FQDN | {{ meta.name }}.example.com |
|
||||
| ingress_path | Define the ingress path to the service | / |
|
||||
| ingress_path_type | Define the type of the path (for LBs) | Prefix |
|
||||
| Name | Description | Default |
|
||||
| ------------------- | ---------------------------------------- | --------------------------- |
|
||||
| ingress_annotations | Ingress annotations | Empty string |
|
||||
| ingress_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
| hostname | Define the FQDN | {{ meta.name }}.example.com |
|
||||
| ingress_path | Define the ingress path to the service | / |
|
||||
| ingress_path_type | Define the type of the path (for LBs) | Prefix |
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -336,8 +460,8 @@ spec:
|
||||
|
||||
The following variables are customizable when `ingress_type=route`
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------------- | --------------------------------------------- | --------------------------------------------------------|
|
||||
| Name | Description | Default |
|
||||
| ------------------------------- | --------------------------------------------- | ------------------------------------------------------- |
|
||||
| route_host | Common name the route answers for | `<instance-name>-<namespace>-<routerCanonicalHostname>` |
|
||||
| route_tls_termination_mechanism | TLS Termination mechanism (Edge, Passthrough) | Edge |
|
||||
| route_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
@@ -356,7 +480,7 @@ spec:
|
||||
|
||||
#### External PostgreSQL Service
|
||||
|
||||
In order for the AWX instance to rely on an external database, the Custom Resource needs to know about the connection details. Those connection details should be stored as a secret and either specified as `postgres_configuration_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-postgres-configuration`.
|
||||
To configure AWX to use an external database, the Custom Resource needs to know about the connection details. To do this, create a k8s secret with those connection details and specify the name of the secret as `postgres_configuration_secret` at the CR spec level.
|
||||
|
||||
|
||||
The secret should be formatted as follows:
|
||||
@@ -379,12 +503,21 @@ stringData:
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
> Please ensure that the value for the variable "password" is wrapped in quotes if the password contains any special characters.
|
||||
> Please ensure that the value for the variable `password` should _not_ contain single or double quotes (`'`, `"`) or backslashes (`\`) to avoid any issues during deployment, [backup](https://github.com/ansible/awx-operator/tree/devel/roles/backup) or [restoration](https://github.com/ansible/awx-operator/tree/devel/roles/restore).
|
||||
|
||||
> It is possible to set a specific username, password, port, or database, but still have the database managed by the operator. In this case, when creating the postgres-configuration secret, the `type: managed` field should be added.
|
||||
|
||||
**Note**: The variable `sslmode` is valid for `external` databases only. The allowed values are: `prefer`, `disable`, `allow`, `require`, `verify-ca`, `verify-full`.
|
||||
|
||||
Once the secret is created, you can specify it on your spec:
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
postgres_configuration_secret: <name-of-your-secret>
|
||||
```
|
||||
|
||||
#### Migrating data from an old AWX instance
|
||||
|
||||
For instructions on how to migrate from an older version of AWX, see [migration.md](./docs/migration.md).
|
||||
@@ -395,13 +528,15 @@ If you don't have access to an external PostgreSQL service, the AWX operator can
|
||||
|
||||
The following variables are customizable for the managed PostgreSQL service
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------------ | ------------------------------------------ | --------------------------------- |
|
||||
| postgres_image | Path of the image to pull | postgres:12 |
|
||||
| postgres_resource_requirements | PostgreSQL container resource requirements | Empty object |
|
||||
| postgres_storage_requirements | PostgreSQL container storage requirements | requests: {storage: 8Gi} |
|
||||
| postgres_storage_class | PostgreSQL PV storage class | Empty string |
|
||||
| postgres_data_path | PostgreSQL data path | `/var/lib/postgresql/data/pgdata` |
|
||||
| Name | Description | Default |
|
||||
| --------------------------------------------- | --------------------------------------------- | ---------------------------------- |
|
||||
| postgres_image | Path of the image to pull | postgres:12 |
|
||||
| postgres_init_container_resource_requirements | Database init container resource requirements | requests: {cpu: 10m, memory: 64Mi} |
|
||||
| postgres_resource_requirements | PostgreSQL container resource requirements | requests: {cpu: 10m, memory: 64Mi} |
|
||||
| postgres_storage_requirements | PostgreSQL container storage requirements | requests: {storage: 8Gi} |
|
||||
| postgres_storage_class | PostgreSQL PV storage class | Empty string |
|
||||
| postgres_data_path | PostgreSQL data path | `/var/lib/postgresql/data/pgdata` |
|
||||
| postgres_priority_class | Priority class used for PostgreSQL pod | Empty string |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
@@ -422,6 +557,9 @@ spec:
|
||||
limits:
|
||||
storage: 50Gi
|
||||
postgres_storage_class: fast-ssd
|
||||
postgres_extra_args:
|
||||
- '-c'
|
||||
- 'max_connections=1000'
|
||||
```
|
||||
|
||||
**Note**: If `postgres_storage_class` is not defined, Postgres will store it's data on a volume using the default storage class for your cluster.
|
||||
@@ -432,15 +570,15 @@ spec:
|
||||
|
||||
There are a few variables that are customizable for awx the image management.
|
||||
|
||||
| Name | Description |
|
||||
| --------------------------| -------------------------- |
|
||||
| image | Path of the image to pull |
|
||||
| image_version | Image version to pull |
|
||||
| image_pull_policy | The pull policy to adopt |
|
||||
| image_pull_secret | The pull secret to use |
|
||||
| ee_images | A list of EEs to register |
|
||||
| redis_image | Path of the image to pull |
|
||||
| redis_image_version | Image version to pull |
|
||||
| Name | Description | Default |
|
||||
| ------------------- | ------------------------- | -------------------------------------- |
|
||||
| image | Path of the image to pull | quay.io/ansible/awx |
|
||||
| image_version | Image version to pull | value of DEFAULT_AWX_VERSION or latest |
|
||||
| image_pull_policy | The pull policy to adopt | IfNotPresent |
|
||||
| image_pull_secrets | The pull secrets to use | None |
|
||||
| ee_images | A list of EEs to register | quay.io/ansible/awx-ee:latest |
|
||||
| redis_image | Path of the image to pull | docker.io/redis |
|
||||
| redis_image_version | Image version to pull | latest |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
@@ -451,7 +589,8 @@ spec:
|
||||
image: myorg/my-custom-awx
|
||||
image_version: latest
|
||||
image_pull_policy: Always
|
||||
image_pull_secret: pull_secret_name
|
||||
image_pull_secrets:
|
||||
- pull_secret_name
|
||||
ee_images:
|
||||
- name: my-custom-awx-ee
|
||||
image: myorg/my-custom-awx-ee
|
||||
@@ -497,11 +636,11 @@ Again, this is the most relaxed SCC that is provided by OpenShift, so be sure to
|
||||
|
||||
The resource requirements for both, the task and the web containers are configurable - both the lower end (requests) and the upper end (limits).
|
||||
|
||||
| Name | Description | Default |
|
||||
| -------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||
| web_resource_requirements | Web container resource requirements | requests: {cpu: 1000m, memory: 2Gi} |
|
||||
| task_resource_requirements | Task container resource requirements | requests: {cpu: 500m, memory: 1Gi} |
|
||||
| ee_resource_requirements | EE control plane container resource requirements | requests: {cpu: 500m, memory: 1Gi} |
|
||||
| Name | Description | Default |
|
||||
| -------------------------- | ------------------------------------------------ | ------------------------------------ |
|
||||
| web_resource_requirements | Web container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| task_resource_requirements | Task container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| ee_resource_requirements | EE control plane container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
@@ -511,42 +650,63 @@ spec:
|
||||
...
|
||||
web_resource_requirements:
|
||||
requests:
|
||||
cpu: 1000m
|
||||
cpu: 250m
|
||||
memory: 2Gi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
task_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
cpu: 250m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
cpu: 2000m
|
||||
memory: 2Gi
|
||||
ee_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
cpu: 250m
|
||||
memory: 100Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
cpu: 500m
|
||||
memory: 2Gi
|
||||
```
|
||||
|
||||
#### Priority Classes
|
||||
|
||||
The AWX and Postgres pods can be assigned a custom PriorityClass to rank their importance compared to other pods in your cluster, which determines which pods get evicted first if resources are running low.
|
||||
First, [create your PriorityClass](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass) if needed.
|
||||
Then set the name of your priority class to the control plane and postgres pods as shown below.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx-demo
|
||||
spec:
|
||||
...
|
||||
control_plane_priority_class: awx-demo-high-priority
|
||||
postgres_priority_class: awx-demo-medium-priority
|
||||
```
|
||||
|
||||
#### Assigning AWX pods to specific nodes
|
||||
|
||||
You can constrain the AWX pods created by the operator to run on a certain subset of nodes. `node_selector` and `postgres_selector` constrains
|
||||
the AWX pods to run only on the nodes that match all the specified key/value pairs. `tolerations` and `postgres_tolerations` allow the AWX
|
||||
pods to be scheduled onto nodes with matching taints.
|
||||
The ability to specify topologySpreadConstraints is also allowed through `topology_spread_constraints`
|
||||
|
||||
|
||||
| Name | Description | Default |
|
||||
| -------------------------------| --------------------------- | ------- |
|
||||
| postgres_image | Path of the image to pull | 12 |
|
||||
| postgres_image_version | Image version to pull | 12 |
|
||||
| node_selector | AWX pods' nodeSelector | '' |
|
||||
| tolerations | AWX pods' tolerations | '' |
|
||||
| postgres_selector | Postgres pods' nodeSelector | '' |
|
||||
| postgres_tolerations | Postgres pods' tolerations | '' |
|
||||
| Name | Description | Default |
|
||||
| --------------------------- | ----------------------------------- | ------- |
|
||||
| postgres_image | Path of the image to pull | postgres |
|
||||
| postgres_image_version | Image version to pull | 13 |
|
||||
| node_selector | AWX pods' nodeSelector | '' |
|
||||
| topology_spread_constraints | AWX pods' topologySpreadConstraints | '' |
|
||||
| tolerations | AWX pods' tolerations | '' |
|
||||
| annotations | AWX pods' annotations | '' |
|
||||
| postgres_selector | Postgres pods' nodeSelector | '' |
|
||||
| postgres_tolerations | Postgres pods' tolerations | '' |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
@@ -558,6 +718,13 @@ spec:
|
||||
disktype: ssd
|
||||
kubernetes.io/arch: amd64
|
||||
kubernetes.io/os: linux
|
||||
topology_spread_constraints: |
|
||||
- maxSkew: 100
|
||||
topologyKey: "topology.kubernetes.io/zone"
|
||||
whenUnsatisfiable: "ScheduleAnyway"
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: "<resourcename>"
|
||||
tolerations: |
|
||||
- key: "dedicated"
|
||||
operator: "Equal"
|
||||
@@ -584,8 +751,8 @@ Trusting a custom Certificate Authority allows the AWX to access network service
|
||||
| Name | Description | Default |
|
||||
| -------------------------------- | ---------------------------------------- | --------|
|
||||
| ldap_cacert_secret | LDAP Certificate Authority secret name | '' |
|
||||
| ldap_password_secret | LDAP BIND DN Password secret name | '' |
|
||||
| bundle_cacert_secret | Certificate Authority secret name | '' |
|
||||
|
||||
Please note the `awx-operator` will look for the data field `ldap-ca.crt` in the specified secret when using the `ldap_cacert_secret`, whereas the data field `bundle-ca.crt` is required for `bundle_cacert_secret` parameter.
|
||||
|
||||
Example of customization could be:
|
||||
@@ -595,10 +762,13 @@ Example of customization could be:
|
||||
spec:
|
||||
...
|
||||
ldap_cacert_secret: <resourcename>-custom-certs
|
||||
ldap_password_secret: <resourcename>-ldap-password
|
||||
bundle_cacert_secret: <resourcename>-custom-certs
|
||||
```
|
||||
|
||||
To create the secret, you can use the command below:
|
||||
To create the secrets, you can use the commands below:
|
||||
|
||||
* Certificate Authority secret
|
||||
|
||||
```
|
||||
# kubectl create secret generic <resourcename>-custom-certs \
|
||||
@@ -606,17 +776,77 @@ To create the secret, you can use the command below:
|
||||
--from-file=bundle-ca.crt=<PATH/TO/YOUR/CA/PEM/FILE>
|
||||
```
|
||||
|
||||
* LDAP BIND DN Password secret
|
||||
|
||||
```
|
||||
# kubectl create secret generic <resourcename>-ldap-password \
|
||||
--from-literal=ldap-password=<your_ldap_dn_password>
|
||||
```
|
||||
|
||||
#### Enabling LDAP Integration at AWX bootstrap
|
||||
|
||||
A sample of extra settings can be found as below:
|
||||
|
||||
```yaml
|
||||
- setting: AUTH_LDAP_SERVER_URI
|
||||
value: >-
|
||||
"ldaps://ad01.abc.com:636 ldaps://ad02.abc.com:636"
|
||||
|
||||
- setting: AUTH_LDAP_BIND_DN
|
||||
value: >-
|
||||
"CN=LDAP User,OU=Service Accounts,DC=abc,DC=com"
|
||||
|
||||
- setting: AUTH_LDAP_USER_SEARCH
|
||||
value: 'LDAPSearch("DC=abc,DC=com",ldap.SCOPE_SUBTREE,"(sAMAccountName=%(user)s)",)'
|
||||
|
||||
- setting: AUTH_LDAP_GROUP_SEARCH
|
||||
value: 'LDAPSearch("OU=Groups,DC=abc,DC=com",ldap.SCOPE_SUBTREE,"(objectClass=group)",)'
|
||||
|
||||
- setting: AUTH_LDAP_USER_ATTR_MAP
|
||||
value: '{"first_name": "givenName","last_name": "sn","email": "mail"}'
|
||||
|
||||
- setting: AUTH_LDAP_REQUIRE_GROUP
|
||||
value: >-
|
||||
"CN=operators,OU=Groups,DC=abc,DC=com"
|
||||
- setting: AUTH_LDAP_USER_FLAGS_BY_GROUP
|
||||
value: {
|
||||
"is_superuser": [
|
||||
"CN=admin,OU=Groups,DC=abc,DC=com"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
- setting: AUTH_LDAP_ORGANIZATION_MAP
|
||||
value: {
|
||||
"abc": {
|
||||
"admins": "CN=admin,OU=Groups,DC=abc,DC=com",
|
||||
"remove_users": false,
|
||||
"remove_admins": false,
|
||||
"users": true
|
||||
}
|
||||
}
|
||||
|
||||
- setting: AUTH_LDAP_TEAM_MAP
|
||||
value: {
|
||||
"admin": {
|
||||
"remove": true,
|
||||
"users": "CN=admin,OU=Groups,DC=abc,DC=com",
|
||||
"organization": "abc"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Persisting Projects Directory
|
||||
|
||||
In cases which you want to persist the `/var/lib/projects` directory, there are few variables that are customizable for the `awx-operator`.
|
||||
|
||||
| Name | Description | Default |
|
||||
| -----------------------------------| ---------------------------------------------------------------------------------------------------- | ---------------|
|
||||
| projects_persistence | Whether or not the /var/lib/projects directory will be persistent | false |
|
||||
| projects_storage_class | Define the PersistentVolume storage class | '' |
|
||||
| projects_storage_size | Define the PersistentVolume size | 8Gi |
|
||||
| projects_storage_access_mode | Define the PersistentVolume access mode | ReadWriteMany |
|
||||
| projects_existing_claim | Define an existing PersistentVolumeClaim to use (cannot be combined with `projects_storage_*`) | '' |
|
||||
| Name | Description | Default |
|
||||
| ---------------------------- | ---------------------------------------------------------------------------------------------- | ------------- |
|
||||
| projects_persistence | Whether or not the /var/lib/projects directory will be persistent | false |
|
||||
| projects_storage_class | Define the PersistentVolume storage class | '' |
|
||||
| projects_storage_size | Define the PersistentVolume size | 8Gi |
|
||||
| projects_storage_access_mode | Define the PersistentVolume access mode | ReadWriteMany |
|
||||
| projects_existing_claim | Define an existing PersistentVolumeClaim to use (cannot be combined with `projects_storage_*`) | '' |
|
||||
|
||||
Example of customization when the `awx-operator` automatically handles the persistent volume could be:
|
||||
|
||||
@@ -633,14 +863,14 @@ spec:
|
||||
|
||||
In a scenario where custom volumes and volume mounts are required to either overwrite defaults or mount configuration files.
|
||||
|
||||
| Name | Description | Default |
|
||||
| --------------------------------- | -------------------------------------------------------- | ------- |
|
||||
| extra_volumes | Specify extra volumes to add to the application pod | '' |
|
||||
| web_extra_volume_mounts | Specify volume mounts to be added to Web container | '' |
|
||||
| task_extra_volume_mounts | Specify volume mounts to be added to Task container | '' |
|
||||
| ee_extra_volume_mounts | Specify volume mounts to be added to Execution container | '' |
|
||||
| init_container_extra_volume_mounts| Specify volume mounts to be added to Init container | '' |
|
||||
| init_container_extra_commands | Specify additional commands for Init container | '' |
|
||||
| Name | Description | Default |
|
||||
| ---------------------------------- | -------------------------------------------------------- | ------- |
|
||||
| extra_volumes | Specify extra volumes to add to the application pod | '' |
|
||||
| web_extra_volume_mounts | Specify volume mounts to be added to Web container | '' |
|
||||
| task_extra_volume_mounts | Specify volume mounts to be added to Task container | '' |
|
||||
| ee_extra_volume_mounts | Specify volume mounts to be added to Execution container | '' |
|
||||
| init_container_extra_volume_mounts | Specify volume mounts to be added to Init container | '' |
|
||||
| init_container_extra_commands | Specify additional commands for Init container | '' |
|
||||
|
||||
|
||||
> :warning: The `ee_extra_volume_mounts` and `extra_volumes` will only take effect to the globally available Execution Environments. For custom `ee`, please [customize the Pod spec](https://docs.ansible.com/ansible-tower/latest/html/administration/external_execution_envs.html#customize-the-pod-spec).
|
||||
@@ -717,7 +947,7 @@ Example spec file for volumes and volume mounts
|
||||
|
||||
In order to register default execution environments from private registries, the Custom Resource needs to know about the pull credentials. Those credentials should be stored as a secret and either specified as `ee_pull_credentials_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-ee-pull-credentials` . Instance initialization will register a `Container registry` type credential on the deployed instance and assign it to the registered default execution environments.
|
||||
|
||||
The secret should be formated as follows:
|
||||
The secret should be formatted as follows:
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -735,13 +965,13 @@ type: Opaque
|
||||
```
|
||||
|
||||
##### Control plane ee from private registry
|
||||
The images listed in "ee_images" will be added as globally available Execution Environments. The "control_plane_ee_image" will be used to run project updates. In order to use a private image for any of these you'll need to use `image_pull_secret` to provide a k8s pull secret to access it. Currently the same secret is used for any of these images supplied at install time.
|
||||
The images listed in "ee_images" will be added as globally available Execution Environments. The "control_plane_ee_image" will be used to run project updates. In order to use a private image for any of these you'll need to use `image_pull_secrets` to provide a list of k8s pull secrets to access it. Currently the same secret is used for any of these images supplied at install time.
|
||||
|
||||
You can create `image_pull_secret`
|
||||
```
|
||||
kubectl create secret <resoucename>-cp-pull-credentials regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
|
||||
```
|
||||
If you need more control (for example, to set a namespace or a label on the new secret) then you can customise the Secret before storing it
|
||||
If you need more control (for example, to set a namespace or a label on the new secret) then you can customize the Secret before storing it
|
||||
|
||||
Example spec file extra-config
|
||||
|
||||
@@ -761,11 +991,11 @@ type: kubernetes.io/dockerconfigjson
|
||||
|
||||
If you need to export custom environment variables to your containers.
|
||||
|
||||
| Name | Description | Default |
|
||||
| ----------------------------- | -------------------------------------------------------- | ------- |
|
||||
| task_extra_env | Environment variables to be added to Task container | '' |
|
||||
| web_extra_env | Environment variables to be added to Web container | '' |
|
||||
| ee_extra_env | Environment variables to be added to EE container | '' |
|
||||
| Name | Description | Default |
|
||||
| -------------- | --------------------------------------------------- | ------- |
|
||||
| task_extra_env | Environment variables to be added to Task container | '' |
|
||||
| web_extra_env | Environment variables to be added to Web container | '' |
|
||||
| ee_extra_env | Environment variables to be added to EE container | '' |
|
||||
|
||||
> :warning: The `ee_extra_env` will only take effect to the globally available Execution Environments. For custom `ee`, please [customize the Pod spec](https://docs.ansible.com/ansible-tower/latest/html/administration/external_execution_envs.html#customize-the-pod-spec).
|
||||
|
||||
@@ -784,13 +1014,43 @@ Example configuration of environment variables
|
||||
value: foo
|
||||
```
|
||||
|
||||
#### CSRF Cookie Secure Setting
|
||||
|
||||
With `csrf_cookie_secure`, you can pass the value for `CSRF_COOKIE_SECURE` to `/etc/tower/settings.py`
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------ | ------------------ | ------- |
|
||||
| csrf_cookie_secure | CSRF Cookie Secure | '' |
|
||||
|
||||
Example configuration of the `csrf_cookie_secure` setting:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
csrf_cookie_secure: 'False'
|
||||
```
|
||||
|
||||
#### Session Cookie Secure Setting
|
||||
|
||||
With `session_cookie_secure`, you can pass the value for `SESSION_COOKIE_SECURE` to `/etc/tower/settings.py`
|
||||
|
||||
| Name | Description | Default |
|
||||
| --------------------- | --------------------- | ------- |
|
||||
| session_cookie_secure | Session Cookie Secure | '' |
|
||||
|
||||
Example configuration of the `session_cookie_secure` setting:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
session_cookie_secure: 'False'
|
||||
```
|
||||
|
||||
#### Extra Settings
|
||||
|
||||
With`extra_settings`, you can pass multiple custom settings via the `awx-operator`. The parameter `extra_settings` will be appended to the `/etc/tower/settings.py` and can be an alternative to the `extra_volumes` parameter.
|
||||
|
||||
| Name | Description | Default |
|
||||
| ----------------------------- | -------------------------------------------------------- | ------- |
|
||||
| extra_settings | Extra settings | '' |
|
||||
| Name | Description | Default |
|
||||
| -------------- | -------------- | ------- |
|
||||
| extra_settings | Extra settings | '' |
|
||||
|
||||
Example configuration of `extra_settings` parameter
|
||||
|
||||
@@ -804,13 +1064,64 @@ Example configuration of `extra_settings` parameter
|
||||
value: "cn=admin,dc=example,dc=com"
|
||||
```
|
||||
|
||||
#### No Log
|
||||
Configure no_log for tasks with no_log
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------ | -------------------- | ------- |
|
||||
| no_log | No log configuration | 'true' |
|
||||
|
||||
Example configuration of `no_log` parameter
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
no_log: 'true'
|
||||
```
|
||||
|
||||
#### Auto upgrade
|
||||
With this parameter you can influence the behavior during an operator upgrade.
|
||||
If set to `true`, the operator will upgrade the specific instance directly.
|
||||
When the value is set to `false`, and we have a running deployment, the operator will not update the AWX instance.
|
||||
This can be useful when you have multiple AWX instances which you want to upgrade step by step instead of all at once.
|
||||
|
||||
|
||||
| Name | Description | Default |
|
||||
| -------------| ---------------------------------- | ------- |
|
||||
| auto_upgrade | Automatic upgrade of AWX instances | true |
|
||||
|
||||
Example configuration of `auto_upgrade` parameter
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
auto_upgrade: true
|
||||
```
|
||||
|
||||
##### Upgrade of instances without auto upgrade
|
||||
|
||||
There are two ways to upgrade instances which are marked with the 'auto_upgrade: false' flag.
|
||||
|
||||
Changing flags:
|
||||
|
||||
- change the auto_upgrade flag on your AWX object to true
|
||||
- wait until the upgrade process of that instance is finished
|
||||
- change the auto_upgrade flag on your AWX object back to false
|
||||
|
||||
Delete the deployment:
|
||||
|
||||
- delete the deployment object of your AWX instance
|
||||
```
|
||||
$ kubectl -n awx delete deployment <yourInstanceName>
|
||||
```
|
||||
- wait until the instance gets redeployed
|
||||
|
||||
|
||||
#### Service Account
|
||||
|
||||
If you need to modify some `ServiceAccount` proprieties
|
||||
|
||||
| Name | Description | Default |
|
||||
| ----------------------------- | -------------------------------------------------------- | ------- |
|
||||
| service_account_annotations | Annotations to the ServiceAccount | '' |
|
||||
| Name | Description | Default |
|
||||
| --------------------------- | --------------------------------- | ------- |
|
||||
| service_account_annotations | Annotations to the ServiceAccount | '' |
|
||||
|
||||
Example configuration of environment variables
|
||||
|
||||
@@ -832,12 +1143,31 @@ awx.awx.ansible.com "awx-demo" deleted
|
||||
|
||||
Deleting an AWX instance will remove all related deployments and statefulsets, however, persistent volumes and secrets will remain. To enforce secrets also getting removed, you can use `garbage_collect_secrets: true`.
|
||||
|
||||
**Note**: If you ever intend to recover an AWX from an existing database you will need a copy of the secrets in order to perform a successful recovery.
|
||||
|
||||
### Upgrading
|
||||
|
||||
To upgrade AWX, it is recommended to upgrade the awx-operator to the version that maps to the desired version of AWX. To find the version of AWX that will be installed by the awx-operator by default, check the version specified in the `image_version` variable in `roles/installer/defaults/main.yml` for that particular release.
|
||||
|
||||
Apply the awx-operator.yml for that release to upgrade the operator, and in turn also upgrade your AWX deployment.
|
||||
|
||||
#### Backup
|
||||
|
||||
The first part of any upgrade should be a backup. Note, there are secrets in the pod which work in conjunction with the database. Having just a database backup without the required secrets will not be sufficient for recovering from an issue when upgrading to a new version. See the [backup role documentation](https://github.com/ansible/awx-operator/tree/devel/roles/backup) for information on how to backup your database and secrets. In the event you need to recover the backup see the [restore role documentation](https://github.com/ansible/awx-operator/tree/devel/roles/restore).
|
||||
|
||||
#### PostgreSQL Upgrade Considerations
|
||||
|
||||
If there is a PostgreSQL major version upgrade, after the data directory on the PVC is migrated to the new version, the old PVC is kept by default.
|
||||
This provides the ability to roll back if needed, but can take up extra storage space in your cluster unnecessarily. You can configure it to be deleted automatically
|
||||
after a successful upgrade by setting the following variable on the AWX spec.
|
||||
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
postgres_keep_pvc_after_upgrade: False
|
||||
```
|
||||
|
||||
|
||||
#### v0.14.0
|
||||
|
||||
##### Cluster-scope to Namespace-scope considerations
|
||||
@@ -849,6 +1179,21 @@ delete your existing `awx-operator` service account, role and role binding.
|
||||
|
||||
Starting with awx-operator 0.14.0, the project is now based on operator-sdk 1.x. You may need to manually delete your old operator Deployment to avoid issues.
|
||||
|
||||
##### Steps to upgrade
|
||||
|
||||
Delete your old AWX Operator and existing `awx-operator` service account, role and role binding in `default` namespace first:
|
||||
|
||||
```
|
||||
$ kubectl -n default delete deployment awx-operator
|
||||
$ kubectl -n default delete serviceaccount awx-operator
|
||||
$ kubectl -n default delete clusterrolebinding awx-operator
|
||||
$ kubectl -n default delete clusterrole awx-operator
|
||||
```
|
||||
|
||||
Then install the new AWX Operator by following the instructions in [Basic Install](#basic-install-on-existing-cluster). The `NAMESPACE` environment variable have to be the name of the namespace in which your old AWX instance resides.
|
||||
|
||||
Once the new AWX Operator is up and running, your AWX deployment will also be upgraded.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please visit [our contributing guidelines](https://github.com/ansible/awx-operator/blob/devel/CONTRIBUTING.md).
|
||||
@@ -856,47 +1201,26 @@ Please visit [our contributing guidelines](https://github.com/ansible/awx-operat
|
||||
|
||||
## Release Process
|
||||
|
||||
### Update version and files
|
||||
The first step is to create a draft release. Typically this will happen in the [Stage Release](https://github.com/ansible/awx/blob/devel/.github/workflows/stage.yml) workflow for AWX and you don't need to do it as a separate step.
|
||||
|
||||
Update the awx-operator version:
|
||||
If you need to do an independent release of the operator, you can run the [Stage Release](https://github.com/ansible/awx-operator/blob/devel/.github/workflows/stage.yml) in the awx-operator repo. Both of these workflows will run smoke tests, so there is no need to do this manually.
|
||||
|
||||
- `Makefile`
|
||||
After the draft release is created, publish it and the [Promote AWX Operator image](https://github.com/ansible/awx-operator/blob/devel/.github/workflows/promote.yaml) will run, which will:
|
||||
|
||||
### Verify Functionality
|
||||
|
||||
Run the following command inside this directory:
|
||||
|
||||
```
|
||||
$ IMAGE_TAG_BASE=quay.io/<user>/awx-operator make docker-build docker-push
|
||||
```
|
||||
|
||||
After it is built, test it on a local cluster:
|
||||
|
||||
```
|
||||
$ minikube start --memory 6g --cpus 4
|
||||
$ minikube addons enable ingress
|
||||
$ export NAMESPACE=example-awx
|
||||
$ make deploy
|
||||
$ ansible-playbook ansible/instantiate-awx-deployment.yml -e namespace=$NAMESPACE -e image=quay.io/<user>/awx -e service_type=nodeport
|
||||
$ # Verify that the awx-task and awx-web containers are launched
|
||||
$ # with the right version of the awx image
|
||||
$ # Launch a job at `minikube service awx-demo-service --url -n $NAMESPACE`
|
||||
$ minikube delete
|
||||
```
|
||||
|
||||
### Update changelog
|
||||
|
||||
Generate a list of commits between the versions and add it to the [changelog](./CHANGELOG.md).
|
||||
```
|
||||
$ git log --no-merges --pretty="- %s (%an) - %h " <old_tag>..<new_tag>
|
||||
```
|
||||
|
||||
### Commit / Create Release
|
||||
|
||||
If everything works, commit the updated version, then [publish a new release](https://github.com/ansible/awx-operator/releases/new) using the same version you used in `ansible/group_vars/all`.
|
||||
|
||||
After creating the release, [this GitHub Workflow](https://github.com/ansible/awx-operator/blob/devel/.github/workflows/release.yaml) will run and publish the new image to quay.io.
|
||||
- Publish image to Quay
|
||||
- Release Helm chart
|
||||
|
||||
## Author
|
||||
|
||||
This operator was originally built in 2019 by [Jeff Geerling](https://www.jeffgeerling.com) and is now maintained by the Ansible Team
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
We ask all of our community members and contributors to adhere to the [Ansible code of conduct](http://docs.ansible.com/ansible/latest/community/code_of_conduct.html). If you have questions or need assistance, please reach out to our community team at [codeofconduct@ansible.com](mailto:codeofconduct@ansible.com)
|
||||
|
||||
## Get Involved
|
||||
|
||||
We welcome your feedback and ideas. The AWX operator uses the same mailing list and IRC channel as AWX itself. Here's how to reach us with feedback and questions:
|
||||
|
||||
- Join the `#ansible-awx` channel on irc.libera.chat
|
||||
- Join the [mailing list](https://groups.google.com/forum/#!forum/awx-project)
|
||||
|
||||
3
SECURITY.md
Normal file
3
SECURITY.md
Normal file
@@ -0,0 +1,3 @@
|
||||
For all security related bugs, email security@ansible.com instead of using this issue tracker and you will receive a prompt response.
|
||||
|
||||
For more information on the Ansible community's practices regarding responsible disclosure, see https://www.ansible.com/security
|
||||
47
ansible/helm-release.yml
Normal file
47
ansible/helm-release.yml
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
vars:
|
||||
chart_repo: awx-operator
|
||||
tasks:
|
||||
- name: Look up release
|
||||
uri:
|
||||
url: "https://api.github.com/repos/{{ chart_owner }}/{{ chart_repo }}/releases/tags/{{ tag }}"
|
||||
register: release
|
||||
ignore_errors: yes
|
||||
|
||||
- fail:
|
||||
msg: |
|
||||
Release must exist before running this playbook
|
||||
when: release is not success
|
||||
|
||||
- name: Build and package helm chart
|
||||
command: |
|
||||
make helm-chart 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=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: Publish helm index
|
||||
command: |
|
||||
make helm-index
|
||||
environment:
|
||||
CHART_OWNER: "{{ chart_owner }}"
|
||||
CR_TOKEN: "{{ gh_token }}"
|
||||
args:
|
||||
chdir: "{{ playbook_dir }}/../"
|
||||
@@ -67,6 +67,9 @@ spec:
|
||||
extra_volumes:
|
||||
description: Specify extra volumes to add to the application pod
|
||||
type: string
|
||||
service_annotations:
|
||||
description: Annotations to add to the service
|
||||
type: string
|
||||
service_type:
|
||||
description: The service type to be used on the deployed instance
|
||||
type: string
|
||||
@@ -98,9 +101,6 @@ spec:
|
||||
ingress_tls_secret:
|
||||
description: Secret where the Ingress TLS secret can be found
|
||||
type: string
|
||||
loadbalancer_annotations:
|
||||
description: Annotations to add to the loadbalancer
|
||||
type: string
|
||||
loadbalancer_protocol:
|
||||
description: Protocol to use for the loadbalancer
|
||||
type: string
|
||||
@@ -134,9 +134,15 @@ spec:
|
||||
node_selector:
|
||||
description: nodeSelector for the pods
|
||||
type: string
|
||||
topology_spread_constraints:
|
||||
description: topology rule(s) for the pods
|
||||
type: string
|
||||
service_labels:
|
||||
description: Additional labels to apply to the service
|
||||
type: string
|
||||
annotations:
|
||||
description: annotations for the pods
|
||||
type: string
|
||||
tolerations:
|
||||
description: node tolerations for the pods
|
||||
type: string
|
||||
@@ -159,6 +165,9 @@ spec:
|
||||
control_plane_ee_image:
|
||||
description: Registry path to the Execution Environment container image to use on control plane pods
|
||||
type: string
|
||||
control_plane_priority_class:
|
||||
description: Assign a preexisting priority class to the control plane pods
|
||||
type: string
|
||||
ee_pull_credentials_secret:
|
||||
description: Secret where pull credentials for registered ees can be found
|
||||
type: string
|
||||
@@ -173,8 +182,13 @@ spec:
|
||||
- never
|
||||
- IfNotPresent
|
||||
- ifnotpresent
|
||||
image_pull_secret:
|
||||
description: The image pull secret
|
||||
image_pull_secrets:
|
||||
description: Image pull secrets for app and database containers
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
image_pull_secret: # deprecated
|
||||
description: (Deprecated) Image pull secret for app and database containers
|
||||
type: string
|
||||
task_resource_requirements:
|
||||
description: Resource requirements for the task container
|
||||
@@ -242,6 +256,50 @@ spec:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
postgres_init_container_resource_requirements:
|
||||
description: Resource requirements for the postgres init container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
redis_resource_requirements:
|
||||
description: Resource requirements for the redis container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
service_account_annotations:
|
||||
description: ServiceAccount annotations
|
||||
type: string
|
||||
@@ -321,6 +379,9 @@ spec:
|
||||
postgres_selector:
|
||||
description: nodeSelector for the Postgres pods
|
||||
type: string
|
||||
postgres_keep_pvc_after_upgrade:
|
||||
description: Specify whether or not to keep the old PVC after PostgreSQL upgrades
|
||||
type: boolean
|
||||
postgres_tolerations:
|
||||
description: node tolerations for the Postgres pods
|
||||
type: string
|
||||
@@ -359,9 +420,16 @@ spec:
|
||||
postgres_storage_class:
|
||||
description: Storage class to use for the PostgreSQL PVC
|
||||
type: string
|
||||
postgres_priority_class:
|
||||
description: Assign a preexisting priority class to the postgres pod
|
||||
type: string
|
||||
postgres_data_path:
|
||||
description: Path where the PostgreSQL data are located
|
||||
type: string
|
||||
postgres_extra_args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
ca_trust_bundle:
|
||||
description: Path where the trusted CA bundle is available
|
||||
type: string
|
||||
@@ -371,6 +439,9 @@ spec:
|
||||
ldap_cacert_secret:
|
||||
description: Secret where can be found the LDAP trusted Certificate Authority Bundle
|
||||
type: string
|
||||
ldap_password_secret:
|
||||
description: Secret where can be found the LDAP bind password
|
||||
type: string
|
||||
bundle_cacert_secret:
|
||||
description: Secret where can be found the trusted Certificate Authority Bundle
|
||||
type: string
|
||||
@@ -398,6 +469,12 @@ spec:
|
||||
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
|
||||
default: ReadWriteMany
|
||||
type: string
|
||||
csrf_cookie_secure:
|
||||
description: Set csrf cookie secure mode for web
|
||||
type: string
|
||||
session_cookie_secure:
|
||||
description: Set session cookie secure mode for web
|
||||
type: string
|
||||
extra_settings:
|
||||
description: Extra settings to specify for the API
|
||||
items:
|
||||
@@ -408,10 +485,21 @@ spec:
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
no_log:
|
||||
description: Configure no_log for no_log tasks
|
||||
type: string
|
||||
security_context_settings:
|
||||
description: Key/values that will be set under the pod-level securityContext field
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
auto_upgrade:
|
||||
description: Should AWX instances be automatically upgraded when operator gets upgraded
|
||||
type: boolean
|
||||
default: true
|
||||
set_self_labels:
|
||||
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
type: boolean
|
||||
default: true
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
@@ -434,7 +522,10 @@ spec:
|
||||
description: Secret key secret name of the deployed instance
|
||||
type: string
|
||||
migratedFromSecret:
|
||||
description: The secret used for migrating an old instance.
|
||||
description: The secret used for migrating an old instance
|
||||
type: string
|
||||
upgradedPostgresVersion:
|
||||
description: Status to indicate that the database has been upgraded to the version in the status
|
||||
type: string
|
||||
version:
|
||||
description: Version of the deployed instance
|
||||
|
||||
@@ -32,17 +32,20 @@ spec:
|
||||
description: Name of the deployment to be backed up
|
||||
type: string
|
||||
backup_pvc:
|
||||
description: Name of the PVC to be used for storing the backup
|
||||
description: Name of the backup PVC
|
||||
type: string
|
||||
backup_pvc_namespace:
|
||||
description: Namespace the PVC is in
|
||||
description: (Deprecated) Namespace the PVC is in
|
||||
type: string
|
||||
backup_storage_requirements:
|
||||
description: Storage requirements for the PostgreSQL container
|
||||
description: Storage requirements for backup PVC (may be similar to existing postgres PVC backing up from)
|
||||
type: string
|
||||
backup_storage_class:
|
||||
description: Storage class to use when creating PVC for backup
|
||||
type: string
|
||||
clean_backup_on_delete:
|
||||
description: Flag to indicate if backup should be deleted on PVC if AWXBackup object is deleted
|
||||
type: boolean
|
||||
postgres_label_selector:
|
||||
description: Label selector used to identify postgres pod for backing up data
|
||||
type: string
|
||||
@@ -52,6 +55,13 @@ spec:
|
||||
postgres_image_version:
|
||||
description: PostgreSQL container image version to use
|
||||
type: string
|
||||
no_log:
|
||||
description: Configure no_log for no_log tasks
|
||||
type: string
|
||||
set_self_labels:
|
||||
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
type: boolean
|
||||
default: true
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -33,7 +33,8 @@ spec:
|
||||
- CR
|
||||
- PVC
|
||||
deployment_name:
|
||||
description: Name of the deployment to be restored to
|
||||
description: Name of the restored deployment. This should be different from the original deployment name
|
||||
if the original deployment still exists.
|
||||
type: string
|
||||
backup_name:
|
||||
description: AWXBackup object name
|
||||
@@ -42,7 +43,7 @@ spec:
|
||||
description: Name of the PVC to be restored from, set as a status found on the awxbackup object (backupClaim)
|
||||
type: string
|
||||
backup_pvc_namespace:
|
||||
description: Namespace the PVC is in
|
||||
description: (Deprecated) Namespace the PVC is in
|
||||
type: string
|
||||
backup_dir:
|
||||
description: Backup directory name, set as a status found on the awxbackup object (backupDirectory)
|
||||
@@ -56,6 +57,13 @@ spec:
|
||||
postgres_image_version:
|
||||
description: PostgreSQL container image version to use
|
||||
type: string
|
||||
no_log:
|
||||
description: Configure no_log for no_log tasks
|
||||
type: string
|
||||
set_self_labels:
|
||||
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
type: boolean
|
||||
default: true
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -34,6 +34,8 @@ spec:
|
||||
env:
|
||||
- name: ANSIBLE_GATHERING
|
||||
value: explicit
|
||||
- name: ANSIBLE_DEBUG_LOGS
|
||||
value: 'false'
|
||||
- name: WATCH_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
@@ -52,5 +54,14 @@ spec:
|
||||
port: 6789
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
requests:
|
||||
memory: "32Mi"
|
||||
cpu: "50m"
|
||||
limits:
|
||||
memory: "4096Mi"
|
||||
cpu: "2000m"
|
||||
serviceAccountName: controller-manager
|
||||
imagePullSecrets:
|
||||
- name: redhat-operators-pull-secret
|
||||
terminationGracePeriodSeconds: 10
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,24 +0,0 @@
|
||||
'''
|
||||
After generating the CSV file, inject custom configuration such as
|
||||
OLM parameters, relatedImages, etc.
|
||||
'''
|
||||
|
||||
import yaml
|
||||
|
||||
csv_path = "../../../bundle/manifests/awx-operator.clusterserviceversion.yaml"
|
||||
existing_csv = open(csv_path, 'r')
|
||||
csv = yaml.safe_load(existing_csv)
|
||||
|
||||
|
||||
raw_olm_params = open("olm-parameters.yaml")
|
||||
olm_params = yaml.safe_load(raw_olm_params)
|
||||
|
||||
# Inject OLM parameters for Customer Resource Objects
|
||||
csv['spec']['customresourcedefinitions']['owned'] = olm_params
|
||||
|
||||
csv['metadata']['annotations']['alm-examples'] = ''
|
||||
|
||||
file_content = yaml.safe_dump(csv, default_flow_style=False, explicit_start=True)
|
||||
|
||||
with open(csv_path, 'w') as f:
|
||||
f.write(file_content)
|
||||
@@ -1,594 +0,0 @@
|
||||
---
|
||||
- displayName: AWX Backup
|
||||
description: Back up a deployment of the awx, including jobs, inventories, and credentials
|
||||
kind: AWXBackup
|
||||
name: awxbackups.awx.ansible.com
|
||||
version: v1beta1
|
||||
specDescriptors:
|
||||
- displayName: Deployment name
|
||||
path: deployment_name
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Backup persistent volume claim
|
||||
path: backup_pvc
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- displayName: Backup persistent volume claim namespace
|
||||
path: backup_pvc_namespace
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- displayName: Backup PVC storage requirements
|
||||
path: backup_storage_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- displayName: Backup PVC storage class
|
||||
path: backup_storage_class
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- displayName: Database backup label selector
|
||||
path: postgres_label_selector
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image
|
||||
path: postgres_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image Version
|
||||
path: postgres_image_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
statusDescriptors:
|
||||
- description: The persistent volume claim name used during backup
|
||||
displayName: Backup claim
|
||||
path: backupClaim
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: The directory data is backed up to on the PVC
|
||||
displayName: Backup directory
|
||||
path: backupDirectory
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: AWX Restore
|
||||
description: Restore a previous awx deployment into the namespace
|
||||
kind: AWXRestore
|
||||
name: awxrestores.awx.ansible.com
|
||||
version: v1beta1
|
||||
specDescriptors:
|
||||
- displayName: Backup source to restore ?
|
||||
path: backup_source
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:CR
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:PVC
|
||||
- displayName: Backup name
|
||||
path: backup_name
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:CR
|
||||
- displayName: Name of newly restored deployment
|
||||
path: deployment_name
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Backup persistent volume claim
|
||||
path: backup_pvc
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:PVC
|
||||
- displayName: Backup namespace
|
||||
path: backup_pvc_namespace
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Backup directory in the persistent volume claim
|
||||
path: backup_dir
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:backup_source:PVC
|
||||
- displayName: Database restore label selector
|
||||
path: postgres_label_selector
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image
|
||||
path: postgres_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image Version
|
||||
path: postgres_image_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
statusDescriptors:
|
||||
- description: The state of the restore
|
||||
displayName: Restore status
|
||||
path: restoreComplete
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Deploy a new instance of AWX
|
||||
displayName: AWX
|
||||
kind: AWX
|
||||
name: awxs.awx.ansible.com
|
||||
version: v1beta1
|
||||
specDescriptors:
|
||||
- displayName: Hostname
|
||||
path: hostname
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Admin account username
|
||||
path: admin_user
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Admin email address
|
||||
path: admin_email
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Admin password secret
|
||||
path: admin_password_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Database configuration secret
|
||||
path: postgres_configuration_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Old Database configuration secret
|
||||
path: old_postgres_configuration_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Secret key secret
|
||||
path: secret_key_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Broadcast Websocket Secret
|
||||
path: broadcast_websocket_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Service Account Annotations
|
||||
path: service_account_annotations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Tower Service Type
|
||||
path: service_type
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:ClusterIP
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:LoadBalancer
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:NodePort
|
||||
- displayName: Tower Ingress Type
|
||||
path: ingress_type
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:none
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Ingress
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Route
|
||||
- displayName: Ingress Path
|
||||
path: ingress_path
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
|
||||
- displayName: Ingress Path Type
|
||||
path: ingress_path_type
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
|
||||
- displayName: Tower Ingress Annotations
|
||||
path: ingress_annotations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
|
||||
- displayName: Tower Ingress TLS Secret
|
||||
path: ingress_tls_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
|
||||
- displayName: Tower LoadBalancer Annotations
|
||||
path: loadbalancer_annotations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:service_type:LoadBalancer
|
||||
- displayName: Tower LoadBalancer Protocol
|
||||
path: loadbalancer_protocol
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:http
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:https
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:service_type:LoadBalancer
|
||||
- displayName: Tower LoadBalancer Port
|
||||
path: loadbalancer_port
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:number
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:service_type:LoadBalancer
|
||||
- displayName: Route DNS host
|
||||
path: route_host
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Route
|
||||
- displayName: Route TLS termination mechanism
|
||||
path: route_tls_termination_mechanism
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Edge
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Passthrough
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Route
|
||||
- displayName: Route TLS credential secret
|
||||
path: route_tls_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Route
|
||||
- displayName: Image Pull Policy
|
||||
path: image_pull_policy
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:imagePullPolicy
|
||||
- displayName: Image Pull Secret
|
||||
path: image_pull_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Web container resource requirements
|
||||
path: web_resource_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: Task container resource requirements
|
||||
path: task_resource_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: EE Control Plane container resource requirements
|
||||
path: ee_resource_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: PostgreSQL container resource requirements (when using a managed
|
||||
instance)
|
||||
path: postgres_resource_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: PostgreSQL container storage requirements (when using a managed
|
||||
instance)
|
||||
path: postgres_storage_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: Replicas
|
||||
path: replicas
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:number
|
||||
- displayName: Remove used secrets on instance removal ?
|
||||
path: garbage_collect_secrets
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- displayName: Preload instance with data upon creation ?
|
||||
path: create_preload_data
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- displayName: Deploy the instance in development mode ?
|
||||
path: development_mode
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Should the task container deployed with privileged level ?
|
||||
path: task_privileged
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Deployment Type
|
||||
path: deployment_type
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Deployment Kind
|
||||
path: kind
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Deployment apiVersion
|
||||
path: api_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Image
|
||||
path: image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Image Version
|
||||
path: image_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Redis Image
|
||||
path: redis_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Redis Image Version
|
||||
path: redis_image_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Redis Capabilities
|
||||
path: redis_capabilities
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image
|
||||
path: postgres_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image Version
|
||||
path: postgres_image_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Postgres Selector
|
||||
path: postgres_selector
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Postgres Label Selector
|
||||
path: postgres_label_selector
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Postgres Tolerations
|
||||
path: postgres_tolerations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Postgres Storage Class
|
||||
path: postgres_storage_class
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Postgres Datapath
|
||||
path: postgres_data_path
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Certificate Authorirty Trust Bundle
|
||||
path: ca_trust_bundle
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: LDAP Certificate Authority Trust Bundle
|
||||
path: ldap_cacert_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Task Args
|
||||
path: task_args
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Enable persistence for /var/lib/projects directory?
|
||||
path: projects_persistence
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- displayName: Use existing Persistent Claim?
|
||||
path: projects_use_existing_claim
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:_Yes_
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_persistence:true
|
||||
- displayName: Projects Existing Persistent Claim
|
||||
path: projects_existing_claim
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_Yes_
|
||||
- urn:alm:descriptor:io.kubernetes:PersistentVolumeClaim
|
||||
- description: Projects Storage Class Name. If not present, the default storage
|
||||
class will be used.
|
||||
displayName: Projects Storage Class Name
|
||||
path: projects_storage_class
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Projects Storage Size
|
||||
displayName: Projects Storage Size
|
||||
path: projects_storage_size
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Projects Storage Access Mode
|
||||
displayName: Projects Storage Access Mode
|
||||
path: projects_storage_access_mode
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:projects_use_existing_claim:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Task Command
|
||||
path: task_command
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Environment variables to be added to Task container
|
||||
displayName: Task Extra Env
|
||||
path: task_extra_env
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Specify volume mounts to be added to Execution container
|
||||
displayName: EE Extra Volume Mounts
|
||||
path: ee_extra_volume_mounts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Registry path to the Execution Environment container to use
|
||||
displayName: EE Images
|
||||
path: ee_images
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Environment variables to be added to EE container
|
||||
displayName: EE Extra Env
|
||||
path: ee_extra_env
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Registry path to the Execution Environment container to use on
|
||||
control plane pods
|
||||
displayName: Control Plane EE Image
|
||||
path: control_plane_ee_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: EE Images Pull Credentials Secret
|
||||
displayName: EE Images Pull Credentials Secret
|
||||
path: ee_pull_credentials_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- description: Specify volume mounts to be added to Task container
|
||||
displayName: Task Extra Volume Mounts
|
||||
path: task_extra_volume_mounts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Web Args
|
||||
path: web_args
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Web Command
|
||||
path: web_command
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Environment variables to be added to Web container
|
||||
displayName: Web Extra Env
|
||||
path: web_extra_env
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Specify volume mounts to be added to Web container
|
||||
displayName: Web Extra Volume Mounts
|
||||
path: web_extra_volume_mounts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Specify extra volumes to add to the application pod
|
||||
displayName: Extra Volumes
|
||||
path: extra_volumes
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Node Selector
|
||||
path: node_selector
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Service Labels
|
||||
path: service_labels
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tolerations
|
||||
path: tolerations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: API Extra Settings
|
||||
path: extra_settings
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Security Context Settings
|
||||
path: security_context_settings
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Registry path to the init container to use
|
||||
displayName: Init Container Image
|
||||
path: init_container_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Init container image version to use
|
||||
displayName: Init Container Image Version
|
||||
path: init_container_image_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Specify Extra commands for the Init container
|
||||
displayName: Init Container Extra Commands
|
||||
path: init_container_extra_commands
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Specify volume mounts to be added to Init container
|
||||
displayName: Init Container Extra Volume Mounts
|
||||
path: init_container_extra_volume_mounts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Secret where can be found the trusted Certificate Authority Bundle
|
||||
path: bundle_cacert_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Nodeport Port
|
||||
path: nodeport_port
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
statusDescriptors:
|
||||
- description: Route to access the instance deployed
|
||||
displayName: URL
|
||||
path: URL
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:org.w3:link
|
||||
- description: Admin user for the instance deployed
|
||||
displayName: Admin User
|
||||
path: adminUser
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Admin password for the instance deployed
|
||||
displayName: Admin Password
|
||||
path: adminPasswordSecret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- description: Version of the instance deployed
|
||||
displayName: Version
|
||||
path: version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Image of the instance deployed
|
||||
displayName: Image
|
||||
path: image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
@@ -6,13 +6,13 @@ metadata:
|
||||
spec:
|
||||
web_resource_requirements:
|
||||
requests:
|
||||
cpu: 250m
|
||||
cpu: 50m
|
||||
memory: 128M
|
||||
task_resource_requirements:
|
||||
requests:
|
||||
cpu: 250m
|
||||
cpu: 50m
|
||||
memory: 128M
|
||||
ee_resource_requirements:
|
||||
requests:
|
||||
cpu: 200m
|
||||
cpu: 50m
|
||||
memory: 64M
|
||||
|
||||
51
docs/debugging.md
Normal file
51
docs/debugging.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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.
|
||||
|
||||
Install some dependencies:
|
||||
|
||||
```
|
||||
$ ansible-galaxy collection install -r molecule/requirements.yml
|
||||
$ pip install -r molecule/requirements.txt
|
||||
```
|
||||
|
||||
To prevent the changes we're about to make from being overwritten, scale down any running instance of the operator:
|
||||
|
||||
```
|
||||
$ kubectl scale deployment awx-operator-controller-manager --replicas=0
|
||||
```
|
||||
|
||||
Create a playbook that invokes the installer role (the operator uses ansible-runner's role execution feature):
|
||||
|
||||
```yaml
|
||||
# run.yml
|
||||
---
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- installer
|
||||
```
|
||||
|
||||
Create a vars file:
|
||||
|
||||
```yaml
|
||||
# vars.yml
|
||||
---
|
||||
ansible_operator_meta:
|
||||
name: awx
|
||||
namespace: awx
|
||||
service_type: nodeport
|
||||
```
|
||||
|
||||
Run the installer:
|
||||
|
||||
```
|
||||
$ ansible-playbook run.yml -e @vars.yml -v
|
||||
```
|
||||
|
||||
Grab the URL and admin password:
|
||||
|
||||
```
|
||||
$ minikube service awx-service --url -n awx
|
||||
$ minikube kubectl get secret awx-admin-password -- -o jsonpath="{.data.password}" | base64 --decode
|
||||
LU6lTfvnkjUvDwL240kXKy1sNhjakZmT
|
||||
```
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
- name: Build kustomize testing overlay
|
||||
# load_restrictor must be set to none so we can load patch files from the default overlay
|
||||
command: '{{ kustomize }} build --load_restrictor none .'
|
||||
command: '{{ kustomize }} build --load-restrictor LoadRestrictionsNone .'
|
||||
args:
|
||||
chdir: '{{ config_dir }}/testing'
|
||||
register: resources
|
||||
|
||||
@@ -23,6 +23,7 @@ provisioner:
|
||||
localhost:
|
||||
awx_image: ${AWX_TEST_IMAGE:-""}
|
||||
awx_version: ${AWX_TEST_VERSION:-""}
|
||||
default_awx_version: "{{ lookup('url', 'https://api.github.com/repos/ansible/awx/releases/latest') | from_json | json_query('tag_name') }}"
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config
|
||||
samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples
|
||||
|
||||
@@ -19,18 +19,43 @@
|
||||
register: admin_pw_secret
|
||||
|
||||
- block:
|
||||
- name: Get pod details
|
||||
k8s_info:
|
||||
namespace: '{{ namespace }}'
|
||||
kind: Pod
|
||||
label_selectors:
|
||||
- app.kubernetes.io/name = example-awx
|
||||
register: awx_pod
|
||||
when: not awx_version
|
||||
|
||||
- name: Exract tags from images
|
||||
set_fact:
|
||||
image_tags: |
|
||||
{{ awx_pod.resources[0].spec.containers |
|
||||
map(attribute='image') |
|
||||
map('regex_search', default_awx_version) }}
|
||||
when: not awx_version
|
||||
|
||||
- fail:
|
||||
msg: |
|
||||
It looks like you may have broken the DEFAULT_AWX_VERSION functionality.
|
||||
This is an environment variable that is set via build arg when releasing awx-operator.
|
||||
when:
|
||||
- not awx_version
|
||||
- default_awx_version not in image_tags
|
||||
|
||||
- name: Launch Demo Job Template
|
||||
awx.awx.job_launch:
|
||||
name: Demo Job Template
|
||||
wait: yes
|
||||
validate_certs: no
|
||||
controller_host: localhost
|
||||
controller_host: localhost/awx/
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_pw_secret.resources[0].data.password | b64decode }}"
|
||||
rescue:
|
||||
- name: Get list of project updates and jobs
|
||||
uri:
|
||||
url: "http://localhost/api/v2/{{ item }}/"
|
||||
url: "http://localhost/awx/api/v2/{{ resource }}/"
|
||||
user: admin
|
||||
password: "{{ admin_pw_secret.resources[0].data.password | b64decode }}"
|
||||
force_basic_auth: yes
|
||||
@@ -38,15 +63,19 @@
|
||||
loop:
|
||||
- project_updates
|
||||
- jobs
|
||||
loop_control:
|
||||
loop_var: resource
|
||||
|
||||
- name: Get all job and project details
|
||||
uri:
|
||||
url: "http://localhost{{ item }}"
|
||||
url: "http://localhost{{ endpoint }}"
|
||||
user: admin
|
||||
password: "{{ admin_pw_secret.resources[0].data.password | b64decode }}"
|
||||
force_basic_auth: yes
|
||||
loop: |
|
||||
{{ job_lists.results | map(attribute='json') | map(attribute='results') | flatten | map(attribute='url') }}
|
||||
loop_control:
|
||||
loop_var: endpoint
|
||||
|
||||
- name: Re-emit failure
|
||||
vars:
|
||||
|
||||
@@ -11,17 +11,21 @@ spec:
|
||||
image_version: {{ awx_version }}
|
||||
{% endif %}
|
||||
ingress_type: ingress
|
||||
ingress_path: /awx
|
||||
ingress_annotations: |
|
||||
kubernetes.io/ingress.class: nginx
|
||||
web_resource_requirements:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 128M
|
||||
cpu: 50m
|
||||
memory: 32M
|
||||
task_resource_requirements:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 128M
|
||||
cpu: 50m
|
||||
memory: 32M
|
||||
ee_resource_requirements:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 64M
|
||||
cpu: 50m
|
||||
memory: 16M
|
||||
postgres_resource_requirements: {}
|
||||
postgres_init_container_resource_requirements: {}
|
||||
redis_resource_requirements: {}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
build:
|
||||
path: '{{ project_dir }}'
|
||||
pull: no
|
||||
args:
|
||||
DEFAULT_AWX_VERSION: '{{ default_awx_version }}'
|
||||
name: '{{ operator_image }}'
|
||||
tag: latest
|
||||
push: no
|
||||
|
||||
@@ -26,6 +26,7 @@ provisioner:
|
||||
awx_image: ${AWX_TEST_IMAGE:-""}
|
||||
awx_version: ${AWX_TEST_VERSION:-""}
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
default_awx_version: "{{ lookup('url', 'https://api.github.com/repos/ansible/awx/releases/latest') | from_json | json_query('tag_name') }}"
|
||||
config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config
|
||||
samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples
|
||||
project_dir: ${MOLECULE_PROJECT_DIRECTORY}
|
||||
|
||||
@@ -2,6 +2,6 @@ molecule
|
||||
molecule-docker
|
||||
yamllint
|
||||
ansible-lint
|
||||
openshift
|
||||
openshift!=0.13.0
|
||||
jmespath
|
||||
ansible-core
|
||||
|
||||
@@ -60,13 +60,7 @@ backup_storage_class: 'standard'
|
||||
backup_storage_requirements: '20Gi'
|
||||
```
|
||||
|
||||
By default, the backup pvc will be created in the same namespace the awxbackup object is created in. If you want your backup to be stored
|
||||
in a specific namespace, you can do so by specifying `backup_pvc_namespace`. Keep in mind that you will
|
||||
need to provide the same namespace when restoring.
|
||||
|
||||
```
|
||||
backup_pvc_namespace: 'custom-namespace'
|
||||
```
|
||||
The backup pvc will be created in the same namespace the awxbackup object is created in.
|
||||
|
||||
If a custom postgres configuration secret was used when deploying AWX, it will automatically be used by the backup role.
|
||||
To check the name of this secret, look at the postgresConfigurationSecret status on your AWX object.
|
||||
@@ -74,7 +68,12 @@ To check the name of this secret, look at the postgresConfigurationSecret status
|
||||
The postgresql pod for the old deployment is used when backing up data to the new postgresql pod. If your postgresql pod has a custom label,
|
||||
you can pass that via the `postgres_label_selector` variable to make sure the postgresql pod can be found.
|
||||
|
||||
It is also possible to tie the lifetime of the backup files to that of the AWXBackup resource object. To do that you can set the
|
||||
`clean_backup_on_delete` value to true. This will delete the `backupDirectory` on the pvc associated with the AWXBackup object deleted.
|
||||
|
||||
```
|
||||
clean_backup_on_delete: true
|
||||
```
|
||||
Testing
|
||||
----------------
|
||||
|
||||
|
||||
@@ -10,3 +10,18 @@ backup_pvc_namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
|
||||
# Size of backup PVC if created dynamically
|
||||
backup_storage_requirements: ''
|
||||
|
||||
# Set no_log settings on certain tasks
|
||||
no_log: 'true'
|
||||
|
||||
# Variable to set when you want backups to be cleaned up when the CRD object is deleted
|
||||
clean_backup_on_delete: false
|
||||
|
||||
# Variable to signal that this role is being run as a finalizer
|
||||
finalizer_run: false
|
||||
|
||||
# Allow additional parameters to be added to the pg_dump backup command
|
||||
pg_dump_suffix: ''
|
||||
|
||||
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
set_self_labels: true
|
||||
|
||||
48
roles/backup/tasks/creation.yml
Normal file
48
roles/backup/tasks/creation.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
- name: Patching labels to {{ kind }} kind
|
||||
k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: "{{ api_version }}"
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
metadata:
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
labels:
|
||||
app.kubernetes.io/name: "{{ ansible_operator_meta.name }}"
|
||||
app.kubernetes.io/part-of: "{{ ansible_operator_meta.name }}"
|
||||
app.kubernetes.io/managed-by: "{{ deployment_type }}-operator"
|
||||
app.kubernetes.io/component: "{{ deployment_type }}"
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
when: set_self_labels | bool
|
||||
|
||||
- name: Look up details for this backup object
|
||||
k8s_info:
|
||||
api_version: "{{ api_version }}"
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: this_backup
|
||||
|
||||
- block:
|
||||
- include_tasks: init.yml
|
||||
|
||||
- include_tasks: postgres.yml
|
||||
|
||||
- include_tasks: awx-cro.yml
|
||||
|
||||
- include_tasks: secrets.yml
|
||||
|
||||
- name: Set flag signifying this backup was successful
|
||||
set_fact:
|
||||
backup_complete: true
|
||||
|
||||
- include_tasks: cleanup.yml
|
||||
|
||||
when:
|
||||
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
|
||||
|
||||
- name: Update status variables
|
||||
include_tasks: update_status.yml
|
||||
7
roles/backup/tasks/delete_backup.yml
Normal file
7
roles/backup/tasks/delete_backup.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: Cleanup backup associated with this option if enabled
|
||||
k8s_exec:
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
bash -c 'rm -rf {{ backup_dir }}'
|
||||
@@ -25,15 +25,15 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: "{{ _name }}"
|
||||
register: _secret
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set secret data
|
||||
set_fact:
|
||||
_data: "{{ _secret['resources'][0]['data'] }}"
|
||||
_type: "{{ _secret['resources'][0]['type'] }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create and Add secret names and data to dictionary
|
||||
set_fact:
|
||||
secret_dict: "{{ secret_dict | default({}) | combine({ item: {'name': _name, 'data': _data, 'type': _type }}) }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: "{{ _name }}"
|
||||
register: _secret
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set secret key
|
||||
set_fact:
|
||||
_data: "{{ _secret['resources'][0]['data'] }}"
|
||||
_type: "{{ _secret['resources'][0]['type'] }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create and Add secret names and data to dictionary
|
||||
set_fact:
|
||||
secret_dict: "{{ secret_dict | default({}) | combine({item: { 'name': _name, 'data': _data, 'type': _type }}) }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: _name != ''
|
||||
|
||||
19
roles/backup/tasks/finalizer.yml
Normal file
19
roles/backup/tasks/finalizer.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
- name: Look up details for this backup object
|
||||
k8s_info:
|
||||
api_version: "{{ api_version }}"
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: this_backup
|
||||
|
||||
- block:
|
||||
- include_tasks: init.yml
|
||||
|
||||
- include_tasks: delete_backup.yml
|
||||
|
||||
- include_tasks: cleanup.yml
|
||||
vars:
|
||||
backup_dir: "{{ this_backup['resources'][0]['status']['backupDirectory'] }}"
|
||||
when:
|
||||
- clean_backup_on_delete and backup_dir is defined
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
|
||||
- name: Delete any existing management pod
|
||||
k8s:
|
||||
name: "{{ ansible_operator_meta.name }}-db-management"
|
||||
@@ -57,8 +56,8 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: '{{ deployment_name }}-backup-claim'
|
||||
namespace: '{{ backup_pvc_namespace }}'
|
||||
name: "{{ deployment_name }}-backup-claim"
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
ownerReferences: null
|
||||
when:
|
||||
- backup_pvc == '' or backup_pvc is not defined
|
||||
|
||||
@@ -1,47 +1,8 @@
|
||||
---
|
||||
- name: Patching labels to {{ kind }} kind
|
||||
k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: '{{ api_version }}'
|
||||
kind: '{{ kind }}'
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
- name: Run creation tasks
|
||||
include_tasks: creation.yml
|
||||
when: not finalizer_run
|
||||
|
||||
- name: Look up details for this backup object
|
||||
k8s_info:
|
||||
api_version: "{{ api_version }}"
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: this_backup
|
||||
|
||||
- block:
|
||||
- include_tasks: init.yml
|
||||
|
||||
- include_tasks: postgres.yml
|
||||
|
||||
- include_tasks: awx-cro.yml
|
||||
|
||||
- include_tasks: secrets.yml
|
||||
|
||||
- name: Set flag signifying this backup was successful
|
||||
set_fact:
|
||||
backup_complete: true
|
||||
|
||||
- include_tasks: cleanup.yml
|
||||
|
||||
when:
|
||||
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
|
||||
|
||||
- name: Update status variables
|
||||
include_tasks: update_status.yml
|
||||
- name: Run finalizer tasks
|
||||
include_tasks: finalizer.yml
|
||||
when: finalizer_run
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: "{{ this_awx['resources'][0]['status']['postgresConfigurationSecret'] }}"
|
||||
register: pg_config
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Fail if postgres configuration secret status does not exist
|
||||
fail:
|
||||
@@ -21,12 +21,12 @@
|
||||
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
|
||||
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
|
||||
awx_postgres_type: "{{ pg_config['resources'][0]['data']['type'] | default('unmanaged'|b64encode) | b64decode }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- block:
|
||||
- name: Delete pod to reload a resource configuration
|
||||
set_fact:
|
||||
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ deployment_name }}"
|
||||
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ deployment_name }}"
|
||||
when: postgres_label_selector is not defined
|
||||
|
||||
- name: Get the postgres pod information
|
||||
@@ -39,6 +39,7 @@
|
||||
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
|
||||
|
||||
@@ -79,7 +80,7 @@
|
||||
- name: Set full resolvable host name for postgres pod
|
||||
set_fact:
|
||||
resolvable_db_host: '{{ (awx_postgres_type == "managed") | ternary(awx_postgres_host + "." + ansible_operator_meta.namespace + ".svc.cluster.local", awx_postgres_host) }}' # yamllint disable-line rule:line-length
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set pg_dump command
|
||||
set_fact:
|
||||
@@ -90,7 +91,8 @@
|
||||
-d {{ awx_postgres_database }}
|
||||
-p {{ awx_postgres_port }}
|
||||
-F custom
|
||||
no_log: true
|
||||
{{ pg_dump_suffix }}
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Write pg_dump to backup on PVC
|
||||
k8s_exec:
|
||||
@@ -99,9 +101,9 @@
|
||||
command: |
|
||||
bash -c """
|
||||
set -e -o pipefail
|
||||
PGPASSWORD={{ awx_postgres_pass }} {{ pgdump }} > {{ backup_dir }}/tower.db
|
||||
PGPASSWORD='{{ awx_postgres_pass }}' {{ pgdump }} > {{ backup_dir }}/tower.db
|
||||
echo 'Successful'
|
||||
"""
|
||||
register: data_migration
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
failed_when: "'Successful' not in data_migration.stdout"
|
||||
|
||||
@@ -21,13 +21,25 @@
|
||||
- ingress_tls_secret
|
||||
- ldap_cacert_secret
|
||||
- bundle_cacert_secret
|
||||
- image_pull_secret
|
||||
- ee_pull_credentials_secret
|
||||
|
||||
# image_pull_secret is deprecated in favor of image_pull_secrets
|
||||
- name: Dump image_pull_secret into file
|
||||
include_tasks: dump_secret.yml
|
||||
with_items:
|
||||
- image_pull_secret
|
||||
when: image_pull_secret is defined
|
||||
|
||||
- name: Dump image_pull_secrets into file
|
||||
include_tasks: dump_secret.yml
|
||||
with_items:
|
||||
- image_pull_secrets
|
||||
when: image_pull_secrets | default([]) | length
|
||||
|
||||
- name: Nest secrets under a single variable
|
||||
set_fact:
|
||||
secrets: {"secrets": '{{ secret_dict }}'}
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Write postgres configuration to pvc
|
||||
k8s_exec:
|
||||
@@ -35,4 +47,4 @@
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
bash -c "echo '{{ secrets | to_yaml }}' > {{ backup_dir }}/secrets.yml"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
deployment_type: "awx"
|
||||
_postgres_image: postgres
|
||||
_postgres_image_version: 12
|
||||
_postgres_image_version: 13
|
||||
backup_complete: false
|
||||
database_type: "unmanaged"
|
||||
supported_pg_version: 13
|
||||
|
||||
@@ -36,7 +36,7 @@ ingress_tls_secret: ''
|
||||
|
||||
loadbalancer_protocol: 'http'
|
||||
loadbalancer_port: '80'
|
||||
loadbalancer_annotations: ''
|
||||
service_annotations: ''
|
||||
|
||||
nodeport_port: '30080'
|
||||
# The TLS termination mechanism to use to access
|
||||
@@ -64,6 +64,17 @@ hostname: ''
|
||||
# kubernetes.io/os: linux
|
||||
node_selector: ''
|
||||
|
||||
# Add a topologySpreadConstraints for the AWX pods.
|
||||
# Specify as literal block. E.g.:
|
||||
# topology_spread_constraints: |
|
||||
# - maxSkew: 100
|
||||
# topologyKey: "topology.kubernetes.io/zone"
|
||||
# whenUnsatisfiable: "ScheduleAnyway"
|
||||
# labelSelector:
|
||||
# matchLabels:
|
||||
# app.kubernetes.io/name: "<resourcename>"
|
||||
topology_spread_constraints: ''
|
||||
|
||||
# Add node tolerations for the AWX pods. Specify as literal block. E.g.:
|
||||
# tolerations: |
|
||||
# - key: "dedicated"
|
||||
@@ -72,6 +83,12 @@ node_selector: ''
|
||||
# effect: "NoSchedule"
|
||||
tolerations: ''
|
||||
|
||||
# Add annotations to awx pods. Specify as literal block. E.g.:
|
||||
# annotations: |
|
||||
# my.annotation/1: value
|
||||
# my.annotation/2: value2
|
||||
annotations: ''
|
||||
|
||||
admin_user: admin
|
||||
admin_email: test@example.com
|
||||
|
||||
@@ -110,13 +127,13 @@ extra_volumes: ''
|
||||
_image: quay.io/ansible/awx
|
||||
_image_version: "{{ lookup('env', 'DEFAULT_AWX_VERSION') or 'latest' }}"
|
||||
_redis_image: docker.io/redis
|
||||
_redis_image_version: latest
|
||||
_redis_image_version: 7
|
||||
_postgres_image: postgres
|
||||
_postgres_image_version: 12
|
||||
_postgres_image_version: 13
|
||||
_init_container_image: quay.io/centos/centos
|
||||
_init_container_image_version: 8
|
||||
_init_container_image_version: stream8
|
||||
image_pull_policy: IfNotPresent
|
||||
image_pull_secret: ''
|
||||
image_pull_secrets: []
|
||||
|
||||
# Extra commands which will be appended to the initContainer
|
||||
# Make sure that each command entered return an exit code 0
|
||||
@@ -147,24 +164,36 @@ replicas: "1"
|
||||
task_args:
|
||||
- /usr/bin/launch_awx_task.sh
|
||||
task_command: []
|
||||
web_args: []
|
||||
web_args:
|
||||
- /usr/bin/launch_awx.sh
|
||||
web_command: []
|
||||
|
||||
task_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
web_resource_requirements:
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
ee_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
|
||||
# Customize CSRF options
|
||||
csrf_cookie_secure: False
|
||||
session_cookie_secure: False
|
||||
|
||||
# Assign a preexisting priority class to the control plane pods
|
||||
control_plane_priority_class: ''
|
||||
|
||||
redis_resource_requirements:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
# Add extra environment variables to the AWX task/web containers. Specify as
|
||||
# literal block. E.g.:
|
||||
# task_extra_env: |
|
||||
@@ -194,6 +223,9 @@ ee_extra_volume_mounts: ''
|
||||
# kubernetes.io/os: linux
|
||||
postgres_selector: ''
|
||||
|
||||
# Specify whether or not to keep the old PVC after PostgreSQL upgrades
|
||||
postgres_keep_pvc_after_upgrade: True
|
||||
|
||||
# Add node tolerations for the Postgres pods.
|
||||
# Specify as literal block. E.g.:
|
||||
# postgres_tolerations: |
|
||||
@@ -205,7 +237,16 @@ postgres_tolerations: ''
|
||||
postgres_storage_requirements:
|
||||
requests:
|
||||
storage: 8Gi
|
||||
postgres_resource_requirements: {}
|
||||
postgres_resource_requirements:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 64Mi
|
||||
postgres_init_container_resource_requirements:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 64Mi
|
||||
# Assign a preexisting priority class to the postgres pod
|
||||
postgres_priority_class: ''
|
||||
postgres_data_path: '/var/lib/postgresql/data/pgdata'
|
||||
|
||||
# Persistence to the AWX project data folder
|
||||
@@ -215,6 +256,9 @@ projects_persistence: false
|
||||
# Define an existing PersistentVolumeClaim to use
|
||||
projects_existing_claim: ''
|
||||
#
|
||||
# Define postgres configuration arguments to use
|
||||
postgres_extra_args: ''
|
||||
|
||||
# Define the storage_class, size and access_mode
|
||||
# when not using an existing claim
|
||||
projects_storage_size: 8Gi
|
||||
@@ -226,6 +270,9 @@ ca_trust_bundle: "/etc/pki/tls/certs/ca-bundle.crt"
|
||||
#
|
||||
ldap_cacert_secret: ''
|
||||
|
||||
# Secret to lookup that provides the LDAP bind password
|
||||
ldap_password_secret: ''
|
||||
|
||||
# Secret to lookup that provides the custom CA trusted bundle
|
||||
bundle_cacert_secret: ''
|
||||
|
||||
@@ -237,3 +284,13 @@ garbage_collect_secrets: false
|
||||
development_mode: false
|
||||
|
||||
security_context_settings: {}
|
||||
|
||||
# Set no_log settings on certain tasks
|
||||
no_log: 'true'
|
||||
|
||||
# Should AWX instances be automatically upgraded when operator gets upgraded
|
||||
#
|
||||
auto_upgrade: true
|
||||
|
||||
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
set_self_labels: true
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ admin_password_secret }}'
|
||||
register: _custom_admin_password
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: admin_password_secret | length
|
||||
|
||||
- name: Check for default admin password configuration
|
||||
@@ -14,19 +14,19 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-admin-password'
|
||||
register: _default_admin_password
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set admin password secret
|
||||
set_fact:
|
||||
_admin_password_secret: '{{ _custom_admin_password["resources"] | default([]) | length | ternary(_custom_admin_password, _default_admin_password) }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- block:
|
||||
- name: Create admin password secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'admin_password_secret.yaml.j2') }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Read admin password secret
|
||||
k8s_info:
|
||||
@@ -34,16 +34,16 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-admin-password'
|
||||
register: _generated_admin_password
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
when: not _admin_password_secret['resources'] | default([]) | length
|
||||
|
||||
- name: Set admin password secret
|
||||
set_fact:
|
||||
__admin_password_secret: '{{ _generated_admin_password["resources"] | default([]) | length | ternary(_generated_admin_password, _admin_password_secret) }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Store admin password
|
||||
set_fact:
|
||||
admin_password: "{{ __admin_password_secret['resources'][0]['data']['password'] | b64decode }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ broadcast_websocket_secret }}'
|
||||
register: _custom_broadcast_websocket
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: broadcast_websocket_secret | length
|
||||
|
||||
- name: Check for default broadcast websocket secret configuration
|
||||
@@ -14,20 +14,20 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-broadcast-websocket'
|
||||
register: _default_broadcast_websocket
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set broadcast websocket secret
|
||||
set_fact:
|
||||
# yamllint disable-line rule:line-length
|
||||
_broadcast_websocket_secret: '{{ _custom_broadcast_websocket["resources"] | default([]) | length | ternary(_custom_broadcast_websocket, _default_broadcast_websocket) }}' # noqa 204
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- block:
|
||||
- name: Create broadcast websocket secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'broadcast_websocket_secret.yaml.j2') }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Read broadcast websocket secret
|
||||
k8s_info:
|
||||
@@ -35,7 +35,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-broadcast-websocket'
|
||||
register: _generated_broadcast_websocket
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
when: not _broadcast_websocket_secret['resources'] | default([]) | length
|
||||
|
||||
@@ -43,9 +43,9 @@
|
||||
set_fact:
|
||||
# yamllint disable-line rule:line-length
|
||||
__broadcast_websocket_secret: '{{ _generated_broadcast_websocket["resources"] | default([]) | length | ternary(_generated_broadcast_websocket, _broadcast_websocket_secret) }}' # noqa 204
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Store broadcast websocket secret name
|
||||
set_fact:
|
||||
broadcast_websocket_secret_value: "{{ __broadcast_websocket_secret['resources'][0]['data']['secret'] | b64decode }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -23,6 +23,6 @@
|
||||
- '{{ _secret_key }}'
|
||||
- '{{ _postgres_configuration }}'
|
||||
- '{{ _broadcast_websocket_secret }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
when: not garbage_collect_secrets | bool
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
name: '{{ postgres_configuration_secret }}'
|
||||
register: _custom_pg_config_resources
|
||||
when: postgres_configuration_secret | length
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Check for default PostgreSQL configuration
|
||||
k8s_info:
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-configuration'
|
||||
register: _default_pg_config_resources
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Check for specified old PostgreSQL configuration secret
|
||||
k8s_info:
|
||||
@@ -23,7 +23,7 @@
|
||||
name: '{{ old_postgres_configuration_secret }}'
|
||||
register: _custom_old_pg_config_resources
|
||||
when: old_postgres_configuration_secret | length
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Check for default old PostgreSQL configuration
|
||||
k8s_info:
|
||||
@@ -31,7 +31,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-old-postgres-configuration'
|
||||
register: _default_old_pg_config_resources
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set old PostgreSQL configuration
|
||||
set_fact:
|
||||
@@ -45,7 +45,7 @@
|
||||
when:
|
||||
- old_pg_config['resources'] is defined
|
||||
- old_pg_config['resources'] | length
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set default postgres image
|
||||
set_fact:
|
||||
@@ -54,7 +54,7 @@
|
||||
- name: Set PostgreSQL configuration
|
||||
set_fact:
|
||||
_pg_config: '{{ _custom_pg_config_resources["resources"] | default([]) | length | ternary(_custom_pg_config_resources, _default_pg_config_resources) }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set user provided postgres image
|
||||
set_fact:
|
||||
@@ -72,7 +72,7 @@
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'postgres_secret.yaml.j2') }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Read Database Configuration
|
||||
k8s_info:
|
||||
@@ -80,54 +80,18 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-configuration'
|
||||
register: _generated_pg_config_resources
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: not _pg_config['resources'] | default([]) | length
|
||||
|
||||
- name: Set PostgreSQL Configuration
|
||||
set_fact:
|
||||
pg_config: '{{ _generated_pg_config_resources["resources"] | default([]) | length | ternary(_generated_pg_config_resources, _pg_config) }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set actual postgres configuration secret used
|
||||
set_fact:
|
||||
__postgres_configuration_secret: "{{ pg_config['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- block:
|
||||
- name: Create Database if no database is specified
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'postgres.yaml.j2') }}"
|
||||
register: create_statefulset_result
|
||||
|
||||
rescue:
|
||||
- name: Scale down Deployment for migration
|
||||
include_tasks: scale_down_deployment.yml
|
||||
|
||||
- name: Scale down PostgreSQL statefulset for migration
|
||||
kubernetes.core.k8s_scale:
|
||||
api_version: apps/v1
|
||||
kind: StatefulSet
|
||||
name: "{{ ansible_operator_meta.name }}-postgres"
|
||||
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"
|
||||
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', 'postgres.yaml.j2') }}"
|
||||
when: pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed'
|
||||
|
||||
- name: Store Database Configuration
|
||||
set_fact:
|
||||
awx_postgres_user: "{{ pg_config['resources'][0]['data']['username'] | b64decode }}"
|
||||
@@ -136,7 +100,125 @@
|
||||
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
|
||||
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
|
||||
awx_postgres_sslmode: "{{ pg_config['resources'][0]['data']['sslmode'] | default('prefer'|b64encode) | b64decode }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set database as managed
|
||||
set_fact:
|
||||
managed_database: "{{ pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed' }}"
|
||||
|
||||
- name: Get the old postgres pod information
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
name: "{{ ansible_operator_meta.name }}-postgres-0"
|
||||
field_selectors:
|
||||
- status.phase=Running
|
||||
register: old_postgres_pod
|
||||
|
||||
- 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: Check if postgres pod is running and version 12
|
||||
block:
|
||||
- name: Set path to PG_VERSION file for given container image
|
||||
set_fact:
|
||||
path_to_pg_version: '{{ postgres_data_path }}/PG_VERSION'
|
||||
|
||||
- name: Get old PostgreSQL version
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-postgres-0"
|
||||
command: |
|
||||
bash -c """
|
||||
cat {{ path_to_pg_version }}
|
||||
"""
|
||||
register: _old_pg_version
|
||||
|
||||
- name: Upgrade data dir from Postgres 12 to 13 if applicable
|
||||
include_tasks: upgrade_postgres.yml
|
||||
when:
|
||||
- _old_pg_version.stdout | default('0') | trim == '12'
|
||||
when:
|
||||
- managed_database
|
||||
- this_awx['resources'][0]['status']['upgradedPostgresVersion'] | default('none') != '12'
|
||||
- old_postgres_pod['resources'] | length # upgrade is complete and old pg pod has been removed
|
||||
|
||||
- block:
|
||||
- name: Create Database if no database is specified
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', '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-13"
|
||||
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-13"
|
||||
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', '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:
|
||||
|
||||
@@ -13,18 +13,6 @@
|
||||
register: users_result
|
||||
changed_when: users_result.return_code > 0
|
||||
|
||||
- name: Update super user password via Django if it does exist (same password is a noop)
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage update_password --username '{{ admin_user }}' --password '{{ admin_password }}'"
|
||||
register: update_pw_result
|
||||
changed_when: users_result.stdout == 'Password not updated'
|
||||
no_log: true
|
||||
when: users_result.return_code == 0
|
||||
|
||||
- name: Create super user via Django if it doesn't exist.
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
@@ -34,20 +22,9 @@
|
||||
bash -c "echo \"from django.contrib.auth.models import User;
|
||||
User.objects.create_superuser('{{ admin_user }}', '{{ admin_email }}', '{{ admin_password }}')\"
|
||||
| awx-manage shell"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: users_result.return_code > 0
|
||||
|
||||
- name: Create preload data if necessary. # noqa 305
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage create_preload_data"
|
||||
register: cdo
|
||||
changed_when: "'added' in cdo.stdout"
|
||||
when: create_preload_data | bool
|
||||
|
||||
- name: Check if legacy queue is present
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
@@ -80,7 +57,7 @@
|
||||
_execution_environments_pull_credentials: >-
|
||||
{{ _custom_execution_environments_pull_credentials["resources"] | default([]) | length
|
||||
| ternary(_custom_execution_environments_pull_credentials, []) }}
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Register default execution environments (without authentication)
|
||||
k8s_exec:
|
||||
@@ -101,7 +78,7 @@
|
||||
default_execution_environment_pull_credentials_url: "{{ _execution_environments_pull_credentials['resources'][0]['data']['url'] | b64decode }}"
|
||||
default_execution_environment_pull_credentials_url_verify: >-
|
||||
{{ _execution_environments_pull_credentials['resources'][0]['data']['ssl_verify'] | default("True"|b64encode) | b64decode }}
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Register default execution environments (with authentication)
|
||||
k8s_exec:
|
||||
@@ -116,5 +93,16 @@
|
||||
--verify-ssl='{{ default_execution_environment_pull_credentials_url_verify }}'"
|
||||
register: ree
|
||||
changed_when: "'changed: True' in ree.stdout"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: _execution_environments_pull_credentials['resources'] | default([]) | length
|
||||
|
||||
- name: Create preload data if necessary. # noqa 305
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage create_preload_data"
|
||||
register: cdo
|
||||
changed_when: "'added' in cdo.stdout"
|
||||
when: create_preload_data | bool
|
||||
|
||||
89
roles/installer/tasks/install.yml
Normal file
89
roles/installer/tasks/install.yml
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
- name: Patching labels to AWX kind
|
||||
k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: '{{ api_version }}'
|
||||
kind: '{{ kind }}'
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
when: set_self_labels | bool
|
||||
|
||||
- name: Include secret key configuration tasks
|
||||
include_tasks: secret_key_configuration.yml
|
||||
|
||||
- name: Load LDAP CAcert certificate
|
||||
include_tasks: load_ldap_cacert_secret.yml
|
||||
when:
|
||||
- ldap_cacert_secret != ''
|
||||
|
||||
- name: Load ldap bind password
|
||||
include_tasks: load_ldap_password_secret.yml
|
||||
when:
|
||||
- ldap_password_secret != ''
|
||||
|
||||
- name: Load bundle certificate authority certificate
|
||||
include_tasks: load_bundle_cacert_secret.yml
|
||||
when:
|
||||
- bundle_cacert_secret != ''
|
||||
|
||||
- name: Include admin password configuration tasks
|
||||
include_tasks: admin_password_configuration.yml
|
||||
|
||||
- name: Include broadcast websocket configuration tasks
|
||||
include_tasks: broadcast_websocket_configuration.yml
|
||||
|
||||
- name: Include set_images tasks
|
||||
include_tasks: set_images.yml
|
||||
|
||||
- name: Include database configuration tasks
|
||||
include_tasks: database_configuration.yml
|
||||
|
||||
- name: Load Route TLS certificate
|
||||
include_tasks: load_route_tls_secret.yml
|
||||
when:
|
||||
- ingress_type | lower == 'route'
|
||||
- route_tls_secret != ''
|
||||
|
||||
- name: Include resources configuration tasks
|
||||
include_tasks: resources_configuration.yml
|
||||
|
||||
- name: Check for pending migrations
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l"
|
||||
changed_when: false
|
||||
register: database_check
|
||||
|
||||
- name: Migrate the database if the K8s resources were updated. # noqa 305
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage migrate --noinput"
|
||||
register: migrate_result
|
||||
when:
|
||||
- database_check is defined
|
||||
- (database_check.stdout|trim) != '0'
|
||||
|
||||
- name: Initialize Django
|
||||
include_tasks: initialize_django.yml
|
||||
|
||||
- name: Update status variables
|
||||
include_tasks: update_status.yml
|
||||
|
||||
- name: Cleanup & Set garbage collection refs
|
||||
include_tasks: cleanup.yml
|
||||
@@ -5,10 +5,10 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ bundle_cacert_secret }}'
|
||||
register: bundle_cacert
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Load bundle Certificate Authority Secret content
|
||||
set_fact:
|
||||
bundle_ca_crt: '{{ bundle_cacert["resources"][0]["data"]["bundle-ca.crt"] | b64decode }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: '"bundle-ca.crt" in bundle_cacert["resources"][0]["data"]'
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ldap_cacert_secret }}'
|
||||
register: ldap_cacert
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Load LDAP CA Certificate Secret content
|
||||
set_fact:
|
||||
ldap_cacert_ca_crt: '{{ ldap_cacert["resources"][0]["data"]["ldap-ca.crt"] | b64decode }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: '"ldap-ca.crt" in ldap_cacert["resources"][0]["data"]'
|
||||
|
||||
14
roles/installer/tasks/load_ldap_password_secret.yml
Normal file
14
roles/installer/tasks/load_ldap_password_secret.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Retrieve LDAP bind password Secret
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ldap_password_secret }}'
|
||||
register: ldap_password
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Load LDAP bind password Secret content
|
||||
set_fact:
|
||||
ldap_bind_password: '{{ ldap_password["resources"][0]["data"]["ldap-password"] | b64decode }}'
|
||||
no_log: "{{ no_log }}"
|
||||
when: '"ldap-password" in ldap_password["resources"][0]["data"]'
|
||||
@@ -5,16 +5,16 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ route_tls_secret }}'
|
||||
register: route_tls
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Load Route TLS Secret content
|
||||
set_fact:
|
||||
route_tls_key: '{{ route_tls["resources"][0]["data"]["tls.key"] | b64decode }}'
|
||||
route_tls_crt: '{{ route_tls["resources"][0]["data"]["tls.crt"] | b64decode }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Load Route TLS Secret content
|
||||
set_fact:
|
||||
route_ca_crt: '{{ route_tls["resources"][0]["data"]["ca.crt"] | b64decode }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: '"ca.crt" in route_tls["resources"][0]["data"]'
|
||||
|
||||
@@ -1,80 +1,13 @@
|
||||
---
|
||||
- name: Patching labels to AWX kind
|
||||
k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: '{{ api_version }}'
|
||||
kind: '{{ kind }}'
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
|
||||
- name: Include secret key configuration tasks
|
||||
include_tasks: secret_key_configuration.yml
|
||||
|
||||
- name: Load LDAP CAcert certificate
|
||||
include_tasks: load_ldap_cacert_secret.yml
|
||||
when:
|
||||
- ldap_cacert_secret != ''
|
||||
|
||||
- name: Load bundle certificate authority certificate
|
||||
include_tasks: load_bundle_cacert_secret.yml
|
||||
when:
|
||||
- bundle_cacert_secret != ''
|
||||
|
||||
- name: Include admin password configuration tasks
|
||||
include_tasks: admin_password_configuration.yml
|
||||
|
||||
- name: Include broadcast websocket configuration tasks
|
||||
include_tasks: broadcast_websocket_configuration.yml
|
||||
|
||||
- name: Include database configuration tasks
|
||||
include_tasks: database_configuration.yml
|
||||
|
||||
- name: Load Route TLS certificate
|
||||
include_tasks: load_route_tls_secret.yml
|
||||
when:
|
||||
- ingress_type | lower == 'route'
|
||||
- route_tls_secret != ''
|
||||
|
||||
- name: Include resources configuration tasks
|
||||
include_tasks: resources_configuration.yml
|
||||
|
||||
- name: Check for pending migrations
|
||||
k8s_exec:
|
||||
- name: Check for presence of Deployment
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
kind: Deployment
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l"
|
||||
changed_when: false
|
||||
register: database_check
|
||||
register: tower_deployment
|
||||
|
||||
- name: Migrate the database if the K8s resources were updated. # noqa 305
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage migrate --noinput"
|
||||
register: migrate_result
|
||||
when:
|
||||
- database_check is defined
|
||||
- (database_check.stdout|trim) != '0'
|
||||
|
||||
- name: Initialize Django
|
||||
include_tasks: initialize_django.yml
|
||||
|
||||
- name: Update status variables
|
||||
include_tasks: update_status.yml
|
||||
|
||||
- name: Cleanup & Set garbage collection refs
|
||||
include_tasks: cleanup.yml
|
||||
# Just execute deployment steps when auto_upgrade is true or when no deployment exists
|
||||
- name: Start installation
|
||||
include_tasks: install.yml
|
||||
when: (tower_deployment['resources'] | length > 0 and auto_upgrade | bool ) or (tower_deployment['resources'] | length == 0)
|
||||
|
||||
@@ -11,26 +11,22 @@
|
||||
awx_old_postgres_database: "{{ old_pg_config['resources'][0]['data']['database'] | b64decode }}"
|
||||
awx_old_postgres_port: "{{ old_pg_config['resources'][0]['data']['port'] | b64decode }}"
|
||||
awx_old_postgres_host: "{{ old_pg_config['resources'][0]['data']['host'] | b64decode }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Default label selector to custom resource generated postgres
|
||||
- name: Set Default label selector for custom resource generated postgres
|
||||
set_fact:
|
||||
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ ansible_operator_meta.name }}"
|
||||
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 }}'
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-0' # using name to keep compatibility
|
||||
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'"
|
||||
delay: 5
|
||||
retries: 60
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
@@ -48,7 +44,7 @@
|
||||
-d {{ awx_old_postgres_database }}
|
||||
-p {{ awx_old_postgres_port }}
|
||||
-F custom
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set pg_restore command
|
||||
set_fact:
|
||||
@@ -56,7 +52,7 @@
|
||||
pg_restore --clean --if-exists
|
||||
-U {{ database_username }}
|
||||
-d {{ database_name }}
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Stream backup from pg_dump to the new postgresql container
|
||||
k8s_exec:
|
||||
@@ -65,10 +61,10 @@
|
||||
command: |
|
||||
bash -c """
|
||||
set -e -o pipefail
|
||||
PGPASSWORD={{ awx_old_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ pg_restore }}
|
||||
PGPASSWORD='{{ awx_old_postgres_pass }}' {{ pgdump }} | PGPASSWORD='{{ awx_postgres_pass }}' {{ pg_restore }}
|
||||
echo 'Successful'
|
||||
"""
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
register: data_migration
|
||||
failed_when: "'Successful' not in data_migration.stdout"
|
||||
|
||||
|
||||
@@ -11,11 +11,21 @@
|
||||
- "app.kubernetes.io/component={{ deployment_type }}"
|
||||
field_selectors:
|
||||
- status.phase=Running
|
||||
register: tower_pods
|
||||
register: tower_pod
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] | default('') }}"
|
||||
tower_pod_name: "{{ tower_pod['resources'][0]['metadata']['name'] | default('') }}"
|
||||
|
||||
- name: Set user provided control plane ee image
|
||||
set_fact:
|
||||
_custom_control_plane_ee_image: "{{ control_plane_ee_image }}"
|
||||
when:
|
||||
- control_plane_ee_image | default([]) | length
|
||||
|
||||
- name: Set Control Plane EE image URL
|
||||
set_fact:
|
||||
_control_plane_ee_image: "{{ _custom_control_plane_ee_image | default(lookup('env', 'RELATED_IMAGE_CONTROL_PLANE_EE')) | default(_control_plane_ee_image, true) }}"
|
||||
|
||||
- name: Apply Resources
|
||||
k8s:
|
||||
@@ -30,7 +40,7 @@
|
||||
- 'persistent'
|
||||
- 'service'
|
||||
- 'ingress'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set default awx app image
|
||||
set_fact:
|
||||
@@ -47,21 +57,6 @@
|
||||
set_fact:
|
||||
_image: "{{ _custom_image | default(lookup('env', 'RELATED_IMAGE_AWX')) | default(_default_image, true) }}"
|
||||
|
||||
- name: Set default awx init container image
|
||||
set_fact:
|
||||
_default_init_container_image: "{{ _init_container_image }}:{{ _init_container_image_version }}"
|
||||
|
||||
- name: Set user provided awx init image
|
||||
set_fact:
|
||||
_custom_init_container_image: "{{ init_container_image }}:{{ init_container_image_version }}"
|
||||
when:
|
||||
- init_container_image | default([]) | length
|
||||
- init_container_image_version is defined or init_container_image_version != ''
|
||||
|
||||
- name: Set Init image URL
|
||||
set_fact:
|
||||
_init_container_image: "{{ _custom_init_container_image | default(lookup('env', 'RELATED_IMAGE_AWX_INIT_CONTAINER')) | default(_default_init_container_image, true) }}"
|
||||
|
||||
- name: Set default redis image
|
||||
set_fact:
|
||||
_default_redis_image: "{{ _redis_image }}:{{ _redis_image_version }}"
|
||||
@@ -77,22 +72,12 @@
|
||||
set_fact:
|
||||
_redis_image: "{{ _custom_redis_image | default(lookup('env', 'RELATED_IMAGE_AWX_REDIS')) | default(_default_redis_image, true) }}"
|
||||
|
||||
- name: Set user provided control plane ee image
|
||||
set_fact:
|
||||
_custom_control_plane_ee_image: "{{ control_plane_ee_image }}"
|
||||
when:
|
||||
- control_plane_ee_image | default([]) | length
|
||||
|
||||
- name: Set Control Plane EE image URL
|
||||
set_fact:
|
||||
_control_plane_ee_image: "{{ _custom_control_plane_ee_image | default(lookup('env', 'RELATED_IMAGE_CONTROL_PLANE_EE')) | default(_control_plane_ee_image, true) }}"
|
||||
|
||||
- name: Apply deployment resources
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'deployment.yaml.j2') }}"
|
||||
wait: yes
|
||||
register: tower_deployment_result
|
||||
register: this_deployment_result
|
||||
|
||||
- block:
|
||||
- name: Delete pod to reload a resource configuration
|
||||
@@ -128,7 +113,7 @@
|
||||
set_fact:
|
||||
tower_pod_name: '{{ _new_pod["resources"][0]["metadata"]["name"] }}'
|
||||
when:
|
||||
- tower_resources_result.changed or tower_deployment_result.changed
|
||||
- tower_resources_result.changed or this_deployment_result.changed
|
||||
|
||||
- name: Verify the resource pod name is populated.
|
||||
assert:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
kind: Deployment
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: tower_deployment
|
||||
register: this_deployment
|
||||
|
||||
- name: Scale down Deployment for migration
|
||||
kubernetes.core.k8s_scale:
|
||||
@@ -16,4 +16,4 @@
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
replicas: 0
|
||||
wait: yes
|
||||
when: tower_deployment['resources'] | length
|
||||
when: this_deployment['resources'] | length
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ secret_key_secret }}'
|
||||
register: _custom_secret_key
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: secret_key_secret | length
|
||||
|
||||
- name: Check for default secret key configuration
|
||||
@@ -14,19 +14,19 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-secret-key'
|
||||
register: _default_secret_key
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set secret key secret
|
||||
set_fact:
|
||||
_secret_key_secret: '{{ _custom_secret_key["resources"] | default([]) | length | ternary(_custom_secret_key, _default_secret_key) }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- block:
|
||||
- name: Create secret key secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'secret_key.yaml.j2') }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Read secret key secret
|
||||
k8s_info:
|
||||
@@ -34,16 +34,16 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-secret-key'
|
||||
register: _generated_secret_key
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
when: not _secret_key_secret['resources'] | default([]) | length
|
||||
|
||||
- name: Set secret key secret
|
||||
set_fact:
|
||||
__secret_key_secret: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Store secret key secret name
|
||||
set_fact:
|
||||
secret_key_secret_name: "{{ __secret_key_secret['resources'][0]['metadata']['name'] }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
19
roles/installer/tasks/set_images.yml
Normal file
19
roles/installer/tasks/set_images.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
# For disconnected environments, images must be set based on the values of `RELATED_IMAGE_` variables
|
||||
---
|
||||
- name: Set default awx init container image
|
||||
set_fact:
|
||||
_default_init_container_image: "{{ _init_container_image }}:{{ _init_container_image_version }}"
|
||||
|
||||
- name: Set user provided awx init image
|
||||
set_fact:
|
||||
_custom_init_container_image: "{{ init_container_image }}:{{ init_container_image_version }}"
|
||||
when:
|
||||
- init_container_image | default([]) | length
|
||||
- init_container_image_version is defined or init_container_image_version != ''
|
||||
|
||||
- name: Set Init image URL
|
||||
set_fact:
|
||||
_init_container_image: >-
|
||||
{{ _custom_init_container_image |
|
||||
default(lookup('env', 'RELATED_IMAGE_AWX_INIT_CONTAINER')) |
|
||||
default(_default_init_container_image, true) }}
|
||||
@@ -101,3 +101,13 @@
|
||||
status:
|
||||
migratedFromSecret: "{{ tower_migrated_from_secret }}"
|
||||
when: tower_migrated_from_secret is defined
|
||||
|
||||
- name: Update upgradedPostgresVersion status
|
||||
operator_sdk.util.k8s_status:
|
||||
api_version: '{{ api_version }}'
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
status:
|
||||
upgradedPostgresVersion: "{{ upgraded_postgres_version }}"
|
||||
when: upgraded_postgres_version is defined
|
||||
|
||||
132
roles/installer/tasks/upgrade_postgres.yml
Normal file
132
roles/installer/tasks/upgrade_postgres.yml
Normal file
@@ -0,0 +1,132 @@
|
||||
---
|
||||
|
||||
# Upgrade Posgres (Managed Databases only)
|
||||
# * If postgres version is not 12, and not an external postgres instance (when managed_database is yes),
|
||||
# then run this playbook with include_tasks from database_configuration.yml
|
||||
# * Data will be streamed via a pg_dump from the postgres 12 pod to the postgres 13
|
||||
# pod via a pg_restore.
|
||||
|
||||
|
||||
- name: Scale down Deployment for migration
|
||||
include_tasks: scale_down_deployment.yml
|
||||
|
||||
- name: Delete existing postgres configuration secret
|
||||
k8s:
|
||||
api_version: v1
|
||||
kind: Secret
|
||||
name: "{{ ansible_operator_meta.name }}-postgres-configuration"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
state: absent
|
||||
wait: yes
|
||||
|
||||
- name: Create Database configuration with new -postgres-{{ supported_pg_version }} hostname
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'postgres_upgrade_secret.yaml.j2') }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set new database var to be used when configuring app credentials (resources_configuration.yml)
|
||||
set_fact:
|
||||
awx_postgres_host: "{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create Database if no database is specified
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'postgres.yaml.j2') }}"
|
||||
wait: true
|
||||
register: create_statefulset_result
|
||||
|
||||
- name: Set postgres label if not defined by user
|
||||
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 new 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
|
||||
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
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Set full resolvable host name for postgres pod
|
||||
set_fact:
|
||||
resolvable_db_host: "{{ ansible_operator_meta.name }}-postgres.{{ ansible_operator_meta.namespace }}.svc.cluster.local" # yamllint disable-line rule:line-length
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set pg_dump command
|
||||
set_fact:
|
||||
pgdump: >-
|
||||
pg_dump
|
||||
-h {{ resolvable_db_host }}
|
||||
-U {{ awx_postgres_user }}
|
||||
-d {{ awx_postgres_database }}
|
||||
-p {{ awx_postgres_port }}
|
||||
-F custom
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set pg_restore command
|
||||
set_fact:
|
||||
pg_restore: >-
|
||||
pg_restore
|
||||
-U {{ awx_postgres_user }}
|
||||
-d {{ awx_postgres_database }}
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Stream backup from pg_dump to the new postgresql container
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ postgres_pod_name }}"
|
||||
command: |
|
||||
bash -c """
|
||||
set -e -o pipefail
|
||||
PGPASSWORD={{ awx_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ pg_restore }}
|
||||
echo 'Successful'
|
||||
"""
|
||||
no_log: "{{ no_log }}"
|
||||
register: data_migration
|
||||
failed_when: "'Successful' not in data_migration.stdout"
|
||||
|
||||
- name: Set flag signifying that this instance has been migrated
|
||||
set_fact:
|
||||
upgraded_postgres_version: '13'
|
||||
|
||||
# Cleanup old Postgres resources
|
||||
- name: Remove old Postgres StatefulSet
|
||||
k8s:
|
||||
kind: StatefulSet
|
||||
api_version: v1
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
name: "{{ ansible_operator_meta.name }}-postgres"
|
||||
state: absent
|
||||
wait: true
|
||||
|
||||
- name: Remove old Postgres Service
|
||||
k8s:
|
||||
kind: Service
|
||||
api_version: v1
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
name: "{{ ansible_operator_meta.name }}-postgres"
|
||||
state: absent
|
||||
|
||||
- name: Remove old persistent volume claim
|
||||
k8s:
|
||||
kind: PersistentVolumeClaim
|
||||
api_version: v1
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
name: "postgres-{{ ansible_operator_meta.name }}-postgres-0"
|
||||
state: absent
|
||||
when: postgres_keep_pvc_after_upgrade
|
||||
@@ -18,6 +18,7 @@ data:
|
||||
settings: |
|
||||
import os
|
||||
import socket
|
||||
from django_auth_ldap.config import LDAPSearch
|
||||
|
||||
def get_secret():
|
||||
if os.path.exists("/etc/tower/SECRET_KEY"):
|
||||
@@ -25,11 +26,22 @@ data:
|
||||
|
||||
ADMINS = ()
|
||||
STATIC_ROOT = '/var/lib/awx/public/static'
|
||||
STATIC_URL = '{{ (ingress_path + '/static/').replace('//', '/') }}'
|
||||
PROJECTS_ROOT = '/var/lib/awx/projects'
|
||||
JOBOUTPUT_ROOT = '/var/lib/awx/job_status'
|
||||
|
||||
IS_K8S = True
|
||||
|
||||
# Set memory available based off of resource request/limit for the task pod
|
||||
memory_limit = '{{ task_resource_requirements["limits"]["memory"] if "limits" in task_resource_requirements and "memory" in task_resource_requirements["limits"] }}'
|
||||
if memory_limit:
|
||||
SYSTEM_TASK_ABS_MEM = memory_limit
|
||||
|
||||
# Set cpu available based off of resource request/limit for the task pod
|
||||
cpu_limit = '{{ task_resource_requirements["limits"]["cpu"] if "limits" in task_resource_requirements and "cpu" in task_resource_requirements["limits"] }}'
|
||||
if cpu_limit:
|
||||
SYSTEM_TASK_ABS_CPU = cpu_limit
|
||||
|
||||
SECRET_KEY = get_secret()
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
@@ -48,8 +60,8 @@ data:
|
||||
CLUSTER_HOST_ID = socket.gethostname()
|
||||
SYSTEM_UUID = os.environ.get('MY_POD_UID', '00000000-0000-0000-0000-000000000000')
|
||||
|
||||
CSRF_COOKIE_SECURE = False
|
||||
SESSION_COOKIE_SECURE = False
|
||||
CSRF_COOKIE_SECURE = {{ csrf_cookie_secure | bool }}
|
||||
SESSION_COOKIE_SECURE = {{ session_cookie_secure | bool }}
|
||||
|
||||
SERVER_EMAIL = 'root@localhost'
|
||||
DEFAULT_FROM_EMAIL = 'webmaster@localhost'
|
||||
@@ -133,6 +145,7 @@ data:
|
||||
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
server {
|
||||
listen 8052 default_server;
|
||||
listen [::]:8052 default_server;
|
||||
server_name _;
|
||||
|
||||
# Redirect all HTTP links to the matching HTTPS page
|
||||
@@ -143,6 +156,7 @@ data:
|
||||
server {
|
||||
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
listen 8053 ssl;
|
||||
listen [::]:8053 ssl;
|
||||
|
||||
ssl_certificate /etc/nginx/pki/web.crt;
|
||||
ssl_certificate_key /etc/nginx/pki/web.key;
|
||||
@@ -153,6 +167,7 @@ data:
|
||||
ssl_prefer_server_ciphers on;
|
||||
{% else %}
|
||||
listen 8052 default_server;
|
||||
listen [::]:8052 default_server;
|
||||
{% endif %}
|
||||
|
||||
# If you have a domain name, this is where to add it
|
||||
@@ -164,6 +179,8 @@ data:
|
||||
|
||||
# Protect against click-jacking https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009)
|
||||
add_header X-Frame-Options "DENY";
|
||||
# Protect against MIME content sniffing https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
location /nginx_status {
|
||||
stub_status on;
|
||||
@@ -172,15 +189,15 @@ data:
|
||||
deny all;
|
||||
}
|
||||
|
||||
location /static/ {
|
||||
location {{ (ingress_path + '/static').replace('//', '/') }} {
|
||||
alias /var/lib/awx/public/static/;
|
||||
}
|
||||
|
||||
location /favicon.ico {
|
||||
location {{ (ingress_path + '/favicon.ico').replace('//', '/') }} {
|
||||
alias /var/lib/awx/public/static/media/favicon.ico;
|
||||
}
|
||||
|
||||
location /websocket {
|
||||
location {{ (ingress_path + '/websocket').replace('//', '/') }} {
|
||||
# Pass request to the upstream alias
|
||||
proxy_pass http://daphne;
|
||||
# Require http version 1.1 to allow for upgrade requests
|
||||
@@ -202,7 +219,7 @@ data:
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
}
|
||||
|
||||
location / {
|
||||
location {{ ingress_path }} {
|
||||
# Add trailing / if missing
|
||||
rewrite ^(.*)$http_host(.*[^/])$ $1$http_host$2/ permanent;
|
||||
uwsgi_read_timeout 120s;
|
||||
@@ -217,6 +234,7 @@ data:
|
||||
add_header Strict-Transport-Security max-age=15768000;
|
||||
# Protect against click-jacking https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009)
|
||||
add_header X-Frame-Options "DENY";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Expires "0";
|
||||
add_header Pragma "no-cache";
|
||||
|
||||
@@ -7,7 +7,7 @@ metadata:
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/version: '{{ _image_version }}'
|
||||
app.kubernetes.io/version: '{{ _image.split(':')[-1] | truncate(63, True, '') }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
@@ -23,18 +23,30 @@ spec:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/version: '{{ _image_version }}'
|
||||
app.kubernetes.io/version: '{{ _image.split(':')[-1] | truncate(63, True, '') }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
{% if annotations %}
|
||||
annotations:
|
||||
{{ annotations | indent(width=8) }}
|
||||
{% endif %}
|
||||
spec:
|
||||
serviceAccountName: '{{ ansible_operator_meta.name }}'
|
||||
{% if image_pull_secret %}
|
||||
{% if image_pull_secret is defined %}
|
||||
imagePullSecrets:
|
||||
- name: {{ image_pull_secret }}
|
||||
{% elif image_pull_secrets | length > 0 %}
|
||||
imagePullSecrets:
|
||||
{% for secret in image_pull_secrets %}
|
||||
- name: {{ secret }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if control_plane_priority_class is defined %}
|
||||
priorityClassName: '{{ control_plane_priority_class }}'
|
||||
{% endif %}
|
||||
{% if bundle_ca_crt or projects_persistence|bool or init_container_extra_commands %}
|
||||
initContainers:
|
||||
{% if bundle_ca_crt or projects_persistence|bool or init_container_extra_commands %}
|
||||
- name: init
|
||||
image: '{{ _init_container_image }}'
|
||||
imagePullPolicy: '{{ image_pull_policy }}'
|
||||
@@ -89,6 +101,7 @@ spec:
|
||||
mountPath: "/var/run/redis"
|
||||
- name: "{{ ansible_operator_meta.name }}-redis-data"
|
||||
mountPath: "/data"
|
||||
resources: {{ redis_resource_requirements }}
|
||||
- image: '{{ _image }}'
|
||||
name: '{{ ansible_operator_meta.name }}-web'
|
||||
{% if web_command %}
|
||||
@@ -169,6 +182,8 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: UWSGI_MOUNT_PATH
|
||||
value: "{{ ingress_path }}"
|
||||
{% if development_mode | bool %}
|
||||
- name: AWX_KUBE_DEVEL
|
||||
value: "1"
|
||||
@@ -306,6 +321,10 @@ spec:
|
||||
nodeSelector:
|
||||
{{ node_selector | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if topology_spread_constraints %}
|
||||
topologySpreadConstraints:
|
||||
{{ topology_spread_constraints | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if tolerations %}
|
||||
tolerations:
|
||||
{{ tolerations | indent(width=8) }}
|
||||
|
||||
@@ -4,3 +4,8 @@ AUTH_LDAP_GLOBAL_OPTIONS = {
|
||||
ldap.OPT_X_TLS_CACERTFILE: "/etc/openldap/certs/ldap-ca.crt"
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
# Load LDAP BIND password from Kubernetes secret if define
|
||||
{% if ldap_password_secret -%}
|
||||
AUTH_LDAP_BIND_PASSWORD = "{{ ldap_bind_password }}"
|
||||
{% endif %}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-postgres'
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: 'postgres'
|
||||
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
|
||||
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'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
@@ -16,8 +16,8 @@ metadata:
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: 'postgres'
|
||||
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
|
||||
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'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
serviceName: '{{ ansible_operator_meta.name }}'
|
||||
@@ -27,22 +27,33 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: 'postgres'
|
||||
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
|
||||
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'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
spec:
|
||||
{% if image_pull_secret %}
|
||||
{% if image_pull_secret is defined %}
|
||||
imagePullSecrets:
|
||||
- name: {{ image_pull_secret }}
|
||||
{% elif image_pull_secrets | length > 0 %}
|
||||
imagePullSecrets:
|
||||
{% for secret in image_pull_secrets %}
|
||||
- name: {{ secret }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if postgres_priority_class is defined %}
|
||||
priorityClassName: '{{ postgres_priority_class }}'
|
||||
{% endif %}
|
||||
containers:
|
||||
- image: '{{ _postgres_image }}'
|
||||
imagePullPolicy: '{{ image_pull_policy }}'
|
||||
name: postgres
|
||||
{% if postgres_extra_args %}
|
||||
args: {{ postgres_extra_args }}
|
||||
{% endif %}
|
||||
env:
|
||||
# For postgres_image based on rhel8/postgresql-12
|
||||
# For postgres_image based on rhel8/postgresql-13
|
||||
- name: POSTGRESQL_DATABASE
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
@@ -83,9 +94,9 @@ spec:
|
||||
value: '{{ postgres_host_auth_method }}'
|
||||
ports:
|
||||
- containerPort: {{ awx_postgres_port | default('5432')}}
|
||||
name: postgres
|
||||
name: postgres-{{ supported_pg_version }}
|
||||
volumeMounts:
|
||||
- name: postgres
|
||||
- name: postgres-{{ supported_pg_version }}
|
||||
mountPath: '{{ postgres_data_path | dirname }}'
|
||||
subPath: '{{ postgres_data_path | dirname | basename }}'
|
||||
resources: {{ postgres_resource_requirements }}
|
||||
@@ -99,7 +110,7 @@ spec:
|
||||
{% endif %}
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: postgres
|
||||
name: postgres-{{ supported_pg_version }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
@@ -113,11 +124,11 @@ spec:
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-postgres'
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: 'postgres'
|
||||
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
|
||||
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'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
@@ -128,8 +139,8 @@ spec:
|
||||
- port: 5432
|
||||
clusterIP: None
|
||||
selector:
|
||||
app.kubernetes.io/name: 'postgres'
|
||||
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
|
||||
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'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
|
||||
@@ -16,5 +16,5 @@ stringData:
|
||||
username: '{{ database_username }}'
|
||||
database: '{{ database_name }}'
|
||||
port: '5432'
|
||||
host: {{ ansible_operator_meta.name }}-postgres
|
||||
host: {{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}
|
||||
type: 'managed'
|
||||
|
||||
20
roles/installer/templates/postgres_upgrade_secret.yaml.j2
Normal file
20
roles/installer/templates/postgres_upgrade_secret.yaml.j2
Normal file
@@ -0,0 +1,20 @@
|
||||
# Postgres Secret.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
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") }}'
|
||||
stringData:
|
||||
password: '{{ awx_postgres_pass }}'
|
||||
username: '{{ awx_postgres_user }}'
|
||||
database: '{{ awx_postgres_database }}'
|
||||
port: '{{ awx_postgres_port }}'
|
||||
host: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
|
||||
type: 'managed'
|
||||
@@ -11,13 +11,20 @@ metadata:
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ service_labels | indent(width=4) }}
|
||||
{% if service_type | lower == 'loadbalancer' and loadbalancer_annotations %}
|
||||
{% if service_annotations %}
|
||||
annotations:
|
||||
{{ loadbalancer_annotations | indent(width=4) }}
|
||||
{{ service_annotations | indent(width=4) }}
|
||||
{% endif %}
|
||||
spec:
|
||||
ports:
|
||||
{% if service_type | lower != 'loadbalancer' and loadbalancer_protocol | lower != 'https' %}
|
||||
|
||||
{% if service_type | lower == "nodeport" %}
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8052
|
||||
name: http
|
||||
nodePort: {{ nodeport_port }}
|
||||
{% elif service_type | lower != 'loadbalancer' and loadbalancer_protocol | lower != 'https' %}
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8052
|
||||
@@ -44,10 +51,10 @@ spec:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
{% if service_type | lower == "loadbalancer" %}
|
||||
type: LoadBalancer
|
||||
{% elif service_type | lower == "nodeport" %}
|
||||
{% if service_type | lower == "nodeport" %}
|
||||
type: NodePort
|
||||
{% elif service_type | lower == "loadbalancer" %}
|
||||
type: LoadBalancer
|
||||
{% else %}
|
||||
type: ClusterIP
|
||||
{% endif %}
|
||||
|
||||
@@ -4,3 +4,4 @@ postgres_host_auth_method: 'scram-sha-256'
|
||||
ldap_cacert_ca_crt: ''
|
||||
bundle_ca_crt: ''
|
||||
projects_existing_claim: ''
|
||||
supported_pg_version: 13
|
||||
|
||||
@@ -33,7 +33,6 @@ metadata:
|
||||
spec:
|
||||
deployment_name: mytower
|
||||
backup_name: awxbackup-2021-04-22
|
||||
backup_pvc_namespace: 'old-awx-namespace'
|
||||
```
|
||||
|
||||
Note that the `deployment_name` above is the name of the AWX deployment you intend to create and restore to.
|
||||
@@ -81,11 +80,7 @@ awx-backup-volume-claim
|
||||
backup_pvc: 'awx-backup-volume-claim'
|
||||
```
|
||||
|
||||
By default, the backup pvc will be created in the same namespace the awxbackup object is created in. This namespace must be specified using the `backup_pvc_namespace` variable.
|
||||
|
||||
```
|
||||
backup_pvc_namespace: 'custom-namespace'
|
||||
```
|
||||
The backup pvc will be created in the same namespace the awxbackup object is created in.
|
||||
|
||||
If a custom postgres configuration secret was used when deploying AWX, it must be set:
|
||||
|
||||
|
||||
@@ -10,3 +10,9 @@ backup_pvc_namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
|
||||
# Required: backup name, found on the awxbackup object
|
||||
backup_dir: ''
|
||||
|
||||
# Set no_log settings on certain tasks
|
||||
no_log: 'true'
|
||||
|
||||
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
set_self_labels: true
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
- '{{ admin_password_secret }}'
|
||||
- '{{ broadcast_websocket_secret }}'
|
||||
- '{{ postgres_configuration_secret }}'
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Cleanup temp spec file
|
||||
file:
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
when: set_self_labels | bool
|
||||
|
||||
- name: Look up details for this restore object
|
||||
k8s_info:
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ postgres_configuration_secret }}'
|
||||
register: pg_config
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Store Database Configuration
|
||||
set_fact:
|
||||
@@ -20,29 +20,31 @@
|
||||
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
|
||||
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
|
||||
awx_postgres_type: "{{ pg_config['resources'][0]['data']['type'] | b64decode | default('unmanaged') }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Default label selector to custom resource generated postgres
|
||||
- name: Set Default label selector for custom resource generated postgres
|
||||
set_fact:
|
||||
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ deployment_name }}"
|
||||
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ deployment_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 }}"
|
||||
register: postgres_pod
|
||||
until:
|
||||
- "postgres_pod['resources'] | length"
|
||||
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
|
||||
delay: 5
|
||||
retries: 60
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
|
||||
- block:
|
||||
- name: Get the postgres pod information
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
label_selectors:
|
||||
- "{{ postgres_label_selector }}"
|
||||
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
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
|
||||
when: awx_postgres_type == 'managed'
|
||||
|
||||
- name: Check for presence of AWX Deployment
|
||||
k8s_info:
|
||||
@@ -65,7 +67,7 @@
|
||||
- name: Set full resolvable host name for postgres pod
|
||||
set_fact:
|
||||
resolvable_db_host: "{{ awx_postgres_host }}.{{ ansible_operator_meta.namespace }}.svc.cluster.local"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: awx_postgres_type == 'managed'
|
||||
|
||||
- name: Set pg_restore command
|
||||
@@ -77,7 +79,7 @@
|
||||
-U {{ awx_postgres_user }}
|
||||
-d {{ awx_postgres_database }}
|
||||
-p {{ awx_postgres_port }}
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Restore database dump to the new postgresql container
|
||||
k8s_exec:
|
||||
@@ -86,9 +88,9 @@
|
||||
command: |
|
||||
bash -c """
|
||||
set -e -o pipefail
|
||||
cat {{ backup_dir }}/tower.db | PGPASSWORD={{ awx_postgres_pass }} {{ pg_restore }}
|
||||
cat {{ backup_dir }}/tower.db | PGPASSWORD='{{ awx_postgres_pass }}' {{ pg_restore }}
|
||||
echo 'Successful'
|
||||
"""
|
||||
register: data_migration
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
failed_when: "'Successful' not in data_migration.stdout"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
command: >-
|
||||
bash -c "cat '{{ backup_dir }}/secrets.yml'"
|
||||
register: _secrets
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create Temporary secrets file
|
||||
tempfile:
|
||||
@@ -20,38 +20,38 @@
|
||||
dest: "{{ tmp_secrets.path }}"
|
||||
content: "{{ _secrets.stdout }}"
|
||||
mode: 0640
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Include secret vars from backup
|
||||
include_vars: "{{ tmp_secrets.path }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: If deployment is managed, set the database_host in the pg config secret
|
||||
block:
|
||||
- name: Set new database host
|
||||
set_fact:
|
||||
database_host: "{{ deployment_name }}-postgres"
|
||||
no_log: true
|
||||
database_host: "{{ deployment_name }}-postgres-{{ supported_pg_version }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set tmp postgres secret dict
|
||||
set_fact:
|
||||
_pg_secret: "{{ secrets['postgresConfigurationSecret'] }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Change postgres host value
|
||||
set_fact:
|
||||
_pg_data: "{{ _pg_secret['data'] | combine({'host': database_host | b64encode }) }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create a postgres secret with the new host value
|
||||
set_fact:
|
||||
_pg_secret: "{{ _pg_secret | combine({'data': _pg_data}) }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create a new dict of secrets with the new postgres secret
|
||||
set_fact:
|
||||
secrets: "{{ secrets | combine({'postgresConfigurationSecret': _pg_secret}) }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
when: secrets['postgresConfigurationSecret']['data']['type'] | b64decode == 'managed'
|
||||
|
||||
- name: Apply secret
|
||||
@@ -61,7 +61,7 @@
|
||||
apply: yes
|
||||
wait: yes
|
||||
definition: "{{ lookup('template', 'secrets.yml.j2') }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Remove ownerReference on restored secrets
|
||||
k8s:
|
||||
@@ -73,4 +73,4 @@
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
ownerReferences: null
|
||||
loop: "{{ secrets | dict2items }}"
|
||||
no_log: true
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
deployment_type: "awx"
|
||||
_postgres_image: postgres
|
||||
_postgres_image_version: 12
|
||||
_postgres_image_version: 13
|
||||
|
||||
backup_api_version: '{{ deployment_type }}.ansible.com/v1beta1'
|
||||
backup_kind: 'AWXBackup'
|
||||
@@ -12,3 +12,4 @@ secret_key_secret: '{{ deployment_name }}-secret-key'
|
||||
admin_password_secret: '{{ deployment_name }}-admin-password'
|
||||
broadcast_websocket_secret: '{{ deployment_name }}-broadcast-websocket'
|
||||
postgres_configuration_secret: '{{ deployment_name }}-postgres-configuration'
|
||||
supported_pg_version: 13
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
kind: AWXBackup
|
||||
role: backup
|
||||
snakeCaseParameters: False
|
||||
finalizer:
|
||||
name: awx.ansible.com/finalizer
|
||||
role: backup
|
||||
vars:
|
||||
finalizer_run: true
|
||||
|
||||
- version: v1beta1
|
||||
group: awx.ansible.com
|
||||
|
||||
Reference in New Issue
Block a user