mirror of
https://github.com/ansible/awx-operator.git
synced 2026-03-27 05:43:11 +00:00
Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b10a8141c | ||
|
|
1ef1f00b3d | ||
|
|
234a10d185 | ||
|
|
e0fa1610ca | ||
|
|
5a856eeba8 | ||
|
|
d26a6bf641 | ||
|
|
8d6db0934f | ||
|
|
c1b2e73123 | ||
|
|
6ac8668ead | ||
|
|
ac5a2538bc | ||
|
|
2bdc87d0a8 | ||
|
|
ab566c2530 | ||
|
|
6a7c3ca2de | ||
|
|
f6f58d5c6d | ||
|
|
b1a547d2a6 | ||
|
|
43f98eda77 | ||
|
|
007e47e35c | ||
|
|
21eb83b052 | ||
|
|
1f8414b8cb | ||
|
|
a199a8c104 | ||
|
|
fb1639a5d4 | ||
|
|
19c6c77c41 | ||
|
|
4ee523ed69 | ||
|
|
4c5bae69ef | ||
|
|
9bf896e37c | ||
|
|
cb50f4f3ac | ||
|
|
066e55e179 | ||
|
|
f35bd7cf83 | ||
|
|
95a1fc082b | ||
|
|
dbd1e59a55 | ||
|
|
61f45147f6 | ||
|
|
c20f9b4128 | ||
|
|
15568fe564 | ||
|
|
1baf417504 | ||
|
|
7fbf1c42aa | ||
|
|
a5e21b56ae | ||
|
|
1399504142 | ||
|
|
e5896d15ed | ||
|
|
6b01ff09ce | ||
|
|
c708cef4dc | ||
|
|
1cf466def2 | ||
|
|
0fc145b6aa | ||
|
|
e30d26cf7b | ||
|
|
7c4a731995 | ||
|
|
d2efea08e6 | ||
|
|
23e94f82c0 | ||
|
|
de2e58f222 | ||
|
|
1c7c89efb3 | ||
|
|
096fe100f7 | ||
|
|
58ee2f0c74 | ||
|
|
93f7484f38 | ||
|
|
225c47dbbc | ||
|
|
2daf8a1320 | ||
|
|
5772c706d3 | ||
|
|
ae0a74bea3 | ||
|
|
97cd7a9b7a | ||
|
|
0975663a52 | ||
|
|
efdbd61860 | ||
|
|
13b45cbb12 | ||
|
|
d3ca9c57c9 | ||
|
|
9b1b5e676d | ||
|
|
17eb9cf8e8 | ||
|
|
ed7e2b2a28 | ||
|
|
5b7589accd | ||
|
|
a1e289e189 | ||
|
|
0611f3efaa | ||
|
|
a94a6f045d | ||
|
|
1892b8f0ea | ||
|
|
57b5795aab | ||
|
|
e8096a5f33 | ||
|
|
271bce48bd | ||
|
|
d64c34f8a4 | ||
|
|
1bddb98476 | ||
|
|
5f183999d0 | ||
|
|
3769897131 | ||
|
|
7f86231009 | ||
|
|
f59dac829a | ||
|
|
edecf4d2fe | ||
|
|
4120b5e2b0 | ||
|
|
8dabca5418 | ||
|
|
1d341a21d0 |
15
.github/workflows/ci.yaml
vendored
15
.github/workflows/ci.yaml
vendored
@@ -82,3 +82,18 @@ jobs:
|
||||
- name: Install helm chart
|
||||
run: |
|
||||
helm install --wait my-awx-operator --namespace awx --create-namespace ./charts/awx-operator
|
||||
no-log:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Check no_log statements
|
||||
run: |
|
||||
set +e
|
||||
no_log=$(grep -nr ' no_log:' roles | grep -v '"{{ no_log }}"')
|
||||
if [ -n "${no_log}" ]; then
|
||||
echo 'Please update the following no_log statement(s) with the "{{ no_log }}" value'
|
||||
echo "${no_log}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
54
.github/workflows/label_issue.yml
vendored
Normal file
54
.github/workflows/label_issue.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: Label Issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
name: Label
|
||||
|
||||
steps:
|
||||
- name: Label Issue - Needs Triage
|
||||
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'
|
||||
|
||||
community:
|
||||
runs-on: ubuntu-latest
|
||||
name: Label Issue - Community
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v4
|
||||
- name: Install python requests
|
||||
run: pip install requests
|
||||
- name: Check if user is a member of Ansible org
|
||||
uses: jannekem/run-python-script-action@v1
|
||||
id: check_user
|
||||
with:
|
||||
script: |
|
||||
import requests
|
||||
headers = {'Accept': 'application/vnd.github+json', 'Authorization': 'token ${{ secrets.GITHUB_TOKEN }}'}
|
||||
response = requests.get('${{ fromJson(toJson(github.event.issue.user.url)) }}/orgs?per_page=100', headers=headers)
|
||||
is_member = False
|
||||
for org in response.json():
|
||||
if org['login'] == 'ansible':
|
||||
is_member = True
|
||||
if is_member:
|
||||
print("User is member")
|
||||
else:
|
||||
print("User is community")
|
||||
- name: Add community label if not a member
|
||||
if: contains(steps.check_user.outputs.stdout, 'community')
|
||||
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90
|
||||
with:
|
||||
add-labels: "community"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
40
.github/workflows/label_pr.yml
vendored
Normal file
40
.github/workflows/label_pr.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: Label PR
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
community:
|
||||
runs-on: ubuntu-latest
|
||||
name: Label PR - Community
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v4
|
||||
- name: Install python requests
|
||||
run: pip install requests
|
||||
- name: Check if user is a member of Ansible org
|
||||
uses: jannekem/run-python-script-action@v1
|
||||
id: check_user
|
||||
with:
|
||||
script: |
|
||||
import requests
|
||||
headers = {'Accept': 'application/vnd.github+json', 'Authorization': 'token ${{ secrets.GITHUB_TOKEN }}'}
|
||||
response = requests.get('${{ fromJson(toJson(github.event.pull_request.user.url)) }}/orgs?per_page=100', headers=headers)
|
||||
is_member = False
|
||||
for org in response.json():
|
||||
if org['login'] == 'ansible':
|
||||
is_member = True
|
||||
if is_member:
|
||||
print("User is member")
|
||||
else:
|
||||
print("User is community")
|
||||
- name: Add community label if not a member
|
||||
if: contains(steps.check_user.outputs.stdout, 'community')
|
||||
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90
|
||||
with:
|
||||
add-labels: "community"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
18
.github/workflows/pr_body_check.yml
vendored
18
.github/workflows/pr_body_check.yml
vendored
@@ -13,21 +13,13 @@ jobs:
|
||||
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
|
||||
env:
|
||||
PR_BODY: ${{ github.event.pull_request.body }}
|
||||
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
|
||||
echo "$PR_BODY" | grep "Bug, Docs Fix or other nominal change" > Z
|
||||
echo "$PR_BODY" | grep "New or Enhanced Feature" > Y
|
||||
echo "$PR_BODY" | grep "Breaking Change" > X
|
||||
exit 0
|
||||
# We exit 0 and set the shell to prevent the returns from the greps from failing this step
|
||||
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
|
||||
|
||||
9
.github/workflows/promote.yaml
vendored
9
.github/workflows/promote.yaml
vendored
@@ -8,7 +8,14 @@ jobs:
|
||||
promote:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
depth: 0
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: gh-pages
|
||||
path: gh-pages
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: |
|
||||
|
||||
22
.github/workflows/triage_new.yml
vendored
22
.github/workflows/triage_new.yml
vendored
@@ -1,22 +0,0 @@
|
||||
---
|
||||
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'
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
*~
|
||||
gh-pages/
|
||||
.cache/
|
||||
/bin
|
||||
/bundle
|
||||
@@ -7,3 +8,4 @@
|
||||
/charts
|
||||
/.cr-release-packages
|
||||
.vscode/
|
||||
__pycache__
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AWX Operator Helm Chart
|
||||
|
||||
This chart installs the AWX Operator resources configured in [this](https://github.com/ansible/awx-operator) repository.
|
||||
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.
|
||||
@@ -8,7 +8,7 @@ To configure your AWX resource using this chart, create your own `yaml` values f
|
||||
In your values config, enable `AWX.enabled` 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.
|
||||
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:
|
||||
```
|
||||
@@ -27,10 +27,10 @@ To update an existing installation, use `helm upgrade` instead of `install`. The
|
||||
## 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.
|
||||
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`.
|
||||
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`. Supplying the password this way is not recommended for production use, but may be helpful for initial PoC.
|
||||
|
||||
|
||||
## Values Summary
|
||||
@@ -44,13 +44,24 @@ The `AWX.postgres` section simplifies the creation of the external postgres secr
|
||||
| `AWX.postgres` | configurations for the external postgres secret | - |
|
||||
|
||||
|
||||
# Contributing
|
||||
# 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.
|
||||
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.
|
||||
|
||||
|
||||
# Chart Publishing
|
||||
|
||||
The chart is currently hosted on the gh-pages branch of the repo. During the release pipeline, the `index.yaml` stored in that branch is generated with helm chart entries from all valid tags. We are currently unable to use the `chart-releaser` pipeline due to the fact that the complete helm chart is not committed to the repo and is instead built during the release process. Therefore, the cr action is unable to compare against previous versions.
|
||||
|
||||
Instead of CR, we use `helm repo index` to generate an index from all locally pulled chart versions. Since we build from scratch every time, the timestamps of all entries will be updated. This could be improved by using yq or something similar to detect which tags are already in the index.yaml file, and only merge in tags that are not present.
|
||||
|
||||
Not using CR could be addressed in the future by keeping the chart built as a part of releases, as long as CR compares the chart to previous release packages rather than previous commits. If the latter is the case, then we would not have the necessary history for comparison.
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
FROM quay.io/operator-framework/ansible-operator:v1.22.2
|
||||
FROM quay.io/operator-framework/ansible-operator:v1.25.3
|
||||
|
||||
USER 0
|
||||
|
||||
RUN dnf install -y openssl
|
||||
|
||||
USER 1001
|
||||
|
||||
ARG DEFAULT_AWX_VERSION
|
||||
ARG OPERATOR_VERSION
|
||||
|
||||
78
Makefile
78
Makefile
@@ -140,7 +140,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/v4.5.2/kustomize_v4.5.2_$(OS)_$(ARCHA).tar.gz | \
|
||||
curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v4.5.7/kustomize_v4.5.7_$(OS)_$(ARCHA).tar.gz | \
|
||||
tar xzf - -C bin/ ;\
|
||||
}
|
||||
else
|
||||
@@ -156,7 +156,7 @@ ifeq (,$(shell which ansible-operator 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(ANSIBLE_OPERATOR)) ;\
|
||||
curl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.22.2/ansible-operator_$(OS)_$(ARCHA) ;\
|
||||
curl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.25.3/ansible-operator_$(OS)_$(ARCHA) ;\
|
||||
chmod +x $(ANSIBLE_OPERATOR) ;\
|
||||
}
|
||||
else
|
||||
@@ -187,7 +187,7 @@ ifeq (,$(shell which opm 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(OPM)) ;\
|
||||
curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$(OS)-$(ARCHA)-opm ;\
|
||||
curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.25.3/$(OS)-$(ARCHA)-opm ;\
|
||||
chmod +x $(OPM) ;\
|
||||
}
|
||||
else
|
||||
@@ -296,8 +296,8 @@ helm-chart: helm-chart-generate
|
||||
helm-chart-generate: kustomize helm kubectl-slice yq charts
|
||||
@echo "== KUSTOMIZE: Set image and chart label =="
|
||||
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
|
||||
cd config/manager && $(KUSTOMIZE) edit set label helm.sh/chart:$(CHART_NAME)-$(VERSION)
|
||||
cd config/default && $(KUSTOMIZE) edit set label helm.sh/chart:$(CHART_NAME)-$(VERSION)
|
||||
cd config/manager && $(KUSTOMIZE) edit set label helm.sh/chart:$(CHART_NAME)
|
||||
cd config/default && $(KUSTOMIZE) edit set label helm.sh/chart:$(CHART_NAME)
|
||||
|
||||
@echo "== Gather Helm Chart Metadata =="
|
||||
# remove the existing chart if it exists
|
||||
@@ -350,26 +350,54 @@ helm-chart-generate: kustomize helm kubectl-slice yq charts
|
||||
|
||||
|
||||
.PHONY: helm-package
|
||||
helm-package: cr helm-chart
|
||||
@echo "== CHART RELEASER (package) =="
|
||||
$(CR) package ./charts/awx-operator
|
||||
helm-package: helm-chart
|
||||
@echo "== Package Current Chart Version =="
|
||||
mkdir -p .cr-release-packages
|
||||
# package the chart and put it in .cr-release-packages dir
|
||||
$(HELM) package ./charts/awx-operator -d .cr-release-packages
|
||||
|
||||
# The actual release happens in ansible/helm-release.yml
|
||||
# until https://github.com/helm/chart-releaser/issues/122 happens
|
||||
# List all tags oldest to newest.
|
||||
TAGS := $(shell git ls-remote --tags --sort=version:refname --refs -q | cut -d/ -f3)
|
||||
|
||||
# The actual release happens in ansible/helm-release.yml, which calls this targer
|
||||
# until https://github.com/helm/chart-releaser/issues/122 happens, chart-releaser is not ideal for a chart
|
||||
# that is contained within a larger repo, where a tag may not require a new chart version
|
||||
.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
|
||||
helm-index:
|
||||
# when running in CI this gh-pages are already checked out with github action to 'gh-pages' directory
|
||||
# TODO: test if gh-pages directory exists and if not exist
|
||||
|
||||
@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
|
||||
@echo "== GENERATE INDEX FILE =="
|
||||
# This step to workaround issues with old releases being dropped.
|
||||
# Until https://github.com/helm/chart-releaser/issues/133 happens
|
||||
@echo "== CHART FETCH previous releases =="
|
||||
# Download all old releases
|
||||
mkdir -p .cr-release-packages
|
||||
|
||||
for tag in $(TAGS); do\
|
||||
dl_url="https://github.com/$(CHART_OWNER)/$(CHART_REPO)/releases/download/$${tag}/$(CHART_REPO)-$${tag}.tgz";\
|
||||
echo "Downloading $${tag} from $${dl_url}";\
|
||||
curl -RLOs -z "$(CHART_REPO)-$${tag}.tgz" --fail $${dl_url};\
|
||||
result=$$?;\
|
||||
if [ $${result} -eq 0 ]; then\
|
||||
echo "Downloaded $${dl_url}";\
|
||||
mkdir -p .cr-release-packages/$${tag};\
|
||||
mv ./$(CHART_REPO)-$${tag}.tgz .cr-release-packages/$${tag};\
|
||||
else\
|
||||
echo "Skipping release $${tag}; No helm chart present";\
|
||||
rm -rf "$(CHART_REPO)-$${tag}.tgz";\
|
||||
fi;\
|
||||
done;\
|
||||
|
||||
# generate the index file in the root of the gh-pages branch
|
||||
# --merge will leave any values in index.yaml that don't get generated by this command, but
|
||||
# it is likely that all values are overridden
|
||||
$(HELM) repo index .cr-release-packages --url https://github.com/$(CHART_OWNER)/$(CHART_REPO)/releases/download/ --merge gh-pages/index.yaml
|
||||
|
||||
mv .cr-release-packages/index.yaml gh-pages/index.yaml
|
||||
|
||||
@echo "== PUSH INDEX FILE =="
|
||||
cd gh-pages;\
|
||||
git add index.yaml;\
|
||||
git commit -m "Updated index.yaml latest release";\
|
||||
git push;\
|
||||
|
||||
198
README.md
198
README.md
@@ -48,6 +48,7 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
|
||||
* [Auto Upgrade](#auto-upgrade)
|
||||
* [Upgrade of instances without auto upgrade](#upgrade-of-instances-without-auto-upgrade)
|
||||
* [Service Account](#service-account)
|
||||
* [Labeling operator managed objects](#labeling-operator-managed-objects)
|
||||
* [Uninstall](#uninstall)
|
||||
* [Upgrading](#upgrading)
|
||||
* [Backup](#backup)
|
||||
@@ -55,6 +56,9 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
|
||||
* [Cluster-scope to Namespace-scope considerations](#cluster-scope-to-namespace-scope-considerations)
|
||||
* [Project is now based on v1.x of the operator-sdk project](#project-is-now-based-on-v1x-of-the-operator-sdk-project)
|
||||
* [Steps to upgrade](#steps-to-upgrade)
|
||||
* [Disable IPV6](#disable-ipv6)
|
||||
* [Add Execution Nodes](#adding-execution-nodes)
|
||||
* [Custom Receptor CA](#custom-receptor-ca)
|
||||
* [Contributing](#contributing)
|
||||
* [Release Process](#release-process)
|
||||
* [Author](#author)
|
||||
@@ -195,12 +199,24 @@ metadata:
|
||||
name: awx-demo
|
||||
spec:
|
||||
service_type: nodeport
|
||||
# default nodeport_port is 30080
|
||||
nodeport_port: <nodeport_port>
|
||||
```
|
||||
|
||||
> It may make sense to create and specify your own secret key for your deployment so that if the k8s secret gets deleted, it can be re-created if needed. If it is not provided, one will be auto-generated, but cannot be recovered if lost. Read more [here](#secret-key-configuration).
|
||||
|
||||
If you are on Openshift, you can take advantage of Routes by specifying the following your spec. This will automatically create a Route for you with a custom hostname. This can be found on the Route section of the Openshift Console.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx-demo
|
||||
spec:
|
||||
service_type: clusterip
|
||||
ingress_type: Route
|
||||
```
|
||||
|
||||
|
||||
Make sure to add this new file to the list of "resources" in your `kustomization.yaml` file:
|
||||
|
||||
```yaml
|
||||
@@ -241,13 +257,13 @@ awx-demo-service NodePort 10.109.40.38 <none> 80:31006/TCP 3m56
|
||||
Once deployed, the AWX instance will be accessible by running:
|
||||
|
||||
```
|
||||
$ minikube service awx-demo-service --url -n $NAMESPACE
|
||||
$ minikube service -n awx awx-demo-service --url
|
||||
```
|
||||
|
||||
By default, the admin user is `admin` and the password is available in the `<resourcename>-admin-password` secret. To retrieve the admin password, run:
|
||||
|
||||
```
|
||||
$ kubectl get secret awx-demo-admin-password -o jsonpath="{.data.password}" | base64 --decode
|
||||
$ kubectl get secret awx-demo-admin-password -o jsonpath="{.data.password}" | base64 --decode ; echo
|
||||
yDL2Cx5Za94g9MvBP6B73nzVLlmfgPjR
|
||||
```
|
||||
|
||||
@@ -301,7 +317,7 @@ There are three variables that are customizable for the admin user account creat
|
||||
|
||||
If `admin_password_secret` is not provided, the operator will look for a secret named `<resourcename>-admin-password` for the admin password. If it is not present, the operator will generate a password and create a Secret from it named `<resourcename>-admin-password`.
|
||||
|
||||
To retrieve the admin password, run `kubectl get secret <resourcename>-admin-password -o jsonpath="{.data.password}" | base64 --decode`
|
||||
To retrieve the admin password, run `kubectl get secret <resourcename>-admin-password -o jsonpath="{.data.password}" | base64 --decode ; echo`
|
||||
|
||||
The secret that is expected to be passed should be formatted as follow:
|
||||
|
||||
@@ -442,9 +458,11 @@ The following variables are customizable when `ingress_type=ingress`. The `ingre
|
||||
| ------------------- | ---------------------------------------- | --------------------------- |
|
||||
| ingress_annotations | Ingress annotations | Empty string |
|
||||
| ingress_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
| ingress_class_name | Define the ingress class name | Cluster default |
|
||||
| hostname | Define the FQDN | {{ meta.name }}.example.com |
|
||||
| ingress_path | Define the ingress path to the service | / |
|
||||
| ingress_path_type | Define the type of the path (for LBs) | Prefix |
|
||||
| ingress_api_version | Define the Ingress resource apiVersion | 'networking.k8s.io/v1' |
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -465,6 +483,7 @@ The following variables are customizable when `ingress_type=route`
|
||||
| route_host | Common name the route answers for | `<instance-name>-<namespace>-<routerCanonicalHostname>` |
|
||||
| route_tls_termination_mechanism | TLS Termination mechanism (Edge, Passthrough) | Edge |
|
||||
| route_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
| route_api_version | Define the Route resource apiVersion | 'route.openshift.io/v1' |
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -478,6 +497,12 @@ spec:
|
||||
|
||||
### Database Configuration
|
||||
|
||||
#### Postgres Version
|
||||
|
||||
The default Postgres version for the version of AWX bundled with the latest version of the awx-operator is Postgres 13. You can find this default for a given version by at the default value for [_postgres_image_version](./roles/installer/defaults/main.yml#L138).
|
||||
|
||||
We only have coverage for the default version of Postgres. Newer versions of Postgres (14+) will likely work, but should only be configured as an external database. If your database is managed by the awx-operator (default if you don't specify a `postgres_configuration_secret`), then you should not override the default version as this may cause issues when awx-operator tries to upgrade your postgresql pod.
|
||||
|
||||
#### External PostgreSQL Service
|
||||
|
||||
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.
|
||||
@@ -695,18 +720,20 @@ You can constrain the AWX pods created by the operator to run on a certain subse
|
||||
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`
|
||||
If you want to use affinity rules for your AWX pod you can use the `affinity` option.
|
||||
|
||||
|
||||
| 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 | '' |
|
||||
| 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 | '' |
|
||||
| affinity | AWX pods' affinity rules | '' |
|
||||
| tolerations | AWX pods' tolerations | '' |
|
||||
| annotations | AWX pods' annotations | '' |
|
||||
| postgres_selector | Postgres pods' nodeSelector | '' |
|
||||
| postgres_tolerations | Postgres pods' tolerations | '' |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
@@ -739,6 +766,28 @@ spec:
|
||||
operator: "Equal"
|
||||
value: "AWX"
|
||||
effect: "NoSchedule"
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 1
|
||||
preference:
|
||||
matchExpressions:
|
||||
- key: another-node-label-key
|
||||
operator: In
|
||||
values:
|
||||
- another-node-label-value
|
||||
- another-node-label-value
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: security
|
||||
operator: In
|
||||
values:
|
||||
- S2
|
||||
topologyKey: topology.kubernetes.io/zone
|
||||
```
|
||||
|
||||
#### Trusting a Custom Certificate Authority
|
||||
@@ -766,7 +815,22 @@ spec:
|
||||
bundle_cacert_secret: <resourcename>-custom-certs
|
||||
```
|
||||
|
||||
To create the secrets, you can use the commands below:
|
||||
Create the secret with `kustomization.yaml` file:
|
||||
|
||||
```yaml
|
||||
....
|
||||
|
||||
secretGenerator:
|
||||
- name: <resourcename>-custom-certs
|
||||
files:
|
||||
- bundle-ca.crt=<path+filename>
|
||||
options:
|
||||
disableNameSuffixHash: true
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Create the secret with CLI:
|
||||
|
||||
* Certificate Authority secret
|
||||
|
||||
@@ -948,6 +1012,17 @@ Example spec file for volumes and volume mounts
|
||||
|
||||
> :warning: **Volume and VolumeMount names cannot contain underscores(_)**
|
||||
|
||||
##### Custom Nginx Configuration
|
||||
|
||||
Using the [extra_volumes feature](#custom-volume-and-volume-mount-options), it is possible to extend the nginx.conf.
|
||||
|
||||
1. Create a ConfigMap with the extra settings you want to include in the nginx.conf
|
||||
2. Create an extra_volumes entry in the AWX spec for this ConfigMap
|
||||
3. Create an web_extra_volume_mounts entry in the AWX spec to mount this volume
|
||||
|
||||
The AWX nginx config automatically includes /etc/nginx/conf.d/*.conf if present.
|
||||
|
||||
|
||||
#### Default execution environments from private registries
|
||||
|
||||
In order to register default execution environments from private registries, the Custom Resource needs to know about the pull credentials. Those credentials should be stored as a secret and either specified as `ee_pull_credentials_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-ee-pull-credentials` . Instance initialization will register a `Container registry` type credential on the deployed instance and assign it to the registered default execution environments.
|
||||
@@ -1067,8 +1142,14 @@ Example configuration of `extra_settings` parameter
|
||||
|
||||
- setting: AUTH_LDAP_BIND_DN
|
||||
value: "cn=admin,dc=example,dc=com"
|
||||
|
||||
- setting: LOG_AGGREGATOR_LEVEL
|
||||
value: "'DEBUG'"
|
||||
```
|
||||
|
||||
Note for some settings, such as `LOG_AGGREGATOR_LEVEL`, the value may need double quotes.
|
||||
|
||||
|
||||
#### No Log
|
||||
Configure no_log for tasks with no_log
|
||||
|
||||
@@ -1080,7 +1161,7 @@ Example configuration of `no_log` parameter
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
no_log: 'true'
|
||||
no_log: true
|
||||
```
|
||||
|
||||
#### Auto upgrade
|
||||
@@ -1136,6 +1217,34 @@ Example configuration of environment variables
|
||||
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME>
|
||||
```
|
||||
|
||||
#### Labeling operator managed objects
|
||||
|
||||
In certain situations labeling of Kubernetes objects managed by the operator
|
||||
might be desired (e.g. for owner identification purposes). For that
|
||||
`additional_labels` parameter could be used
|
||||
|
||||
| Name | Description | Default |
|
||||
| --------------------------- | ---------------------------------------------------------------------------------------- | ------- |
|
||||
| additional_labels | Additional labels defined on the resource, which should be propagated to child resources | [] |
|
||||
|
||||
Example configuration where only `my/team` and `my/service` labels will be
|
||||
propagated to child objects (`Deployment`, `Secret`s, `ServiceAccount`, etc):
|
||||
|
||||
```yaml
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx-demo
|
||||
labels:
|
||||
my/team: "foo"
|
||||
my/service: "bar"
|
||||
my/do-not-inherit: "yes"
|
||||
spec:
|
||||
additional_labels:
|
||||
- my/team
|
||||
- my/service
|
||||
...
|
||||
```
|
||||
|
||||
### Uninstall ###
|
||||
|
||||
@@ -1158,7 +1267,14 @@ Apply the awx-operator.yml for that release to upgrade the operator, and in turn
|
||||
|
||||
#### 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).
|
||||
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). *Before Restoring from a backup*, be sure to:
|
||||
* delete the old existing AWX CR
|
||||
* delete the persistent volume claim (PVC) for the database from the old deployment, which has a name like `postgres-13-<deployment-name>-postgres-13-0`
|
||||
|
||||
**Note**: Do not delete the namespace/project, as that will delete the backup and the backup's PVC as well.
|
||||
|
||||
|
||||
#### PostgreSQL Upgrade Considerations
|
||||
|
||||
@@ -1199,6 +1315,52 @@ Then install the new AWX Operator by following the instructions in [Basic Instal
|
||||
|
||||
Once the new AWX Operator is up and running, your AWX deployment will also be upgraded.
|
||||
|
||||
### Disable IPV6
|
||||
Starting with AWX Operator release 0.24.0,[IPV6 was enabled in ngnix configuration](https://github.com/ansible/awx-operator/pull/950) which causes
|
||||
upgrades and installs to fail in environments where IPv6 is not allowed. Starting in 1.1.1 release, you can set the `ipv6_disabled` flag on the AWX
|
||||
spec. If you need to use an AWX operator version between 0.24.0 and 1.1.1 in an IPv6 disabled environment, it is suggested to enabled ipv6 on worker
|
||||
nodes.
|
||||
|
||||
In order to disable ipv6 on ngnix configuration (awx-web container), add following to the AWX spec.
|
||||
|
||||
The following variables are customizable
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------- | ---------------------- | ------- |
|
||||
| ipv6_disabled | Flag to disable ipv6 | false |
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
ipv6_disabled: true
|
||||
```
|
||||
|
||||
### Adding Execution Nodes
|
||||
Starting with AWX Operator v0.30.0 and AWX v21.7.0, standalone execution nodes can be added to your deployments.
|
||||
See [AWX execution nodes docs](https://github.com/ansible/awx/blob/devel/docs/execution_nodes.md) for information about this feature.
|
||||
|
||||
#### Custom Receptor CA
|
||||
The control nodes on the K8S cluster will communicate with execution nodes via mutual TLS TCP connections, running via Receptor.
|
||||
Execution nodes will verify incoming connections by ensuring the x509 certificate was issued by a trusted Certificate Authority (CA).
|
||||
|
||||
A user may wish to provide their own CA for this validation. If no CA is provided, AWX Operator will automatically generate one using OpenSSL.
|
||||
|
||||
Given custom `ca.crt` and `ca.key` stored locally, run the following,
|
||||
|
||||
```bash
|
||||
kubectl create secret tls awx-demo-receptor-ca \
|
||||
--cert=/path/to/ca.crt --key=/path/to/ca.key
|
||||
```
|
||||
|
||||
The secret should be named `{AWX Custom Resource name}-receptor-ca`. In the above the AWX CR name is "awx-demo". Please replace "awx-demo" with your AWX Custom Resource name.
|
||||
|
||||
If this secret is created after AWX is deployed, run the following to restart the deployment,
|
||||
|
||||
```bash
|
||||
kubectl rollout restart deployment awx-demo
|
||||
```
|
||||
|
||||
**Important Note**, changing the receptor CA will break connections to any existing execution nodes. These nodes will enter an `unavailable` state, and jobs will not be able to run on them. Users will need to download and re-run the install bundle for each execution node. This will replace the TLS certificate files with those signed by the new CA. The execution nodes should then appear in a `ready` state after a few minutes.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please visit [our contributing guidelines](https://github.com/ansible/awx-operator/blob/devel/CONTRIBUTING.md).
|
||||
|
||||
@@ -55,7 +55,7 @@ spec:
|
||||
description: Storage requirements for backup PVC (may be similar to existing postgres PVC backing up from)
|
||||
type: string
|
||||
backup_resource_requirements:
|
||||
description: Resource requirements for the task container
|
||||
description: Resource requirements for the management pod used to create a backup
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
@@ -78,6 +78,9 @@ spec:
|
||||
clean_backup_on_delete:
|
||||
description: Flag to indicate if backup should be deleted on PVC if AWXBackup object is deleted
|
||||
type: boolean
|
||||
pg_dump_suffix:
|
||||
description: Additional parameters for the pg_dump command
|
||||
type: string
|
||||
postgres_label_selector:
|
||||
description: Label selector used to identify postgres pod for backing up data
|
||||
type: string
|
||||
@@ -89,7 +92,13 @@ spec:
|
||||
type: string
|
||||
no_log:
|
||||
description: Configure no_log for no_log tasks
|
||||
type: string
|
||||
type: boolean
|
||||
default: true
|
||||
additional_labels:
|
||||
description: Additional labels defined on the resource, which should be propagated to child resources
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
set_self_labels:
|
||||
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
type: boolean
|
||||
|
||||
@@ -50,6 +50,9 @@ spec:
|
||||
description: Name of the restored deployment. This should be different from the original deployment name
|
||||
if the original deployment still exists.
|
||||
type: string
|
||||
cluster_name:
|
||||
description: Cluster name
|
||||
type: string
|
||||
backup_name:
|
||||
description: AWXBackup object name
|
||||
type: string
|
||||
@@ -62,8 +65,8 @@ spec:
|
||||
backup_dir:
|
||||
description: Backup directory name, set as a status found on the awxbackup object (backupDirectory)
|
||||
type: string
|
||||
backup_resource_requirements:
|
||||
description: Resource requirements for the management pod that backs up AWX
|
||||
restore_resource_requirements:
|
||||
description: Resource requirements for the management pod that restores AWX from a backup
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
@@ -91,7 +94,13 @@ spec:
|
||||
type: string
|
||||
no_log:
|
||||
description: Configure no_log for no_log tasks
|
||||
type: string
|
||||
type: boolean
|
||||
default: true
|
||||
additional_labels:
|
||||
description: Additional labels defined on the resource, which should be propagated to child resources
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
set_self_labels:
|
||||
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
type: boolean
|
||||
|
||||
@@ -103,6 +103,9 @@ spec:
|
||||
- ingress
|
||||
- Route
|
||||
- route
|
||||
ingress_api_version:
|
||||
description: The Ingress API version to use
|
||||
type: string
|
||||
ingress_path:
|
||||
description: The ingress path used to reach the deployed service
|
||||
type: string
|
||||
@@ -115,6 +118,9 @@ spec:
|
||||
ingress_tls_secret:
|
||||
description: Secret where the Ingress TLS secret can be found
|
||||
type: string
|
||||
ingress_class_name:
|
||||
description: The name of ingress class to use instead of the cluster default.
|
||||
type: string
|
||||
loadbalancer_protocol:
|
||||
description: Protocol to use for the loadbalancer
|
||||
type: string
|
||||
@@ -138,19 +144,387 @@ spec:
|
||||
- edge
|
||||
- Passthrough
|
||||
- passthrough
|
||||
route_api_version:
|
||||
description: The route API version to use
|
||||
type: string
|
||||
route_tls_secret:
|
||||
description: Secret where the TLS related credentials are stored
|
||||
type: string
|
||||
nodeport_port:
|
||||
description: Port to use for the nodeport
|
||||
type: integer
|
||||
default: 30080
|
||||
node_selector:
|
||||
description: nodeSelector for the pods
|
||||
type: string
|
||||
topology_spread_constraints:
|
||||
description: topology rule(s) for the pods
|
||||
type: string
|
||||
affinity:
|
||||
description: If specified, the pod's scheduling constraints
|
||||
properties:
|
||||
nodeAffinity:
|
||||
properties:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
items:
|
||||
properties:
|
||||
preference:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchFields:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
weight:
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- preference
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
properties:
|
||||
nodeSelectorTerms:
|
||||
items:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchFields:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
required:
|
||||
- nodeSelectorTerms
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
type: object
|
||||
podAffinity:
|
||||
properties:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
items:
|
||||
properties:
|
||||
podAffinityTerm:
|
||||
properties:
|
||||
labelSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaceSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
topologyKey:
|
||||
type: string
|
||||
required:
|
||||
- topologyKey
|
||||
type: object
|
||||
weight:
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- podAffinityTerm
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
items:
|
||||
properties:
|
||||
labelSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaceSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
topologyKey:
|
||||
type: string
|
||||
required:
|
||||
- topologyKey
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
podAntiAffinity:
|
||||
properties:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
items:
|
||||
properties:
|
||||
podAffinityTerm:
|
||||
properties:
|
||||
labelSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaceSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
topologyKey:
|
||||
type: string
|
||||
required:
|
||||
- topologyKey
|
||||
type: object
|
||||
weight:
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- podAffinityTerm
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
items:
|
||||
properties:
|
||||
labelSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaceSelector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
topologyKey:
|
||||
type: string
|
||||
required:
|
||||
- topologyKey
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
service_labels:
|
||||
description: Additional labels to apply to the service
|
||||
type: string
|
||||
@@ -501,7 +875,8 @@ spec:
|
||||
type: array
|
||||
no_log:
|
||||
description: Configure no_log for no_log tasks
|
||||
type: string
|
||||
type: boolean
|
||||
default: true
|
||||
security_context_settings:
|
||||
description: Key/values that will be set under the pod-level securityContext field
|
||||
type: object
|
||||
@@ -514,6 +889,15 @@ spec:
|
||||
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
type: boolean
|
||||
default: true
|
||||
additional_labels:
|
||||
description: Additional labels defined on the resource, which should be propagated to child resources
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
ipv6_disabled:
|
||||
description: Disable web container's nginx ipv6 listener
|
||||
type: boolean
|
||||
default: false
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxbackups.awx.ansible.com
|
||||
spec:
|
||||
group: awx.ansible.com
|
||||
names:
|
||||
kind: AWXBackup
|
||||
listKind: AWXBackupList
|
||||
plural: awxbackups
|
||||
singular: awxbackup
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
description: Schema validation for the AWXBackup CRD
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
required:
|
||||
- deployment_name
|
||||
properties:
|
||||
backup_resource_requirements:
|
||||
description: Resource requirements for the task container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
deployment_name:
|
||||
description: Name of the deployment to be backed up
|
||||
type: string
|
||||
backup_pvc:
|
||||
description: Name of the backup PVC
|
||||
type: string
|
||||
backup_pvc_namespace:
|
||||
description: (Deprecated) Namespace the PVC is in
|
||||
type: string
|
||||
backup_storage_requirements:
|
||||
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
|
||||
postgres_image:
|
||||
description: Registry path to the PostgreSQL container to use
|
||||
type: string
|
||||
postgres_image_version:
|
||||
description: PostgreSQL container image version to use
|
||||
type: string
|
||||
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:
|
||||
conditions:
|
||||
description: The resulting conditions when a Service Telemetry is instantiated
|
||||
items:
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
backupDirectory:
|
||||
description: Backup directory name on the specified pvc
|
||||
type: string
|
||||
backupClaim:
|
||||
description: Backup persistent volume claim
|
||||
type: string
|
||||
@@ -1,104 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxrestores.awx.ansible.com
|
||||
spec:
|
||||
group: awx.ansible.com
|
||||
names:
|
||||
kind: AWXRestore
|
||||
listKind: AWXRestoreList
|
||||
plural: awxrestores
|
||||
singular: awxrestore
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
description: Schema validation for the AWXRestore CRD
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
backup_source:
|
||||
description: Backup source
|
||||
type: string
|
||||
enum:
|
||||
- CR
|
||||
- PVC
|
||||
restore_resource_requirements:
|
||||
description: Resource requirements for the management pod the restores the database to the new AWX instance
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
deployment_name:
|
||||
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
|
||||
type: string
|
||||
backup_pvc:
|
||||
description: Name of the PVC to be restored from, set as a status found on the awxbackup object (backupClaim)
|
||||
type: string
|
||||
backup_pvc_namespace:
|
||||
description: (Deprecated) Namespace the PVC is in
|
||||
type: string
|
||||
backup_dir:
|
||||
description: Backup directory name, set as a status found on the awxbackup object (backupDirectory)
|
||||
type: string
|
||||
postgres_label_selector:
|
||||
description: Label selector used to identify postgres pod for backing up data
|
||||
type: string
|
||||
postgres_image:
|
||||
description: Registry path to the PostgreSQL container to use
|
||||
type: string
|
||||
postgres_image_version:
|
||||
description: PostgreSQL container image version to use
|
||||
type: string
|
||||
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:
|
||||
conditions:
|
||||
description: The resulting conditions when a Service Telemetry is instantiated
|
||||
items:
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
restoreComplete:
|
||||
description: Restore process complete
|
||||
type: boolean
|
||||
@@ -9,10 +9,12 @@ namespace: awx
|
||||
namePrefix: awx-operator-
|
||||
|
||||
# Labels to add to all resources and selectors.
|
||||
#commonLabels:
|
||||
# someName: someValue
|
||||
#labels:
|
||||
#- includeSelectors: true
|
||||
# pairs:
|
||||
# someName: someValue
|
||||
|
||||
bases:
|
||||
resources:
|
||||
- ../crd
|
||||
- ../rbac
|
||||
- ../manager
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - "ALL"
|
||||
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
|
||||
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0
|
||||
args:
|
||||
- "--secure-listen-address=0.0.0.0:8443"
|
||||
- "--upstream=http://127.0.0.1:8080/"
|
||||
|
||||
@@ -21,7 +21,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/default-container: manager
|
||||
kubectl.kubernetes.io/default-container: awx-manager
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- basic-check-spec
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
image: quay.io/operator-framework/scorecard-test:v1.25.3
|
||||
labels:
|
||||
suite: basic
|
||||
test: basic-check-spec-test
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-bundle-validation
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
image: quay.io/operator-framework/scorecard-test:v1.25.3
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-bundle-validation-test
|
||||
@@ -14,7 +14,7 @@
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-crds-have-validation
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
image: quay.io/operator-framework/scorecard-test:v1.25.3
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-crds-have-validation-test
|
||||
@@ -24,7 +24,7 @@
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-crds-have-resources
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
image: quay.io/operator-framework/scorecard-test:v1.25.3
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-crds-have-resources-test
|
||||
@@ -34,7 +34,7 @@
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-spec-descriptors
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
image: quay.io/operator-framework/scorecard-test:v1.25.3
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-spec-descriptors-test
|
||||
@@ -44,7 +44,7 @@
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-status-descriptors
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
image: quay.io/operator-framework/scorecard-test:v1.25.3
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-status-descriptors-test
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
register: awx_pod
|
||||
when: not awx_version
|
||||
|
||||
- name: Exract tags from images
|
||||
- name: Extract tags from images
|
||||
set_fact:
|
||||
image_tags: |
|
||||
{{ awx_pod.resources[0].spec.containers |
|
||||
@@ -83,3 +83,61 @@
|
||||
result: '{{ ansible_failed_result }}'
|
||||
fail:
|
||||
msg: '{{ failed_task }}'
|
||||
|
||||
- block:
|
||||
- name: Look up details for this deployment
|
||||
k8s_info:
|
||||
namespace: "{{ namespace }}"
|
||||
api_version: "awx.ansible.com/v1beta1"
|
||||
kind: AWX
|
||||
name: example-awx
|
||||
register: this_awx
|
||||
|
||||
- name: Get pod details
|
||||
k8s_info:
|
||||
namespace: '{{ namespace }}'
|
||||
kind: Pod
|
||||
label_selectors:
|
||||
- app.kubernetes.io/name = example-awx
|
||||
register: awx_pod
|
||||
|
||||
- name: Extract additional_labels from AWX spec
|
||||
set_fact:
|
||||
awx_additional_labels: >-
|
||||
{{ this_awx.resources[0].metadata.labels
|
||||
| dict2items | selectattr('key', 'in', this_awx.resources[0].spec.additional_labels)
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: Extract additional_labels from AWX Pod
|
||||
set_fact:
|
||||
pod_additional_labels: >-
|
||||
{{ awx_pod.resources[0].metadata.labels
|
||||
| dict2items | selectattr('key', 'in', this_awx.resources[0].spec.additional_labels)
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: AWX Pod contains additional_labels
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- pod_additional_labels == awx_additional_labels
|
||||
|
||||
- name: Extract Pod labels which shouldn't have been propagated to it from AWX
|
||||
set_fact:
|
||||
pod_extra_labels: >-
|
||||
{{ awx_pod.resources[0].metadata.labels
|
||||
| dict2items | selectattr('key', 'in', ["my/do-not-inherit"])
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: AWX Pod doesn't contain AWX labels not in additional_labels
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- pod_extra_labels == []
|
||||
rescue:
|
||||
- name: Re-emit failure
|
||||
vars:
|
||||
failed_task:
|
||||
result: '{{ ansible_failed_result }}'
|
||||
fail:
|
||||
msg: '{{ failed_task }}'
|
||||
|
||||
@@ -3,6 +3,10 @@ apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: example-awx
|
||||
labels:
|
||||
my/team: "foo"
|
||||
my/service: "bar"
|
||||
my/do-not-inherit: "yes"
|
||||
spec:
|
||||
{% if awx_image %}
|
||||
image: {{ awx_image }}
|
||||
@@ -26,6 +30,10 @@ spec:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 16M
|
||||
no_log: false
|
||||
postgres_resource_requirements: {}
|
||||
postgres_init_container_resource_requirements: {}
|
||||
redis_resource_requirements: {}
|
||||
additional_labels:
|
||||
- my/team
|
||||
- my/service
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
molecule
|
||||
molecule<4.0.2
|
||||
molecule-docker
|
||||
yamllint
|
||||
ansible-lint
|
||||
|
||||
31
playbooks/awx.yml
Normal file
31
playbooks/awx.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
gather_facts: no
|
||||
collections:
|
||||
- kubernetes.core
|
||||
- operator_sdk.util
|
||||
vars:
|
||||
no_log: true
|
||||
pre_tasks:
|
||||
- name: Verify imagePullSecrets
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: redhat-operators-pull-secret
|
||||
register: _rh_ops_secret
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Create imagePullSecret
|
||||
k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: redhat-operators-pull-secret
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
stringData:
|
||||
operator: awx
|
||||
when:
|
||||
- (_rh_ops_secret is not defined) or not (_rh_ops_secret['resources'] | length)
|
||||
roles:
|
||||
- installer
|
||||
@@ -3,4 +3,4 @@ collections:
|
||||
- name: kubernetes.core
|
||||
version: '>=2.3.2'
|
||||
- name: operator_sdk.util
|
||||
version: "0.2.0"
|
||||
version: "0.4.0"
|
||||
|
||||
@@ -93,6 +93,12 @@ backup_resource_requirements:
|
||||
memory: "32Mi"
|
||||
```
|
||||
|
||||
To customize the pg_dump command that will be executed on a backup use the `pg_dump_suffix` variable. This variable will append your provided pg_dump parameters to the end of the 'standard' command. For example to exclude the data from 'main_jobevent' and 'main_job' to decrease the size of the backup use:
|
||||
|
||||
```
|
||||
pg_dump_suffix: "--exclude-table-data 'main_jobevent*' --exclude-table-data 'main_job'"
|
||||
```
|
||||
|
||||
Testing
|
||||
----------------
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ backup_pvc_namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
backup_storage_requirements: ''
|
||||
|
||||
# Set no_log settings on certain tasks
|
||||
no_log: 'true'
|
||||
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
|
||||
@@ -31,6 +31,9 @@ backup_resource_requirements:
|
||||
# Allow additional parameters to be added to the pg_dump backup command
|
||||
pg_dump_suffix: ''
|
||||
|
||||
# Labels defined on the resource, which should be propagated to child resources
|
||||
additional_labels: []
|
||||
|
||||
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
set_self_labels: true
|
||||
...
|
||||
|
||||
@@ -24,7 +24,8 @@ galaxy_info:
|
||||
- backup
|
||||
- automation
|
||||
|
||||
dependencies: []
|
||||
dependencies:
|
||||
- role: common
|
||||
|
||||
collections:
|
||||
- kubernetes.core
|
||||
|
||||
@@ -25,10 +25,11 @@
|
||||
set_fact:
|
||||
awx_spec:
|
||||
spec: "{{ _awx }}"
|
||||
previous_deployment_name: "{{ this_awx['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Write awx object to pvc
|
||||
k8s_exec:
|
||||
k8s_cp:
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
bash -c 'echo "$0" > {{ backup_dir }}/awx_object' {{ awx_spec | to_yaml | quote }}
|
||||
remote_path: "{{ backup_dir }}/awx_object"
|
||||
content: "{{ awx_spec | to_yaml }}"
|
||||
|
||||
@@ -10,12 +10,7 @@
|
||||
metadata:
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
labels:
|
||||
app.kubernetes.io/name: "{{ ansible_operator_meta.name }}"
|
||||
app.kubernetes.io/part-of: "{{ ansible_operator_meta.name }}"
|
||||
app.kubernetes.io/managed-by: "{{ deployment_type }}-operator"
|
||||
app.kubernetes.io/component: "{{ deployment_type }}"
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
labels: '{{ lookup("template", "../common/templates/labels/common.yaml.j2") | from_yaml }}'
|
||||
when: set_self_labels | bool
|
||||
|
||||
- name: Look up details for this backup object
|
||||
@@ -26,6 +21,16 @@
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: this_backup
|
||||
|
||||
- name: Build `additional_labels_items` labels from `additional_labels`
|
||||
set_fact:
|
||||
additional_labels_items: >-
|
||||
{{ this_backup['resources'][0]['metadata']['labels']
|
||||
| dict2items | selectattr('key', 'in', additional_labels)
|
||||
}}
|
||||
when:
|
||||
- additional_labels | length
|
||||
- this_backup['resources'][0]['metadata']['labels']
|
||||
|
||||
- block:
|
||||
- include_tasks: init.yml
|
||||
|
||||
|
||||
24
roles/backup/tasks/dump_receptor_secrets.yml
Normal file
24
roles/backup/tasks/dump_receptor_secrets.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
|
||||
- name: Get secret
|
||||
k8s_info:
|
||||
version: v1
|
||||
kind: Secret
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: "{{ item }}"
|
||||
register: _secret
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Backup secret if exists
|
||||
block:
|
||||
- name: Set secret key
|
||||
set_fact:
|
||||
_data: "{{ _secret['resources'][0]['data'] }}"
|
||||
_type: "{{ _secret['resources'][0]['type'] }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create and Add secret names and data to dictionary
|
||||
set_fact:
|
||||
secret_dict: "{{ secret_dict | default({}) | combine({item: { 'name': item, 'data': _data, 'type': _type }}) }}"
|
||||
no_log: "{{ no_log }}"
|
||||
when: _secret | length
|
||||
@@ -75,7 +75,7 @@
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
bash -c "chmod 0600 {{ backup_dir }}/tower.db && chown postgres:root {{ backup_dir }}/tower.db"
|
||||
bash -c "chmod 660 {{ backup_dir }}/tower.db && chown :root {{ backup_dir }}/tower.db"
|
||||
|
||||
- name: Set full resolvable host name for postgres pod
|
||||
set_fact:
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
---
|
||||
|
||||
- name: Create Temporary secrets file
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: .json
|
||||
register: tmp_secrets
|
||||
|
||||
- name: Dump (generated) secret names from statuses and data into file
|
||||
include_tasks: dump_generated_secret.yml
|
||||
with_items:
|
||||
@@ -23,6 +17,12 @@
|
||||
- bundle_cacert_secret
|
||||
- ee_pull_credentials_secret
|
||||
|
||||
- name: Dump receptor secret names and data into file
|
||||
include_tasks: dump_receptor_secrets.yml
|
||||
loop:
|
||||
- '{{ deployment_name }}-receptor-ca'
|
||||
- '{{ deployment_name }}-receptor-work-signing'
|
||||
|
||||
# image_pull_secret is deprecated in favor of image_pull_secrets
|
||||
- name: Dump image_pull_secret into file
|
||||
include_tasks: dump_secret.yml
|
||||
@@ -42,9 +42,9 @@
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Write postgres configuration to pvc
|
||||
k8s_exec:
|
||||
k8s_cp:
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
bash -c "echo '{{ secrets | to_yaml }}' > {{ backup_dir }}/secrets.yml"
|
||||
remote_path: "{{ backup_dir }}/secrets.yml"
|
||||
content: "{{ secrets | to_yaml }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -6,11 +6,7 @@ metadata:
|
||||
namespace: {{ backup_pvc_namespace }}
|
||||
ownerReferences: null
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
|
||||
@@ -5,11 +5,7 @@ metadata:
|
||||
name: {{ ansible_operator_meta.name }}-db-management
|
||||
namespace: {{ backup_pvc_namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
spec:
|
||||
containers:
|
||||
- name: {{ ansible_operator_meta.name }}-db-management
|
||||
|
||||
8
roles/common/defaults/main.yml
Normal file
8
roles/common/defaults/main.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
deployment_type: awx
|
||||
kind: 'AWX'
|
||||
api_version: '{{ deployment_type }}.ansible.com/v1beta1'
|
||||
|
||||
# Used to determine some cluster specific logic regarding projects_persistence pvc permissions
|
||||
is_k8s: false
|
||||
is_openshift: false
|
||||
32
roles/common/meta/main.yml
Normal file
32
roles/common/meta/main.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: Ansible
|
||||
description: AWX role for AWX Operator for Kubernetes.
|
||||
company: Red Hat, Inc.
|
||||
|
||||
license: MIT
|
||||
|
||||
min_ansible_version: 2.8
|
||||
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- all
|
||||
- name: Debian
|
||||
versions:
|
||||
- all
|
||||
|
||||
galaxy_tags:
|
||||
- tower
|
||||
- awx
|
||||
- ansible
|
||||
- automation
|
||||
- ci
|
||||
- cd
|
||||
- deployment
|
||||
|
||||
dependencies: []
|
||||
|
||||
collections:
|
||||
- kubernetes.core
|
||||
- operator_sdk.util
|
||||
20
roles/common/tasks/main.yml
Normal file
20
roles/common/tasks/main.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
|
||||
- name: Get information about the cluster
|
||||
set_fact:
|
||||
api_groups: "{{ lookup('k8s', cluster_info='api_groups') }}"
|
||||
when:
|
||||
- not is_openshift | bool
|
||||
- not is_k8s | bool
|
||||
|
||||
- name: Determine the cluster type
|
||||
set_fact:
|
||||
is_openshift: "{{ True if 'route.openshift.io' in api_groups else False }}"
|
||||
is_k8s: "{{ False if 'route.openshift.io' in api_groups else True }}"
|
||||
when:
|
||||
- not is_openshift | bool
|
||||
- not is_k8s | bool
|
||||
|
||||
# Indicate what kind of cluster we are in (OpenShift or Kubernetes).
|
||||
- debug:
|
||||
msg: "CLUSTER TYPE: is_openshift={{ is_openshift }}; is_k8s={{ is_k8s }}"
|
||||
3
roles/common/templates/labels/additional_labels.yaml.j2
Normal file
3
roles/common/templates/labels/additional_labels.yaml.j2
Normal file
@@ -0,0 +1,3 @@
|
||||
{% for item in additional_labels_items | default([]) %}
|
||||
{{ item.key }}: '{{ item.value }}'
|
||||
{% endfor %}
|
||||
7
roles/common/templates/labels/common.yaml.j2
Normal file
7
roles/common/templates/labels/common.yaml.j2
Normal file
@@ -0,0 +1,7 @@
|
||||
# https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") }}
|
||||
1
roles/common/templates/labels/version.yaml.j2
Normal file
1
roles/common/templates/labels/version.yaml.j2
Normal file
@@ -0,0 +1 @@
|
||||
app.kubernetes.io/version: '{{ _image.split(':')[-1] | truncate(63, True, '', 0) }}'
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
deployment_type: awx
|
||||
kind: '{{ deployment_type | upper }}'
|
||||
kind: 'AWX'
|
||||
api_version: '{{ deployment_type }}.ansible.com/v1beta1'
|
||||
|
||||
database_name: "{{ deployment_type }}"
|
||||
@@ -9,8 +9,10 @@ database_username: "{{ deployment_type }}"
|
||||
task_privileged: false
|
||||
service_type: ClusterIP
|
||||
ingress_type: none
|
||||
ingress_class_name: ''
|
||||
ingress_path: '/'
|
||||
ingress_path_type: 'Prefix'
|
||||
ingress_api_version: 'networking.k8s.io/v1'
|
||||
# Add annotations to the service account. Specify as literal block. E.g.:
|
||||
# service_account_annotations: |
|
||||
# eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME>
|
||||
@@ -38,7 +40,9 @@ loadbalancer_protocol: 'http'
|
||||
loadbalancer_port: '80'
|
||||
service_annotations: ''
|
||||
|
||||
nodeport_port: '30080'
|
||||
# Port to be used for NodePort configuration, default is to auto-assign a port between 30000-32768
|
||||
#nodeport_port: '30080'
|
||||
|
||||
# The TLS termination mechanism to use to access
|
||||
# the services. Supported mechanism are: edge, passthrough
|
||||
#
|
||||
@@ -49,6 +53,10 @@ route_tls_termination_mechanism: edge
|
||||
#
|
||||
route_tls_secret: ''
|
||||
|
||||
# Route API Version to support older version
|
||||
# of the kubernetes services
|
||||
route_api_version: 'route.openshift.io/v1'
|
||||
|
||||
# Host to create the root with.
|
||||
# If not specific will default to <instance-name>-<namespace>-<routerCanonicalHostname>
|
||||
#
|
||||
@@ -75,6 +83,8 @@ node_selector: ''
|
||||
# app.kubernetes.io/name: "<resourcename>"
|
||||
topology_spread_constraints: ''
|
||||
|
||||
affinity: {}
|
||||
|
||||
# Add node tolerations for the AWX pods. Specify as literal block. E.g.:
|
||||
# tolerations: |
|
||||
# - key: "dedicated"
|
||||
@@ -130,8 +140,6 @@ _redis_image: docker.io/redis
|
||||
_redis_image_version: 7
|
||||
_postgres_image: postgres
|
||||
_postgres_image_version: 13
|
||||
_init_container_image: quay.io/centos/centos
|
||||
_init_container_image_version: stream8
|
||||
image_pull_policy: IfNotPresent
|
||||
image_pull_secrets: []
|
||||
|
||||
@@ -157,6 +165,11 @@ ee_images:
|
||||
|
||||
_control_plane_ee_image: quay.io/ansible/awx-ee:latest
|
||||
|
||||
_init_container_image: "{{ _control_plane_ee_image.split(':')[0] }}"
|
||||
_init_container_image_version: "{{ _control_plane_ee_image.split(':')[1] }}"
|
||||
|
||||
_init_projects_container_image: quay.io/centos/centos:stream9
|
||||
|
||||
create_preload_data: true
|
||||
|
||||
replicas: "1"
|
||||
@@ -286,11 +299,17 @@ development_mode: false
|
||||
security_context_settings: {}
|
||||
|
||||
# Set no_log settings on certain tasks
|
||||
no_log: 'true'
|
||||
no_log: true
|
||||
|
||||
# Should AWX instances be automatically upgraded when operator gets upgraded
|
||||
#
|
||||
auto_upgrade: true
|
||||
|
||||
# Labels defined on the resource, which should be propagated to child resources
|
||||
additional_labels: []
|
||||
|
||||
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
set_self_labels: true
|
||||
|
||||
# Disable web container's nginx ipv6 listener
|
||||
ipv6_disabled: false
|
||||
|
||||
@@ -25,7 +25,8 @@ galaxy_info:
|
||||
- cd
|
||||
- deployment
|
||||
|
||||
dependencies: []
|
||||
dependencies:
|
||||
- role: common
|
||||
|
||||
collections:
|
||||
- kubernetes.core
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
- '{{ _secret_key }}'
|
||||
- '{{ _postgres_configuration }}'
|
||||
- '{{ _broadcast_websocket_secret }}'
|
||||
- '{{ ansible_operator_meta.name }}-receptor-ca'
|
||||
- '{{ ansible_operator_meta.name }}-receptor-work-signing'
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
when: not garbage_collect_secrets | bool
|
||||
|
||||
@@ -18,10 +18,21 @@
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "echo \"from django.contrib.auth.models import User;
|
||||
User.objects.create_superuser('{{ admin_user }}', '{{ admin_email }}', '{{ admin_password }}')\"
|
||||
| awx-manage shell"
|
||||
command: awx-manage createsuperuser --username={{ admin_user | quote }} --email={{ admin_email | quote }} --noinput
|
||||
register: result
|
||||
changed_when: "'That username is already taken' not in result.stderr"
|
||||
failed_when: "'That username is already taken' not in result.stderr and 'Superuser created successfully' not in result.stdout"
|
||||
no_log: "{{ no_log }}"
|
||||
when: users_result.return_code > 0
|
||||
|
||||
- name: Update Django super user password
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: awx-manage update_password --username='{{ admin_user }}' --password='{{ admin_password }}'
|
||||
register: result
|
||||
changed_when: "'Password updated' in result.stdout"
|
||||
no_log: "{{ no_log }}"
|
||||
when: users_result.return_code > 0
|
||||
|
||||
|
||||
@@ -10,14 +10,29 @@
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
labels: '{{ lookup("template", "../common/templates/labels/common.yaml.j2") | from_yaml }}'
|
||||
when: set_self_labels | bool
|
||||
|
||||
- name: Build `additional_labels_items` labels from `additional_labels`
|
||||
block:
|
||||
- name: Look up details for this deployment
|
||||
k8s_info:
|
||||
api_version: "{{ api_version }}"
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: this_awx
|
||||
|
||||
- name: Select resource labels which are in `additional_labels`
|
||||
set_fact:
|
||||
additional_labels_items: >-
|
||||
{{ this_awx['resources'][0]['metadata']['labels']
|
||||
| dict2items | selectattr('key', 'in', additional_labels)
|
||||
| list
|
||||
}}
|
||||
when: this_awx['resources'][0]['metadata']['labels']
|
||||
when: additional_labels | length
|
||||
|
||||
- name: Include secret key configuration tasks
|
||||
include_tasks: secret_key_configuration.yml
|
||||
|
||||
|
||||
@@ -27,6 +27,139 @@
|
||||
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: Check for Receptor CA Secret
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-receptor-ca'
|
||||
register: _receptor_ca
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Migrate Receptor CA Secret
|
||||
when:
|
||||
- _receptor_ca['resources'] | default([]) | length
|
||||
- _receptor_ca['resources'][0]['type'] != "kubernetes.io/tls"
|
||||
block:
|
||||
- name: Delete old Receptor CA Secret
|
||||
k8s:
|
||||
state: absent
|
||||
kind: Secret
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-receptor-ca'
|
||||
- name: Create tempfile for receptor-ca.key
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: .key
|
||||
register: _receptor_ca_key_file
|
||||
- name: Copy Receptor CA key from old secret to tempfile
|
||||
copy:
|
||||
content: "{{ _receptor_ca['resources'][0]['data']['receptor-ca.key'] | b64decode }}"
|
||||
dest: "{{ _receptor_ca_key_file.path }}"
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Create tempfile for receptor-ca.crt
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: .crt
|
||||
register: _receptor_ca_crt_file
|
||||
- name: Copy Receptor CA cert from old secret to tempfile
|
||||
copy:
|
||||
content: "{{ _receptor_ca['resources'][0]['data']['receptor-ca.crt'] | b64decode }}"
|
||||
dest: "{{ _receptor_ca_crt_file.path }}"
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Create New Receptor CA secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}"
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Remove tempfiles
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "{{ _receptor_ca_key_file.path }}"
|
||||
- "{{ _receptor_ca_crt_file.path }}"
|
||||
|
||||
- name: Create Receptor Mesh CA
|
||||
block:
|
||||
- name: Create tempfile for receptor-ca.key
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: .key
|
||||
register: _receptor_ca_key_file
|
||||
- name: Generate Receptor CA key
|
||||
command: |
|
||||
openssl genrsa -out {{ _receptor_ca_key_file.path }} 4096
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Create tempfile for receptor-ca.crt
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: .crt
|
||||
register: _receptor_ca_crt_file
|
||||
- name: Generate Receptor CA cert
|
||||
command: |
|
||||
openssl req -x509 -new -nodes -key {{ _receptor_ca_key_file.path }} \
|
||||
-subj "/CN={{ ansible_operator_meta.name }} Receptor Root CA" \
|
||||
-sha256 -days 3650 -out {{ _receptor_ca_crt_file.path }}
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Create Receptor CA secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}"
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Remove tempfiles
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "{{ _receptor_ca_key_file.path }}"
|
||||
- "{{ _receptor_ca_crt_file.path }}"
|
||||
when: not _receptor_ca['resources'] | default([]) | length
|
||||
|
||||
- name: Check for Receptor work signing Secret
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
name: '{{ ansible_operator_meta.name }}-receptor-work-signing'
|
||||
register: _receptor_work_signing
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Generate Receptor work signing RSA key pair
|
||||
block:
|
||||
- name: Create tempfile for receptor work signing private key
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: .pem
|
||||
register: _receptor_work_signing_private_key_file
|
||||
- name: Generate Receptor work signing private key
|
||||
command: |
|
||||
openssl genrsa -out {{ _receptor_work_signing_private_key_file.path }} 4096
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Create tempfile for receptor work signing public key
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: .pem
|
||||
register: _receptor_work_signing_public_key_file
|
||||
- name: Generate Receptor work signing public key
|
||||
command: |
|
||||
openssl rsa \
|
||||
-in {{ _receptor_work_signing_private_key_file.path }} \
|
||||
-out {{ _receptor_work_signing_public_key_file.path }} \
|
||||
-outform PEM -pubout
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Create Receptor work signing Secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'secrets/receptor_work_signing_secret.yaml.j2') }}"
|
||||
no_log: "{{ no_log }}"
|
||||
- name: Remove tempfiles
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "{{ _receptor_work_signing_private_key_file.path }}"
|
||||
- "{{ _receptor_work_signing_public_key_file.path }}"
|
||||
when: not _receptor_work_signing['resources'] | default([]) | length
|
||||
|
||||
- name: Apply Resources
|
||||
k8s:
|
||||
apply: yes
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
command: |
|
||||
bash -c """
|
||||
set -e -o pipefail
|
||||
PGPASSWORD={{ awx_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ pg_restore }}
|
||||
PGPASSWORD='{{ awx_postgres_pass }}' {{ pgdump }} | PGPASSWORD='{{ awx_postgres_pass }}' {{ pg_restore }}
|
||||
echo 'Successful'
|
||||
"""
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -6,11 +6,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-{{ deployment_type }}-configmap'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
data:
|
||||
environment: |
|
||||
AWX_SKIP_MIGRATIONS=true
|
||||
@@ -46,8 +42,8 @@ data:
|
||||
{%- set cpu_limit = task_resource_requirements["limits"]["cpu"] if "limits" in task_resource_requirements and "cpu" in task_resource_requirements["limits"] -%}
|
||||
{%- if cpu_limit is defined -%}
|
||||
{%- set callback_receiver_cpu = cpu_limit | cpu_string_to_decimal -%}
|
||||
{%- if callback_receiver_cpu |int > 4 -%}
|
||||
# Set callback receiver workers based off cpu limit, default workers are 4, but if we have more than 4 cpu we can set higher value for workers
|
||||
{%- if callback_receiver_cpu |int > 4 %}
|
||||
# Set callback receiver workers based off cpu limit, default workers are 4, but if we have more than 4 cpu we can set higher value for workers
|
||||
JOB_EVENT_WORKERS = {{ callback_receiver_cpu }}
|
||||
{%- endif -%}
|
||||
{%- endif %}
|
||||
@@ -132,7 +128,9 @@ data:
|
||||
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
server {
|
||||
listen 8052 default_server;
|
||||
{% if not ipv6_disabled %}
|
||||
listen [::]:8052 default_server;
|
||||
{% endif %}
|
||||
server_name _;
|
||||
|
||||
# Redirect all HTTP links to the matching HTTPS page
|
||||
@@ -143,7 +141,9 @@ data:
|
||||
server {
|
||||
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
listen 8053 ssl;
|
||||
{% if not ipv6_disabled %}
|
||||
listen [::]:8053 ssl;
|
||||
{% endif %}
|
||||
|
||||
ssl_certificate /etc/nginx/pki/web.crt;
|
||||
ssl_certificate_key /etc/nginx/pki/web.key;
|
||||
@@ -154,7 +154,9 @@ data:
|
||||
ssl_prefer_server_ciphers on;
|
||||
{% else %}
|
||||
listen 8052 default_server;
|
||||
{% if not ipv6_disabled %}
|
||||
listen [::]:8052 default_server;
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# If you have a domain name, this is where to add it
|
||||
@@ -212,9 +214,7 @@ data:
|
||||
uwsgi_read_timeout 120s;
|
||||
uwsgi_pass uwsgi;
|
||||
include /etc/nginx/uwsgi_params;
|
||||
{%- if extra_nginx_include is defined %}
|
||||
include {{ extra_nginx_include }};
|
||||
{%- endif %}
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
proxy_set_header X-Forwarded-Port 443;
|
||||
uwsgi_param HTTP_X_FORWARDED_PORT 443;
|
||||
|
||||
@@ -236,30 +236,38 @@ data:
|
||||
receptor_conf: |
|
||||
---
|
||||
- log-level: debug
|
||||
|
||||
- local-only: null
|
||||
- node:
|
||||
firewallrules:
|
||||
- action: reject
|
||||
tonode: HOSTNAME
|
||||
toservice: control
|
||||
- control-service:
|
||||
service: control
|
||||
filename: /var/run/receptor/receptor.sock
|
||||
permissions: 0660
|
||||
|
||||
- local-only:
|
||||
|
||||
permissions: '0660'
|
||||
- work-command:
|
||||
worktype: local
|
||||
command: ansible-runner
|
||||
params: worker
|
||||
allowruntimeparams: true
|
||||
|
||||
- work-kubernetes:
|
||||
worktype: kubernetes-runtime-auth
|
||||
authmethod: runtime
|
||||
allowruntimeauth: true
|
||||
allowruntimepod: true
|
||||
allowruntimeparams: true
|
||||
|
||||
- work-kubernetes:
|
||||
worktype: kubernetes-incluster-auth
|
||||
authmethod: incluster
|
||||
allowruntimeauth: true
|
||||
allowruntimepod: true
|
||||
allowruntimeparams: true
|
||||
- tls-client:
|
||||
cert: /etc/receptor/tls/receptor.crt
|
||||
key: /etc/receptor/tls/receptor.key
|
||||
name: tlsclient
|
||||
rootcas: /etc/receptor/tls/ca/receptor-ca.crt
|
||||
- work-signing:
|
||||
privatekey: /etc/receptor/signing/work-private-key.pem
|
||||
tokenexpiration: 1m
|
||||
|
||||
@@ -6,12 +6,8 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
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 }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
{{ lookup("template", "../common/templates/labels/version.yaml.j2") | indent(width=4) | trim }}
|
||||
spec:
|
||||
replicas: {{ replicas }}
|
||||
selector:
|
||||
@@ -22,11 +18,8 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
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 }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=8) | trim }}
|
||||
{{ lookup("template", "../common/templates/labels/version.yaml.j2") | indent(width=8) | trim }}
|
||||
{% if annotations %}
|
||||
annotations:
|
||||
{{ annotations | indent(width=8) }}
|
||||
@@ -46,26 +39,40 @@ spec:
|
||||
priorityClassName: '{{ control_plane_priority_class }}'
|
||||
{% endif %}
|
||||
initContainers:
|
||||
{% if bundle_ca_crt or projects_persistence|bool or init_container_extra_commands %}
|
||||
- name: init
|
||||
image: '{{ _init_container_image }}'
|
||||
imagePullPolicy: '{{ image_pull_policy }}'
|
||||
resources: {{ task_resource_requirements }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
hostname=$MY_POD_NAME
|
||||
receptor --cert-makereq bits=2048 commonname=$hostname dnsname=$hostname nodeid=$hostname outreq=/etc/receptor/tls/receptor.req outkey=/etc/receptor/tls/receptor.key
|
||||
receptor --cert-signreq req=/etc/receptor/tls/receptor.req cacert=/etc/receptor/tls/ca/receptor-ca.crt cakey=/etc/receptor/tls/ca/receptor-ca.key outcert=/etc/receptor/tls/receptor.crt verify=yes
|
||||
{% if bundle_ca_crt %}
|
||||
mkdir -p /etc/pki/ca-trust/extracted/{java,pem,openssl,edk2}
|
||||
update-ca-trust
|
||||
{% endif %}
|
||||
{% if projects_persistence|bool %}
|
||||
chmod 775 /var/lib/awx/projects
|
||||
chgrp 1000 /var/lib/awx/projects
|
||||
{% endif %}
|
||||
{% if init_container_extra_commands %}
|
||||
{{ init_container_extra_commands | indent(width=14) }}
|
||||
{% endif %}
|
||||
env:
|
||||
- name: MY_POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
volumeMounts:
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
mountPath: "/etc/receptor/tls/ca/receptor-ca.crt"
|
||||
subPath: "tls.crt"
|
||||
readOnly: true
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
mountPath: "/etc/receptor/tls/ca/receptor-ca.key"
|
||||
subPath: "tls.key"
|
||||
readOnly: true
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-tls"
|
||||
mountPath: "/etc/receptor/tls/"
|
||||
{% if bundle_ca_crt %}
|
||||
- name: "ca-trust-extracted"
|
||||
mountPath: "/etc/pki/ca-trust/extracted"
|
||||
@@ -74,13 +81,27 @@ spec:
|
||||
subPath: bundle-ca.crt
|
||||
readOnly: true
|
||||
{% endif %}
|
||||
{% if projects_persistence|bool %}
|
||||
- name: "{{ ansible_operator_meta.name }}-projects"
|
||||
mountPath: "/var/lib/awx/projects"
|
||||
{% endif %}
|
||||
{% if init_container_extra_volume_mounts -%}
|
||||
{{ init_container_extra_volume_mounts | indent(width=12, first=True) }}
|
||||
{% endif %}
|
||||
{% if projects_persistence|bool and is_k8s|bool %}
|
||||
- name: init-projects
|
||||
image: '{{ _init_projects_container_image }}'
|
||||
imagePullPolicy: '{{ image_pull_policy }}'
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
chmod 775 /var/lib/awx/projects
|
||||
chgrp 1000 /var/lib/awx/projects
|
||||
env:
|
||||
- name: MY_POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
volumeMounts:
|
||||
- name: "{{ ansible_operator_meta.name }}-projects"
|
||||
mountPath: "/var/lib/awx/projects"
|
||||
{% endif %}
|
||||
containers:
|
||||
- image: '{{ _redis_image }}'
|
||||
@@ -170,6 +191,18 @@ spec:
|
||||
mountPath: "/var/lib/awx/rsyslog"
|
||||
- name: "{{ ansible_operator_meta.name }}-projects"
|
||||
mountPath: "/var/lib/awx/projects"
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-work-signing"
|
||||
mountPath: "/etc/receptor/signing/work-public-key.pem"
|
||||
subPath: "work-public-key.pem"
|
||||
readOnly: true
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
mountPath: "/etc/receptor/tls/ca/receptor-ca.crt"
|
||||
subPath: "tls.crt"
|
||||
readOnly: true
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
mountPath: "/etc/receptor/tls/ca/receptor-ca.key"
|
||||
subPath: "tls.key"
|
||||
readOnly: true
|
||||
{% if development_mode | bool %}
|
||||
- name: awx-devel
|
||||
mountPath: "/awx_devel"
|
||||
@@ -243,8 +276,10 @@ spec:
|
||||
- name: rsyslog-dir
|
||||
mountPath: "/var/lib/awx/rsyslog"
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-config"
|
||||
mountPath: "/etc/receptor/receptor.conf"
|
||||
subPath: receptor.conf
|
||||
mountPath: "/etc/receptor/"
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-work-signing"
|
||||
mountPath: "/etc/receptor/signing/work-private-key.pem"
|
||||
subPath: "work-private-key.pem"
|
||||
readOnly: true
|
||||
- name: receptor-socket
|
||||
mountPath: "/var/run/receptor"
|
||||
@@ -286,7 +321,15 @@ spec:
|
||||
name: '{{ ansible_operator_meta.name }}-ee'
|
||||
imagePullPolicy: '{{ image_pull_policy }}'
|
||||
resources: {{ ee_resource_requirements }}
|
||||
args: ['receptor', '--config', '/etc/receptor/receptor.conf']
|
||||
args:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
if [ ! -f /etc/receptor/receptor.conf ]; then
|
||||
cp /etc/receptor/receptor-default.conf /etc/receptor/receptor.conf
|
||||
sed -i "s/HOSTNAME/$HOSTNAME/g" /etc/receptor/receptor.conf
|
||||
fi
|
||||
exec receptor --config /etc/receptor/receptor.conf
|
||||
volumeMounts:
|
||||
{% if bundle_ca_crt %}
|
||||
- name: "ca-trust-extracted"
|
||||
@@ -296,10 +339,21 @@ spec:
|
||||
subPath: bundle-ca.crt
|
||||
readOnly: true
|
||||
{% endif %}
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-config"
|
||||
mountPath: "/etc/receptor/receptor.conf"
|
||||
- name: "{{ ansible_operator_meta.name }}-default-receptor-config"
|
||||
mountPath: "/etc/receptor/receptor-default.conf"
|
||||
subPath: receptor.conf
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-config"
|
||||
mountPath: "/etc/receptor/"
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
mountPath: "/etc/receptor/tls/ca/receptor-ca.crt"
|
||||
subPath: "tls.crt"
|
||||
readOnly: true
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-work-signing"
|
||||
mountPath: "/etc/receptor/signing/work-private-key.pem"
|
||||
subPath: "work-private-key.pem"
|
||||
readOnly: true
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-tls"
|
||||
mountPath: "/etc/receptor/tls/"
|
||||
- name: receptor-socket
|
||||
mountPath: "/var/run/receptor"
|
||||
- name: "{{ ansible_operator_meta.name }}-projects"
|
||||
@@ -325,13 +379,17 @@ spec:
|
||||
topologySpreadConstraints:
|
||||
{{ topology_spread_constraints | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if affinity | length %}
|
||||
affinity:
|
||||
{{ affinity | to_nice_yaml | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if tolerations %}
|
||||
tolerations:
|
||||
{{ tolerations | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if projects_persistence|bool or (security_context_settings|length) %}
|
||||
{% if (projects_persistence|bool and is_k8s|bool) or (security_context_settings|length) %}
|
||||
securityContext:
|
||||
{% if projects_persistence|bool %}
|
||||
{% if projects_persistence|bool and is_k8s|bool %}
|
||||
fsGroup: 1000
|
||||
{% endif %}
|
||||
{% if security_context_settings|length %}
|
||||
@@ -377,6 +435,14 @@ spec:
|
||||
path: 'ldap.py'
|
||||
- key: execution_environments.py
|
||||
path: 'execution_environments.py'
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-tls"
|
||||
emptyDir: {}
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
secret:
|
||||
secretName: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-work-signing"
|
||||
secret:
|
||||
secretName: "{{ ansible_operator_meta.name }}-receptor-work-signing"
|
||||
- name: "{{ secret_key_secret_name }}"
|
||||
secret:
|
||||
secretName: '{{ secret_key_secret_name }}'
|
||||
@@ -414,6 +480,8 @@ spec:
|
||||
- name: rsyslog-dir
|
||||
emptyDir: {}
|
||||
- name: {{ ansible_operator_meta.name }}-receptor-config
|
||||
emptyDir: {}
|
||||
- name: {{ ansible_operator_meta.name }}-default-receptor-config
|
||||
configMap:
|
||||
name: '{{ ansible_operator_meta.name }}-{{ deployment_type }}-configmap'
|
||||
items:
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
{% if ingress_type|lower == "ingress" %}
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{% if ingress_api_version is defined %}
|
||||
apiVersion: '{{ ingress_api_version }}'
|
||||
{% endif %}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-ingress'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
{% if ingress_annotations %}
|
||||
annotations:
|
||||
{{ ingress_annotations | indent(width=4) }}
|
||||
{% endif %}
|
||||
spec:
|
||||
{% if ingress_class_name %}
|
||||
ingressClassName: '{{ ingress_class_name }}'
|
||||
{% endif %}
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
@@ -39,17 +40,15 @@ spec:
|
||||
|
||||
{% if ingress_type|lower == "route" %}
|
||||
---
|
||||
apiVersion: route.openshift.io/v1
|
||||
{% if route_api_version is defined %}
|
||||
apiVersion: '{{ route_api_version }}'
|
||||
{% endif %}
|
||||
kind: Route
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
spec:
|
||||
{% if route_host != '' %}
|
||||
host: {{ route_host }}
|
||||
|
||||
@@ -5,11 +5,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-service'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
{{ service_labels | indent(width=4) }}
|
||||
{% if service_annotations %}
|
||||
annotations:
|
||||
@@ -23,7 +19,9 @@ spec:
|
||||
protocol: TCP
|
||||
targetPort: 8052
|
||||
name: http
|
||||
{% if nodeport_port is defined %}
|
||||
nodePort: {{ nodeport_port }}
|
||||
{% endif %}
|
||||
{% elif service_type | lower != 'loadbalancer' and loadbalancer_protocol | lower != 'https' %}
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
|
||||
@@ -5,11 +5,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
{% if service_account_annotations %}
|
||||
annotations:
|
||||
{{ service_account_annotations | indent(width=4) }}
|
||||
@@ -20,6 +16,8 @@ kind: Role
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
rules:
|
||||
- apiGroups: [""] # "" indicates the core API group
|
||||
resources: ["pods"]
|
||||
@@ -40,6 +38,8 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
|
||||
@@ -5,10 +5,6 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-admin-password'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
stringData:
|
||||
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
|
||||
@@ -6,11 +6,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-app-credentials'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
data:
|
||||
credentials.py: "{{ lookup('template', 'settings/credentials.py.j2') | b64encode }}"
|
||||
ldap.py: "{{ lookup('template', 'settings/ldap.py.j2') | b64encode }}"
|
||||
|
||||
@@ -5,10 +5,6 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-broadcast-websocket'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
stringData:
|
||||
secret: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
|
||||
@@ -6,11 +6,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-configuration'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
stringData:
|
||||
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
username: '{{ database_username }}'
|
||||
|
||||
@@ -6,11 +6,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-configuration'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
stringData:
|
||||
password: '{{ awx_postgres_pass }}'
|
||||
username: '{{ awx_postgres_user }}'
|
||||
|
||||
12
roles/installer/templates/secrets/receptor_ca_secret.yaml.j2
Normal file
12
roles/installer/templates/secrets/receptor_ca_secret.yaml.j2
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-receptor-ca'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
type: kubernetes.io/tls
|
||||
data:
|
||||
tls.crt: '{{ lookup('file', '{{ _receptor_ca_crt_file.path }}') | b64encode }}'
|
||||
tls.key: '{{ lookup('file', '{{ _receptor_ca_key_file.path }}') | b64encode }}'
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-receptor-work-signing'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
data:
|
||||
work-private-key.pem: '{{ lookup('file', '{{ _receptor_work_signing_private_key_file.path }}') | b64encode }}'
|
||||
work-public-key.pem: '{{ lookup('file', '{{ _receptor_work_signing_public_key_file.path }}') | b64encode }}'
|
||||
@@ -5,10 +5,6 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-secret-key'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
stringData:
|
||||
secret_key: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
|
||||
@@ -6,6 +6,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") | indent(width=4) | trim }}
|
||||
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
|
||||
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/component: 'database'
|
||||
@@ -27,6 +28,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") | indent(width=8) | trim }}
|
||||
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
|
||||
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/component: 'database'
|
||||
@@ -127,6 +129,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
{{ lookup("template", "../common/templates/labels/additional_labels.yaml.j2") | indent(width=4) | trim }}
|
||||
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
|
||||
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/component: 'database'
|
||||
|
||||
@@ -5,11 +5,7 @@ metadata:
|
||||
name: '{{ ansible_operator_meta.name }}-projects-claim'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ projects_storage_access_mode }}
|
||||
|
||||
@@ -17,6 +17,12 @@ This role assumes you are authenticated with an Openshift or Kubernetes cluster:
|
||||
- AWX is deployed to via the operator
|
||||
- An AWX backup is available on a PVC in your cluster (see the backup [README.md](../backup/README.md))
|
||||
|
||||
*Before Restoring from a backup*, be sure to:
|
||||
- delete the old existing AWX CR
|
||||
- delete the persistent volume claim (PVC) for the database from the old deployment, which has a name like `postgres-13-<deployment-name>-postgres-13-0`
|
||||
|
||||
**Note**: Do not delete the namespace/project, as that will delete the backup and the backup's PVC as well.
|
||||
|
||||
|
||||
Usage
|
||||
----------------
|
||||
|
||||
@@ -11,8 +11,11 @@ backup_pvc_namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
# Required: backup name, found on the awxbackup object
|
||||
backup_dir: ''
|
||||
|
||||
# Default cluster name
|
||||
cluster_name: 'cluster.local'
|
||||
|
||||
# Set no_log settings on certain tasks
|
||||
no_log: 'true'
|
||||
no_log: true
|
||||
|
||||
# Default resource requirements
|
||||
restore_resource_requirements:
|
||||
@@ -23,6 +26,9 @@ restore_resource_requirements:
|
||||
cpu: "25m"
|
||||
memory: "32Mi"
|
||||
|
||||
# Labels defined on the resource, which should be propagated to child resources
|
||||
additional_labels: []
|
||||
|
||||
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
set_self_labels: true
|
||||
...
|
||||
|
||||
@@ -24,7 +24,8 @@ galaxy_info:
|
||||
- restore
|
||||
- automation
|
||||
|
||||
dependencies: []
|
||||
dependencies:
|
||||
- role: common
|
||||
|
||||
collections:
|
||||
- kubernetes.core
|
||||
|
||||
@@ -1,27 +1,5 @@
|
||||
---
|
||||
|
||||
- name: Get AWX object definition from pvc
|
||||
k8s_exec:
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
bash -c "cat '{{ backup_dir }}/awx_object'"
|
||||
register: awx_object
|
||||
|
||||
- name: Create temp file for spec dict
|
||||
tempfile:
|
||||
state: file
|
||||
register: tmp_spec
|
||||
|
||||
- name: Write spec vars to temp file
|
||||
copy:
|
||||
content: "{{ awx_object.stdout }}"
|
||||
dest: "{{ tmp_spec.path }}"
|
||||
mode: '0644'
|
||||
|
||||
- name: Include spec vars to save them as a dict
|
||||
include_vars: "{{ tmp_spec.path }}"
|
||||
|
||||
- name: Deploy AWX
|
||||
k8s:
|
||||
state: "{{ state | default('present') }}"
|
||||
|
||||
25
roles/restore/tasks/import_vars.yml
Normal file
25
roles/restore/tasks/import_vars.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
|
||||
- name: Import awx_object variables
|
||||
block:
|
||||
- name: Get AWX object definition from pvc
|
||||
k8s_exec:
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
bash -c "cat '{{ backup_dir }}/awx_object'"
|
||||
register: awx_object
|
||||
|
||||
- name: Create temp file for spec dict
|
||||
tempfile:
|
||||
state: file
|
||||
register: tmp_spec
|
||||
|
||||
- name: Write spec vars to temp file
|
||||
copy:
|
||||
content: "{{ awx_object.stdout }}"
|
||||
dest: "{{ tmp_spec.path }}"
|
||||
mode: '0644'
|
||||
|
||||
- name: Include spec vars to save them as a dict
|
||||
include_vars: "{{ tmp_spec.path }}"
|
||||
@@ -10,12 +10,7 @@
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
labels: '{{ lookup("template", "../common/templates/labels/common.yaml.j2") | from_yaml }}'
|
||||
when: set_self_labels | bool
|
||||
|
||||
- name: Look up details for this restore object
|
||||
@@ -26,9 +21,21 @@
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: this_restore
|
||||
|
||||
- name: Build `additional_labels_items` labels from `additional_labels`
|
||||
set_fact:
|
||||
additional_labels_items: >-
|
||||
{{ this_restore['resources'][0]['metadata']['labels']
|
||||
| dict2items | selectattr('key', 'in', additional_labels)
|
||||
}}
|
||||
when:
|
||||
- additional_labels | length
|
||||
- this_restore['resources'][0]['metadata']['labels']
|
||||
|
||||
- block:
|
||||
- include_tasks: init.yml
|
||||
|
||||
- include_tasks: import_vars.yml
|
||||
|
||||
- include_tasks: secrets.yml
|
||||
|
||||
- include_tasks: deploy_awx.yml
|
||||
|
||||
@@ -66,7 +66,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"
|
||||
resolvable_db_host: "{{ awx_postgres_host }}.{{ ansible_operator_meta.namespace }}.svc.{{ cluster_name }}"
|
||||
no_log: "{{ no_log }}"
|
||||
when: awx_postgres_type == 'managed'
|
||||
|
||||
@@ -76,7 +76,6 @@
|
||||
pg_restore --clean --if-exists
|
||||
-U {{ awx_postgres_user }}
|
||||
-h {{ resolvable_db_host }}
|
||||
-U {{ awx_postgres_user }}
|
||||
-d {{ awx_postgres_database }}
|
||||
-p {{ awx_postgres_port }}
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
@@ -54,6 +54,37 @@
|
||||
no_log: "{{ no_log }}"
|
||||
when: secrets['postgresConfigurationSecret']['data']['type'] | b64decode == 'managed'
|
||||
|
||||
- name: Set new receptor secret names
|
||||
set_fact:
|
||||
previous_receptor_ca_name: "{{ previous_deployment_name }}-receptor-ca"
|
||||
previous_receptor_tls_name: "{{ previous_deployment_name }}-receptor-work-signing"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set new name for receptor secrets using deployment_name
|
||||
block:
|
||||
- name: Set new receptor secret names
|
||||
set_fact:
|
||||
receptor_ca_name: "{{ deployment_name }}-receptor-ca"
|
||||
receptor_work_signing_name: "{{ deployment_name }}-receptor-work-signing"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set tmp dict for receptor secrets
|
||||
set_fact:
|
||||
_ca_secret: "{{ secrets[previous_receptor_ca_name] }}"
|
||||
_work_signing_secret: "{{ secrets[previous_receptor_tls_name] }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Change receptor secret names in tmp dict
|
||||
set_fact:
|
||||
_ca_secret_name: "{{ _ca_secret | combine({ 'name': receptor_ca_name }) }}"
|
||||
_work_signing_secret_name: "{{ _work_signing_secret | combine({ 'name': receptor_work_signing_name}) }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Create a new dict of receptor secrets with updated names
|
||||
set_fact:
|
||||
secrets: "{{ secrets | combine({previous_receptor_ca_name: _ca_secret_name, previous_receptor_tls_name: _work_signing_secret_name}) }}"
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Apply secret
|
||||
k8s:
|
||||
state: present
|
||||
|
||||
@@ -5,11 +5,7 @@ metadata:
|
||||
name: {{ ansible_operator_meta.name }}-db-management
|
||||
namespace: {{ backup_pvc_namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
spec:
|
||||
containers:
|
||||
- name: {{ ansible_operator_meta.name }}-db-management
|
||||
|
||||
@@ -6,11 +6,7 @@ metadata:
|
||||
name: '{{ secrets[secret]['name'] }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/component: '{{ deployment_type }}'
|
||||
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
|
||||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }}
|
||||
type: '{{ secrets[secret]['type'] }}'
|
||||
stringData:
|
||||
{% for key, value in secrets[secret]['data'].items() %}
|
||||
|
||||
BIN
vendor/galaxy.ansible.com/kubernetes/core/kubernetes-core-1.1.1.tar.gz
generated
vendored
BIN
vendor/galaxy.ansible.com/kubernetes/core/kubernetes-core-1.1.1.tar.gz
generated
vendored
Binary file not shown.
BIN
vendor/galaxy.ansible.com/kubernetes/core/kubernetes-core-2.3.2.tar.gz
generated
vendored
Normal file
BIN
vendor/galaxy.ansible.com/kubernetes/core/kubernetes-core-2.3.2.tar.gz
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/galaxy.ansible.com/operator_sdk/util/operator_sdk-util-0.1.0.tar.gz
generated
vendored
BIN
vendor/galaxy.ansible.com/operator_sdk/util/operator_sdk-util-0.1.0.tar.gz
generated
vendored
Binary file not shown.
BIN
vendor/galaxy.ansible.com/operator_sdk/util/operator_sdk-util-0.4.0.tar.gz
generated
vendored
Normal file
BIN
vendor/galaxy.ansible.com/operator_sdk/util/operator_sdk-util-0.4.0.tar.gz
generated
vendored
Normal file
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
- version: v1beta1
|
||||
group: awx.ansible.com
|
||||
kind: AWX
|
||||
role: installer
|
||||
playbook: playbooks/awx.yml
|
||||
snakeCaseParameters: False
|
||||
|
||||
- version: v1beta1
|
||||
|
||||
Reference in New Issue
Block a user