mirror of
https://github.com/ansible/awx-operator.git
synced 2026-03-27 05:43:11 +00:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
630a5ee1f3 | ||
|
|
3d78e90ab1 | ||
|
|
3981e6ba5e | ||
|
|
ac682a9c05 | ||
|
|
7bdf48ffc0 | ||
|
|
fc11db4ece | ||
|
|
148309325e | ||
|
|
82756ebfe7 | ||
|
|
a9cee5f4da | ||
|
|
5f3d9ed96f | ||
|
|
1eb8501430 | ||
|
|
ecbb16960f | ||
|
|
368f786244 | ||
|
|
e4fe1ee214 | ||
|
|
0d1fa239a5 | ||
|
|
8a51fe9285 | ||
|
|
33c64d5695 | ||
|
|
a534c856db | ||
|
|
acda72558f | ||
|
|
9e2eb16b67 | ||
|
|
6b02c2c53b | ||
|
|
0ca3f1a7c4 | ||
|
|
69474557eb | ||
|
|
48e3a96305 | ||
|
|
da7e227f71 | ||
|
|
98d5ac126d | ||
|
|
cb5db01406 | ||
|
|
494384c1d7 | ||
|
|
34c2e48e0a | ||
|
|
122995fda7 | ||
|
|
9761c78fe9 | ||
|
|
062c7153c6 | ||
|
|
6ef4aed024 | ||
|
|
3fe42ed4b9 | ||
|
|
2ff1d35b6d | ||
|
|
d3934d9e08 | ||
|
|
3c8ce3718a | ||
|
|
66f03c3c16 | ||
|
|
7e2c2bf92c | ||
|
|
7b95f03a30 | ||
|
|
b0cb1cc07d | ||
|
|
5be4c13016 | ||
|
|
07427be0b7 | ||
|
|
c23bc68900 | ||
|
|
582701d949 | ||
|
|
b6b3b6c0ab | ||
|
|
25a6c3c48a | ||
|
|
c67289d2cf | ||
|
|
d0c7f343b2 | ||
|
|
ef17865f12 | ||
|
|
d5fd5d3819 | ||
|
|
a61ed18147 | ||
|
|
e3e3da0e0e | ||
|
|
1470779b8f | ||
|
|
400df47678 | ||
|
|
0f0ff32bf6 | ||
|
|
a9245454a4 | ||
|
|
bba8b8e2b5 | ||
|
|
93c5e4a0c3 | ||
|
|
06c0dd96d0 | ||
|
|
e6b11084db | ||
|
|
669fe1d253 | ||
|
|
e4cfa2f809 | ||
|
|
7251961bcc | ||
|
|
3a5fbb0b06 | ||
|
|
a69ca7f8b5 | ||
|
|
0fb252b6e4 | ||
|
|
718e5cfcb9 | ||
|
|
a8153d5ffb | ||
|
|
7b0a68c2f4 | ||
|
|
1c89044be4 | ||
|
|
15ed13dd8d | ||
|
|
f2ad70678c | ||
|
|
2ec77f1e7e | ||
|
|
aa7d0b9918 | ||
|
|
38209f9720 | ||
|
|
0ba4feaf7a | ||
|
|
d4c1fda066 | ||
|
|
0d97183bbf | ||
|
|
293f0158e0 | ||
|
|
bb30b3b9fe | ||
|
|
39bebe64ba | ||
|
|
5bd84b3d3e | ||
|
|
76e315d191 | ||
|
|
dd022258b5 | ||
|
|
019fa3d356 | ||
|
|
4a968aa605 | ||
|
|
92639c1e89 | ||
|
|
a7cfbe23da | ||
|
|
16a2b590d6 | ||
|
|
8518e0d1c7 | ||
|
|
6bc101af3e |
35
.github/workflows/devel.yaml
vendored
35
.github/workflows/devel.yaml
vendored
@@ -13,15 +13,36 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build Image
|
||||
- name: Fail if QUAY_REGISTRY not set
|
||||
run: |
|
||||
IMG=awx-operator:devel make docker-build
|
||||
if [[ -z "${{ vars.QUAY_REGISTRY }}" ]]; then
|
||||
echo "QUAY_REGISTRY not set. Please set QUAY_REGISTRY in variable GitHub Actions variables."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Push To Quay
|
||||
uses: redhat-actions/push-to-registry@v2.1.1
|
||||
- name: Log into registry ghcr.io
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
image: awx-operator
|
||||
tags: devel
|
||||
registry: quay.io/ansible/
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Log into registry quay.io
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ${{ vars.QUAY_REGISTRY }}
|
||||
username: ${{ secrets.QUAY_USER }}
|
||||
password: ${{ secrets.QUAY_TOKEN }}
|
||||
|
||||
|
||||
- name: Build and Store Image @ghcr
|
||||
run: |
|
||||
IMG=ghcr.io/${{ github.repository }}:${{ github.sha }} make docker-buildx
|
||||
|
||||
|
||||
- name: Publish Image to quay.io
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
ghcr.io/${{ github.repository }}:${{ github.sha }} \
|
||||
--tag ${{ vars.QUAY_REGISTRY }}/awx-operator:devel
|
||||
|
||||
19
.github/workflows/feature.yml
vendored
19
.github/workflows/feature.yml
vendored
@@ -29,25 +29,6 @@ jobs:
|
||||
run: |
|
||||
echo "IMAGE_TAG_BASE=ghcr.io/${OWNER_LC}/awx-operator" >>${GITHUB_ENV}
|
||||
|
||||
- name: Set ARCH environment variable
|
||||
run: |
|
||||
echo "ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)" >>${GITHUB_ENV}
|
||||
|
||||
- name: Set OS environment variable
|
||||
run: |
|
||||
echo "OS=$(uname | awk '{print tolower($0)}')" >>${GITHUB_ENV}
|
||||
|
||||
- name: Install operator-sdk
|
||||
run: |
|
||||
echo "Installing operator-sdk ${OPERATOR_SDK_DL_URL}" && \
|
||||
curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH} && \
|
||||
chmod +x operator-sdk_${OS}_${ARCH} && \
|
||||
sudo mkdir -p /usr/local/bin/ && \
|
||||
sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk && \
|
||||
operator-sdk version
|
||||
env:
|
||||
OPERATOR_SDK_DL_URL: https://github.com/operator-framework/operator-sdk/releases/download/v1.26.0
|
||||
|
||||
- name: Log in to registry
|
||||
run: |
|
||||
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
72
.github/workflows/promote.yaml
vendored
72
.github/workflows/promote.yaml
vendored
@@ -3,37 +3,81 @@ name: Promote AWX Operator image
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: 'Name for the tag of the release.'
|
||||
required: true
|
||||
quay_registry:
|
||||
description: 'Quay registry to push to.'
|
||||
default: 'quay.io/ansible'
|
||||
|
||||
env:
|
||||
QUAY_REGISTRY: ${{ vars.QUAY_REGISTRY }}
|
||||
|
||||
jobs:
|
||||
promote:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set GitHub Env vars for workflow_dispatch event
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV
|
||||
echo "QUAY_REGISTRY=${{ github.event.inputs.quay_registry }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set GitHub Env vars if release event
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
run: |
|
||||
echo "TAG_NAME=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Fail if QUAY_REGISTRY not set
|
||||
run: |
|
||||
if [[ -z "${{ env.QUAY_REGISTRY }}" ]]; then
|
||||
echo "QUAY_REGISTRY not set. Please set QUAY_REGISTRY in variable GitHub Actions variables."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
depth: 0
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: |
|
||||
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
- name: Log in to Quay
|
||||
run: |
|
||||
echo ${{ secrets.QUAY_TOKEN }} | docker login quay.io -u ${{ secrets.QUAY_USER }} --password-stdin
|
||||
- name: Log into registry ghcr.io
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Re-tag and promote awx-operator image
|
||||
|
||||
- name: Log into registry quay.io
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ${{ env.QUAY_REGISTRY }}
|
||||
username: ${{ secrets.QUAY_USER }}
|
||||
password: ${{ secrets.QUAY_TOKEN }}
|
||||
|
||||
|
||||
- name: Pull Tagged Staged Image and Publish to quay.io
|
||||
run: |
|
||||
docker pull ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }}
|
||||
docker tag ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }} quay.io/${{ github.repository }}:${{ github.event.release.tag_name }}
|
||||
docker tag ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }} quay.io/${{ github.repository }}:latest
|
||||
docker push quay.io/${{ github.repository }}:${{ github.event.release.tag_name }}
|
||||
docker push quay.io/${{ github.repository }}:latest
|
||||
docker buildx imagetools create \
|
||||
ghcr.io/${{ github.repository }}:${{ env.TAG_NAME }} \
|
||||
--tag ${{ env.QUAY_REGISTRY }}/awx-operator:${{ env.TAG_NAME }}
|
||||
|
||||
|
||||
- name: Pull Staged Image and Publish to quay.io/${{ github.repository }}:latest
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
ghcr.io/${{ github.repository }}:${{ env.TAG_NAME }} \
|
||||
--tag ${{ env.QUAY_REGISTRY }}/awx-operator:latest
|
||||
|
||||
|
||||
- name: Release Helm chart
|
||||
run: |
|
||||
ansible-playbook ansible/helm-release.yml -v \
|
||||
-e operator_image=quay.io/${{ github.repository }} \
|
||||
-e operator_image=${{ env.QUAY_REGISTRY }}/awx-operator \
|
||||
-e chart_owner=${{ github.repository_owner }} \
|
||||
-e tag=${{ github.event.release.tag_name }} \
|
||||
-e tag=${{ env.TAG_NAME }} \
|
||||
-e gh_token=${{ secrets.GITHUB_TOKEN }} \
|
||||
-e gh_user=${{ github.actor }} \
|
||||
-e repo_type=https
|
||||
|
||||
86
.github/workflows/publish-operator-hub.yaml
vendored
Normal file
86
.github/workflows/publish-operator-hub.yaml
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
name: Publish AWX Operator on operator-hub
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: 'Name for the tag of the release.'
|
||||
required: true
|
||||
operator_hub_fork:
|
||||
description: 'Fork of operator-hub where the PR will be created from. default: awx-auto'
|
||||
required: true
|
||||
default: 'awx-auto'
|
||||
image_registry:
|
||||
description: 'Image registry where the image is published to. default: quay.io'
|
||||
required: true
|
||||
default: 'quay.io'
|
||||
image_registry_organization:
|
||||
description: 'Image registry organization where the image is published to. default: ansible'
|
||||
required: true
|
||||
default: 'ansible'
|
||||
community_operator_github_org:
|
||||
description: 'Github organization for community-opeartor project. default: k8s-operatorhub'
|
||||
required: true
|
||||
default: 'k8s-operatorhub'
|
||||
community_operator_prod_github_org:
|
||||
description: 'GitHub organization for community-operator-prod project. default: redhat-openshift-ecosystem'
|
||||
required: true
|
||||
default: 'redhat-openshift-ecosystem'
|
||||
jobs:
|
||||
promote:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set GITHUB_ENV from workflow_dispatch event
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
echo "VERSION=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV
|
||||
echo "IMAGE_REGISTRY=${{ github.event.inputs.image_registry }}" >> $GITHUB_ENV
|
||||
echo "IMAGE_REGISTRY_ORGANIZATION=${{ github.event.inputs.image_registry_organization }}" >> $GITHUB_ENV
|
||||
echo "COMMUNITY_OPERATOR_GITHUB_ORG=${{ github.event.inputs.community_operator_github_org }}" >> $GITHUB_ENV
|
||||
echo "COMMUNITY_OPERATOR_PROD_GITHUB_ORG=${{ github.event.inputs.community_operator_prod_github_org }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set GITHUB_ENV for release event
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
run: |
|
||||
echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
|
||||
echo "IMAGE_REGISTRY=quay.io" >> $GITHUB_ENV
|
||||
echo "IMAGE_REGISTRY_ORGANIZATION=ansible" >> $GITHUB_ENV
|
||||
echo "COMMUNITY_OPERATOR_GITHUB_ORG=k8s-operatorhub" >> $GITHUB_ENV
|
||||
echo "COMMUNITY_OPERATOR_PROD_GITHUB_ORG=redhat-openshift-ecosystem" >> $GITHUB_ENV
|
||||
|
||||
- name: Log in to image registry
|
||||
run: |
|
||||
echo ${{ secrets.QUAY_TOKEN }} | docker login ${{ env.IMAGE_REGISTRY }} -u ${{ secrets.QUAY_USER }} --password-stdin
|
||||
|
||||
- name: Checkout awx-operator at workflow branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: awx-operator
|
||||
|
||||
- name: Checkout awx-opearator at ${{ env.VERSION }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-tags: true
|
||||
ref: ${{ env.VERSION }}
|
||||
path: awx-operator-${{ env.VERSION }}
|
||||
fetch-depth: 0 # fetch all history so that git describe works
|
||||
|
||||
- name: Copy scripts to awx-operator-${{ env.VERSION }}
|
||||
run: |
|
||||
cp -f \
|
||||
awx-operator/hack/publish-to-operator-hub.sh \
|
||||
awx-operator-${{ env.VERSION }}/hack/publish-to-operator-hub.sh
|
||||
cp -f \
|
||||
awx-operator/Makefile \
|
||||
awx-operator-${{ env.VERSION }}/Makefile
|
||||
|
||||
- name: Build and publish bundle to operator-hub
|
||||
working-directory: awx-operator-${{ env.VERSION }}
|
||||
env:
|
||||
IMG_REPOSITORY: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_REGISTRY_ORGANIZATION }}
|
||||
GITHUB_TOKEN: ${{ secrets.AWX_AUTO_GITHUB_TOKEN }}
|
||||
run: |
|
||||
git config --global user.email "awx-automation@redhat.com"
|
||||
git config --global user.name "AWX Automation"
|
||||
./hack/publish-to-operator-hub.sh
|
||||
39
.github/workflows/stage.yml
vendored
39
.github/workflows/stage.yml
vendored
@@ -37,12 +37,6 @@ jobs:
|
||||
|
||||
exit 0
|
||||
|
||||
- name: Checkout awx
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ${{ github.repository_owner }}/awx
|
||||
path: awx
|
||||
|
||||
- name: Checkout awx-operator
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -53,17 +47,20 @@ jobs:
|
||||
run: |
|
||||
python3 -m pip install docker
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: |
|
||||
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
- name: Log into registry ghcr.io
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and stage awx-operator
|
||||
- name: Stage awx-operator
|
||||
working-directory: awx-operator
|
||||
run: |
|
||||
BUILD_ARGS="--build-arg DEFAULT_AWX_VERSION=${{ github.event.inputs.default_awx_version }} \
|
||||
--build-arg OPERATOR_VERSION=${{ github.event.inputs.version }}" \
|
||||
IMAGE_TAG_BASE=ghcr.io/${{ github.repository_owner }}/awx-operator \
|
||||
VERSION=${{ github.event.inputs.version }} make docker-build docker-push
|
||||
--build-arg OPERATOR_VERSION=${{ github.event.inputs.version }}" \
|
||||
IMG=ghcr.io/${{ github.repository }}:${{ github.event.inputs.version }} \
|
||||
make docker-buildx
|
||||
|
||||
- name: Run test deployment
|
||||
working-directory: awx-operator
|
||||
@@ -76,10 +73,12 @@ jobs:
|
||||
env:
|
||||
AWX_TEST_VERSION: ${{ github.event.inputs.default_awx_version }}
|
||||
|
||||
- name: Create draft release
|
||||
working-directory: awx
|
||||
run: |
|
||||
ansible-playbook tools/ansible/stage.yml \
|
||||
-e version=${{ github.event.inputs.version }} \
|
||||
-e repo=${{ github.repository_owner }}/awx-operator \
|
||||
-e github_token=${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create Draft Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.event.inputs.version }}
|
||||
release_name: Release ${{ github.event.inputs.version }}
|
||||
draft: true
|
||||
|
||||
@@ -8,10 +8,12 @@ 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://ansible.readthedocs.io/projects/awx-operator/en/latest/installation/helm-install-on-existing-cluster.html) guide provides key installation instructions.
|
||||
|
||||
Example:
|
||||
```
|
||||
|
||||
```bash
|
||||
helm install my-awx-operator awx-operator/awx-operator -n awx --create-namespace -f myvalues.yaml
|
||||
```
|
||||
|
||||
@@ -24,6 +26,39 @@ Argument breakdown:
|
||||
|
||||
To update an existing installation, use `helm upgrade` instead of `install`. The rest of the syntax remains the same.
|
||||
|
||||
### Caveats on upgrading existing installation
|
||||
|
||||
There is no support at this time for upgrading or deleting CRDs using Helm. See [helm documentation](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations) for additional detail.
|
||||
|
||||
When upgrading to releases with CRD changes use the following command to update the CRDs
|
||||
|
||||
```bash
|
||||
kubectl apply --server-side -k github.com/ansible/awx-operator/config/crd?ref=<VERSION>
|
||||
```
|
||||
|
||||
If running above command results in an error like below:
|
||||
|
||||
```text
|
||||
Apply failed with 1 conflict: conflict with "helm" using apiextensions.k8s.io/v1: .spec.versions
|
||||
Please review the fields above--they currently have other managers. Here
|
||||
are the ways you can resolve this warning:
|
||||
* If you intend to manage all of these fields, please re-run the apply
|
||||
command with the `--force-conflicts` flag.
|
||||
* If you do not intend to manage all of the fields, please edit your
|
||||
manifest to remove references to the fields that should keep their
|
||||
current managers.
|
||||
* You may co-own fields by updating your manifest to match the existing
|
||||
value; in this case, you'll become the manager if the other manager(s)
|
||||
stop managing the field (remove it from their configuration).
|
||||
See https://kubernetes.io/docs/reference/using-api/server-side-apply/#conflicts
|
||||
```
|
||||
|
||||
Use `--force-conflicts` flag to resolve the conflict.
|
||||
|
||||
```bash
|
||||
kubectl apply --server-side --force-conflicts -k github.com/ansible/awx-operator/config/crd?ref=<VERSION>
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -32,6 +67,158 @@ These sub-headers aim to be a more intuitive entrypoint into customizing your de
|
||||
### 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`. Supplying the password this way is not recommended for production use, but may be helpful for initial PoC.
|
||||
|
||||
### Additional Kubernetes Resources
|
||||
The `AWX.extraDeploy` section allows the creation of additional Kubernetes resources. This simplifies setups requiring additional objects that are used by AWX, e.g. using `ExternalSecrets` to create Kubernetes secrets.
|
||||
|
||||
Resources are passed as an array, either as YAML or strings (literal "|"). The resources are passed through `tpl`, so templating is possible. Example:
|
||||
|
||||
```yaml
|
||||
AWX:
|
||||
# enable use of awx-deploy template
|
||||
...
|
||||
|
||||
# configurations for external postgres instance
|
||||
postgres:
|
||||
enabled: false
|
||||
...
|
||||
|
||||
extraDeploy:
|
||||
- |
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-postgres-secret-string-example
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: {{ .Release.Name }}
|
||||
spec:
|
||||
secretStoreRef:
|
||||
name: vault
|
||||
kind: ClusterSecretStore
|
||||
refreshInterval: "1h"
|
||||
target:
|
||||
name: postgres-configuration-secret-string-example
|
||||
creationPolicy: "Owner"
|
||||
deletionPolicy: "Delete"
|
||||
dataFrom:
|
||||
- extract:
|
||||
key: awx/postgres-configuration-secret
|
||||
|
||||
- apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-postgres-secret-yaml-example"
|
||||
namespace: "{{ .Release.Namespace }}"
|
||||
labels:
|
||||
app: "{{ .Release.Name }}"
|
||||
spec:
|
||||
secretStoreRef:
|
||||
name: vault
|
||||
kind: ClusterSecretStore
|
||||
refreshInterval: "1h"
|
||||
target:
|
||||
name: postgres-configuration-secret-yaml-example
|
||||
creationPolicy: "Owner"
|
||||
deletionPolicy: "Delete"
|
||||
dataFrom:
|
||||
- extract:
|
||||
key: awx/postgres-configuration-secret
|
||||
```
|
||||
|
||||
### Custom secrets
|
||||
The `customSecrets` section simplifies the creation of our custom secrets used during AWX deployment. Supplying the passwords this way is not recommended for production use, but may be helpful for initial PoC.
|
||||
|
||||
If enabled, the configs provided will automatically used to create the respective secrets and linked at the CR spec level. For proper secret management, the sensitive values can be passed in at the command line rather than specified in code. Use the `--set` argument with `helm install`.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
AWX:
|
||||
# enable use of awx-deploy template
|
||||
...
|
||||
|
||||
# configurations for external postgres instance
|
||||
postgres:
|
||||
enabled: false
|
||||
...
|
||||
|
||||
customSecrets:
|
||||
enabled: true
|
||||
admin:
|
||||
enabled: true
|
||||
password: mysuperlongpassword
|
||||
secretName: my-admin-password
|
||||
secretKey:
|
||||
enabled: true
|
||||
key: supersecuresecretkey
|
||||
secretName: my-awx-secret-key
|
||||
ingressTls:
|
||||
enabled: true
|
||||
selfSignedCert: true
|
||||
key: unset
|
||||
certificate: unset
|
||||
routeTls:
|
||||
enabled: false
|
||||
key: <contentoftheprivatekey>
|
||||
certificate: <contentofthepublickey>
|
||||
ldapCacert:
|
||||
enabled: false
|
||||
crt: <contentofmybundlecacrt>
|
||||
ldap:
|
||||
enabled: true
|
||||
password: yourldapdnpassword
|
||||
bundleCacert:
|
||||
enabled: false
|
||||
crt: <contentofmybundlecacrt>
|
||||
eePullCredentials:
|
||||
enabled: false
|
||||
url: unset
|
||||
username: unset
|
||||
password: unset
|
||||
sslVerify: true
|
||||
secretName: my-ee-pull-credentials
|
||||
cpPullCredentials:
|
||||
enabled: false
|
||||
dockerconfig:
|
||||
- registry: https://index.docker.io/v1/
|
||||
username: unset
|
||||
password: unset
|
||||
secretName: my-cp-pull-credentials
|
||||
```
|
||||
|
||||
### Custom volumes
|
||||
The `customVolumes` section simplifies the creation of Persistent Volumes used when you want to store your databases and projects files on the cluster's Node. Since their backends are `hostPath`, the size specified are just like a label and there is no actual capacity limitation.
|
||||
|
||||
You have to prepare directories for these volumes. For example:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /data/postgres-13
|
||||
sudo mkdir -p /data/projects
|
||||
sudo chmod 755 /data/postgres-13
|
||||
sudo chown 1000:0 /data/projects
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
AWX:
|
||||
# enable use of awx-deploy template
|
||||
...
|
||||
|
||||
# configurations for external postgres instance
|
||||
postgres:
|
||||
enabled: false
|
||||
...
|
||||
|
||||
customVolumes:
|
||||
postgres:
|
||||
enabled: true
|
||||
hostPath: /data/postgres-13
|
||||
projects:
|
||||
enabled: true
|
||||
hostPath: /data/projects
|
||||
size: 1Gi
|
||||
```
|
||||
|
||||
## Values Summary
|
||||
|
||||
@@ -43,6 +230,120 @@ The `AWX.postgres` section simplifies the creation of the external postgres secr
|
||||
| `AWX.spec` | specs to directly configure the AWX resource | `{}` |
|
||||
| `AWX.postgres` | configurations for the external postgres secret | - |
|
||||
|
||||
### extraDeploy
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `extraDeploy` | array of additional resources to be deployed (supports YAML or literal "\|") | - |
|
||||
|
||||
### customSecrets
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.enabled` | Enable the secret resources configuration | `false` |
|
||||
| `customSecrets.admin` | Configurations for the secret that contains the admin user password | - |
|
||||
| `customSecrets.secretKey` | Configurations for the secret that contains the symmetric key for encryption | - |
|
||||
| `customSecrets.ingressTls` | Configurations for the secret that contains the TLS information when `ingress_type=ingress` | - |
|
||||
| `customSecrets.routeTls` | Configurations for the secret that contains the TLS information when `ingress_type=route` (`route_tls_secret`) | - |
|
||||
| `customSecrets.ldapCacert` | Configurations for the secret that contains the LDAP Certificate Authority | - |
|
||||
| `customSecrets.ldap` | Configurations for the secret that contains the LDAP BIND DN password | - |
|
||||
| `customSecrets.bundleCacert` | Configurations for the secret that contains the Certificate Authority | - |
|
||||
| `customSecrets.eePullCredentials` | Configurations for the secret that contains the pull credentials for registered ees can be found | - |
|
||||
| `customSecrets.cpPullCredentials` | Configurations for the secret that contains the image pull credentials for app and database containers | - |
|
||||
|
||||
|
||||
Below the addition variables to customize the secret configuration.
|
||||
|
||||
#### Admin user password secret configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.admin.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.admin.password` | Admin user password | - |
|
||||
| `customSecrets.admin.secretName` | Name of secret for `admin_password_secret` | `<resourcename>-admin-password>` |
|
||||
|
||||
#### Secret Key secret configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.secretKey.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.secretKey.key` | Key is used to encrypt sensitive data in the database | - |
|
||||
| `customSecrets.secretKey.secretName` | Name of secret for `secret_key_secret` | `<resourcename>-secret-key` |
|
||||
|
||||
#### Ingress TLS secret configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.ingressTls.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.ingressTls.selfSignedCert` | If `true`, an self-signed TLS certificate for `AWX.spec.hostname` will be create by helm | `false` |
|
||||
| `customSecrets.ingressTls.key` | Private key to use for TLS/SSL | - |
|
||||
| `customSecrets.ingressTls.certificate` | Certificate to use for TLS/SSL | - |
|
||||
| `customSecrets.ingressTls.secretName` | Name of secret for `ingress_tls_secret` | `<resourcename>-ingress-tls` |
|
||||
| `customSecrets.ingressTls.labels` | Array of labels for the secret | - |
|
||||
|
||||
#### Route TLS secret configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.routeTls.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.routeTls.key` | Private key to use for TLS/SSL | - |
|
||||
| `customSecrets.routeTls.certificate` | Certificate to use for TLS/SSL | - |
|
||||
| `customSecrets.routeTls.secretName` | Name of secret for `route_tls_secret` | `<resourcename>-route-tls` |
|
||||
|
||||
#### LDAP Certificate Authority secret configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.ldapCacert.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.ldapCacert.crt` | Bundle of CA Root Certificates | - |
|
||||
| `customSecrets.ldapCacert.secretName` | Name of secret for `ldap_cacert_secret` | `<resourcename>-custom-certs` |
|
||||
|
||||
#### LDAP BIND DN Password secret configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.ldap.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.ldap.password` | LDAP BIND DN password | - |
|
||||
| `customSecrets.ldap.secretName` | Name of secret for `ldap_password_secret` | `<resourcename>-ldap-password` |
|
||||
|
||||
#### Certificate Authority secret configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.bundleCacert.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.bundleCacert.crt` | Bundle of CA Root Certificates | - |
|
||||
| `customSecrets.bundleCacert.secretName` | Name of secret for `bundle_cacert_secret` | `<resourcename>-custom-certs` |
|
||||
|
||||
#### Default EE pull secrets configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.eePullCredentials.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.eePullCredentials.url` | Registry url | - |
|
||||
| `customSecrets.eePullCredentials.username` | Username to connect as | - |
|
||||
| `customSecrets.eePullCredentials.password` | Password to connect with | - |
|
||||
| `customSecrets.eePullCredentials.sslVerify` | Whether verify ssl connection or not. | `true` |
|
||||
| `customSecrets.eePullCredentials.secretName` | Name of secret for `ee_pull_credentials_secret` | `<resourcename>-ee-pull-credentials` |
|
||||
|
||||
#### Control Plane pull secrets configuration
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customSecrets.cpPullCredentials.enabled` | If `true`, secret will be created | `false` |
|
||||
| `customSecrets.cpPullCredentials.dockerconfig` | Array of configurations for the Docker credentials that are used for accessing a registry | - |
|
||||
| `customSecrets.cpPullCredentials.dockerconfig[].registry` | Server location for Docker registry | `https://index.docker.io/v1/` |
|
||||
| `customSecrets.cpPullCredentials.dockerconfig[].username` | Username to connect as | - |
|
||||
| `customSecrets.cpPullCredentials.dockerconfig[].password` | Password to connect with | - |
|
||||
| `customSecrets.cpPullCredentials.secretName` | Name of secret for `image_pull_secrets`| `<resoucename>-cp-pull-credentials` |
|
||||
|
||||
### customVolumes
|
||||
|
||||
#### Persistent Volume for databases postgres
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customVolumes.postgres.enabled` | Enable the PV resource configuration for the postgres databases | `false` |
|
||||
| `customVolumes.postgres.hostPath` | Directory location on host | - |
|
||||
| `customVolumes.postgres.size` | Size of the volume | `8Gi` |
|
||||
| `customVolumes.postgres.accessModes` | Volume access mode | `ReadWriteOnce` |
|
||||
| `customVolumes.postgres.storageClassName` | PersistentVolume storage class name for `postgres_storage_class` | `<resourcename>-postgres-volume` |
|
||||
|
||||
#### Persistent Volume for projects files
|
||||
| Value | Description | Default |
|
||||
|---|---|---|
|
||||
| `customVolumes.projects.enabled` | Enable the PVC and PVC resources configuration for the projects files | `false` |
|
||||
| `customVolumes.projects.hostPath` | Directory location on host | - |
|
||||
| `customVolumes.projects.size` | Size of the volume | `8Gi` |
|
||||
| `customVolumes.projects.accessModes` | Volume access mode | `ReadWriteOnce` |
|
||||
| `customVolumes.postgres.storageClassName` | PersistentVolume storage class name | `<resourcename>-projects-volume` |
|
||||
|
||||
# Contributing
|
||||
|
||||
@@ -63,5 +364,3 @@ The chart is currently hosted on the gh-pages branch of the repo. During the rel
|
||||
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.
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
spec:
|
||||
{{- /* Provide custom persistent volumes configs if enabled */}}
|
||||
{{- include "spec.storageClassNames" $ }}
|
||||
{{- /* Provide custom secrets configs if enabled */}}
|
||||
{{- include "spec.secrets" $ }}
|
||||
{{- /* Include raw map from the values file spec */}}
|
||||
{{ .spec | toYaml | indent 2 }}
|
||||
{{- /* Provide security context defaults */}}
|
||||
|
||||
8
.helm/starter/templates/extra-list.yaml
Normal file
8
.helm/starter/templates/extra-list.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
{{- range .Values.extraDeploy }}
|
||||
---
|
||||
{{- if typeIs "string" . }}
|
||||
{{- tpl . $ }}
|
||||
{{- else }}
|
||||
{{- tpl (. | toYaml | nindent 0) $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
170
.helm/starter/templates/secrets/_helpers.tpl
Normal file
170
.helm/starter/templates/secrets/_helpers.tpl
Normal file
@@ -0,0 +1,170 @@
|
||||
{{/*
|
||||
Generate certificates for ingress
|
||||
*/}}
|
||||
{{- define "ingress.gen-certs" -}}
|
||||
{{- $ca := genCA "ingress-ca" 365 -}}
|
||||
{{- $cert := genSignedCert ( $.Values.AWX.spec.hostname | required "AWX.spec.hostname is required!" ) nil nil 365 $ca -}}
|
||||
tls.crt: {{ $cert.Cert | b64enc }}
|
||||
tls.key: {{ $cert.Key | b64enc }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the admin user password
|
||||
*/}}
|
||||
{{- define "admin.secretName" -}}
|
||||
{{ default (printf "%s-admin-password" $.Values.AWX.name) (default $.Values.customSecrets.admin.secretName $.Values.AWX.spec.admin_password_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the TLS information when ingress_type=route
|
||||
*/}}
|
||||
{{- define "routeTls.secretName" -}}
|
||||
{{ default (printf "%s-route-tls" $.Values.AWX.name) (default $.Values.customSecrets.routeTls.secretName $.Values.AWX.spec.route_tls_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the TLS information when ingress_type=ingress
|
||||
*/}}
|
||||
{{- define "ingressTls.secretName" -}}
|
||||
{{ default (printf "%s-ingress-tls" $.Values.AWX.name) (default $.Values.customSecrets.ingressTls.secretName $.Values.AWX.spec.ingress_tls_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the LDAP Certificate Authority
|
||||
*/}}
|
||||
{{- define "ldapCacert.secretName" -}}
|
||||
{{ default (printf "%s-custom-certs" $.Values.AWX.name) (default ($.Values.customSecrets.ldapCacert).secretName $.Values.AWX.spec.ldap_cacert_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the custom Certificate Authority
|
||||
*/}}
|
||||
{{- define "bundleCacert.secretName" -}}
|
||||
{{ default (printf "%s-custom-certs" $.Values.AWX.name) (default ($.Values.customSecrets.bundleCacert).secretName $.Values.AWX.spec.bundle_cacert_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the LDAP BIND DN password
|
||||
*/}}
|
||||
{{- define "ldap.secretName" -}}
|
||||
{{ default (printf "%s-ldap-password" $.Values.AWX.name) (default $.Values.customSecrets.ldap.secretName $.Values.AWX.spec.ldap_password_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the symmetric key for encryption
|
||||
*/}}
|
||||
{{- define "secretKey.secretName" -}}
|
||||
{{ default (printf "%s-secret-key" $.Values.AWX.name) (default $.Values.customSecrets.secretKey.secretName $.Values.AWX.spec.secret_key_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the default execution environment pull credentials
|
||||
*/}}
|
||||
{{- define "eePullCredentials.secretName" -}}
|
||||
{{ default (printf "%s-ee-pull-credentials" $.Values.AWX.name) (default $.Values.customSecrets.eePullCredentials.secretName $.Values.AWX.spec.ee_pull_credentials_secret) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secret that contains the default control plane pull credentials
|
||||
*/}}
|
||||
{{- define "cpPullCredentials.secretName" -}}
|
||||
{{ default (printf "%s-cp-pull-credentials" $.Values.AWX.name) (default $.Values.customSecrets.cpPullCredentials.secretName $.Values.AWX.spec.image_pull_secrets) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the .dockerconfigjson file unencoded.
|
||||
*/}}
|
||||
{{- define "dockerconfigjson.b64dec" }}
|
||||
{{- print "{\"auths\":{" }}
|
||||
{{- range $index, $item := . }}
|
||||
{{- if $index }}
|
||||
{{- print "," }}
|
||||
{{- end }}
|
||||
{{- printf "\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}" (default "https://index.docker.io/v1/" $item.registry) $item.username $item.password (default "" $item.email) (printf "%s:%s" $item.username $item.password | b64enc) }}
|
||||
{{- end }}
|
||||
{{- print "}}" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the base64-encoded .dockerconfigjson.
|
||||
*/}}
|
||||
{{- define "dockerconfigjson.b64enc" }}
|
||||
{{- $list := ternary (list .) . (kindIs "map" .) }}
|
||||
{{- include "dockerconfigjson.required" $list }}
|
||||
{{- include "dockerconfigjson.b64dec" $list | b64enc }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Required values for .dockerconfigjson
|
||||
*/}}
|
||||
{{- define "dockerconfigjson.required" -}}
|
||||
{{- range . -}}
|
||||
{{- $_ := required "cpPullCredentials.dockerconfigjson[].username is required!" .username -}}
|
||||
{{- $_ := required "cpPullCredentials.dockerconfigjson[].password is required!" .password -}}
|
||||
{{- end -}}
|
||||
{{/* Check for registry uniqueness */}}
|
||||
{{- $registries := list -}}
|
||||
{{- range . -}}
|
||||
{{- $registries = append $registries (default "https://index.docker.io/v1/" .registry) -}}
|
||||
{{- end -}}
|
||||
{{- $_ := required "All cpPullCredentials.dockerconfigjson[].registry's must be unique!" (or (eq (len $registries) (len ($registries | uniq))) nil) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Generate the name of the secrets
|
||||
*/}}
|
||||
{{- define "spec.secrets" -}}
|
||||
{{- /* secret configs if enabled */}}
|
||||
{{- if hasKey $.Values "customSecrets" }}
|
||||
{{- with $.Values.customSecrets }}
|
||||
{{- if .enabled }}
|
||||
{{- if hasKey . "admin" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "admin_password_secret")) .admin.enabled }}
|
||||
admin_password_secret: {{ include "admin.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "secretKey" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "secret_key_secret")) .secretKey.enabled }}
|
||||
secret_key_secret: {{ include "secretKey.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "routeTls" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "route_tls_secret")) .routeTls.enabled }}
|
||||
route_tls_secret: {{ include "routeTls.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "ingressTls" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "ingress_tls_secret")) .ingressTls.enabled }}
|
||||
ingress_tls_secret: {{ include "ingressTls.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "ldapCacert" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "ldap_cacert_secret")) .ldapCacert.enabled }}
|
||||
ldap_cacert_secret: {{ include "ldapCacert.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "bundleCacert" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "bundle_cacert_secret")) .bundleCacert.enabled }}
|
||||
bundle_cacert_secret: {{ include "bundleCacert.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "ldap" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "ldap_password_secret")) .ldap.enabled }}
|
||||
ldap_password_secret: {{ include "ldap.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "eePullCredentials" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "ee_pull_credentials_secret")) .eePullCredentials.enabled }}
|
||||
ee_pull_credentials_secret: {{ include "eePullCredentials.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if hasKey . "cpPullCredentials" }}
|
||||
{{- if and (not (hasKey $.Values.AWX.spec "image_pull_secrets")) .cpPullCredentials.enabled }}
|
||||
image_pull_secrets:
|
||||
- {{ include "cpPullCredentials.secretName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
16
.helm/starter/templates/secrets/admin-password-secret.yaml
Normal file
16
.helm/starter/templates/secrets/admin-password-secret.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- if hasKey .Values.customSecrets "admin" }}
|
||||
{{- with $.Values.customSecrets.admin }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "admin.secretName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: Opaque
|
||||
data:
|
||||
password: {{ .password | required "customSecrets.admin.password is required!" | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,16 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- if hasKey .Values.customSecrets "cpPullCredentials" }}
|
||||
{{- with $.Values.customSecrets.cpPullCredentials }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "cpPullCredentials.secretName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: {{ template "dockerconfigjson.b64enc" .dockerconfig | required "customSecrets.cpPullCredentials.dockerconfig is required!" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
49
.helm/starter/templates/secrets/custom-certs-secret.yaml
Normal file
49
.helm/starter/templates/secrets/custom-certs-secret.yaml
Normal file
@@ -0,0 +1,49 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- with .Values.customSecrets }}
|
||||
{{- $hasLdapCrt := (hasKey $.Values.customSecrets "ldapCacert") -}}
|
||||
{{- $hasBundleCrt := (hasKey . "bundleCacert") -}}
|
||||
{{- if or $hasLdapCrt $hasBundleCrt }}
|
||||
{{- $ldapCrtEnabled := ternary (.ldapCacert).enabled false $hasLdapCrt -}}
|
||||
{{- $bundleCrtEnabled := ternary (.bundleCacert).enabled false $hasBundleCrt -}}
|
||||
{{- $ldapSecretName := (include "ldapCacert.secretName" $) -}}
|
||||
{{- $bundleSecretName := (include "bundleCacert.secretName" $) -}}
|
||||
{{- if and (or $bundleCrtEnabled $ldapCrtEnabled) (eq $ldapSecretName $bundleSecretName) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ $ldapSecretName }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: Opaque
|
||||
data:
|
||||
{{- if $ldapCrtEnabled }}
|
||||
ldap-ca.crt: {{ .ldapCacert.crt | required "customSecrets.ldapCacert.crt is required!" | b64enc }}
|
||||
{{- end }}
|
||||
{{- if $bundleCrtEnabled }}
|
||||
bundle-ca.crt: {{ .bundleCacert.crt | required "customSecrets.bundleCacert.crt is required!" | b64enc }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- if $ldapCrtEnabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ $ldapSecretName }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: Opaque
|
||||
data:
|
||||
ldap-ca.crt: {{ .ldapCacert.crt | required "customSecrets.ldapCacert.crt is required!" | b64enc }}
|
||||
{{- end }}
|
||||
{{- if $bundleCrtEnabled }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ $bundleSecretName }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: Opaque
|
||||
data:
|
||||
bundle-ca.crt: {{ .bundleCacert.crt | required "customSecrets.bundleCacert.crt is required!" | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- if hasKey .Values.customSecrets "eePullCredentials" }}
|
||||
{{- with $.Values.customSecrets.eePullCredentials }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "eePullCredentials.secretName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
url: {{ (required "customSecrets.eePullCredentials.url is required!" .url) | quote }}
|
||||
username: {{ (required "customSecrets.eePullCredentials.username is required!" .username) | quote }}
|
||||
password: {{ (required "customSecrets.eePullCredentials.password is required!" .password) | quote }}
|
||||
ssl_verify: {{ or .sslVerify (eq (.sslVerify | toString) "<nil>") | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
25
.helm/starter/templates/secrets/ingress-tls-secret.yaml
Normal file
25
.helm/starter/templates/secrets/ingress-tls-secret.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- if hasKey .Values.customSecrets "ingressTls" }}
|
||||
{{- with $.Values.customSecrets.ingressTls }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "ingressTls.secretName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
{{- if .labels }}
|
||||
labels:
|
||||
{{ toYaml .labels | indent 4 }}
|
||||
{{- end }}
|
||||
type: kubernetes.io/tls
|
||||
data:
|
||||
{{- if .selfSignedCert }}
|
||||
{{ ( include "ingress.gen-certs" $ ) | indent 2 }}
|
||||
{{ else }}
|
||||
tls.key: {{ (.key | required "customSecrets.ingressTls.key is required!") | b64enc }}
|
||||
tls.crt: {{ (.certificate | required "customSecrets.ingressTls.certificate is required!") | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
16
.helm/starter/templates/secrets/ldap-password-secret.yaml
Normal file
16
.helm/starter/templates/secrets/ldap-password-secret.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- if hasKey .Values.customSecrets "ldap" }}
|
||||
{{- with $.Values.customSecrets.ldap }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "ldap.secretName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: Opaque
|
||||
data:
|
||||
ldap-password: {{ .password | required "customSecrets.ldap.password is required!" | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
17
.helm/starter/templates/secrets/route-tls-secret.yaml
Normal file
17
.helm/starter/templates/secrets/route-tls-secret.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- if hasKey .Values.customSecrets "routeTls" }}
|
||||
{{- with $.Values.customSecrets.routeTls }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "routeTls.secretName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: kubernetes.io/tls
|
||||
data:
|
||||
tls.key: {{ (.key | required "customSecrets.routeTls.key is required!") | b64enc }}
|
||||
tls.crt: {{ (.certificate | required "customSecrets.routeTls.certificate is required!") | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
16
.helm/starter/templates/secrets/secret-key-secret.yaml
Normal file
16
.helm/starter/templates/secrets/secret-key-secret.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
{{- if ($.Values.customSecrets).enabled }}
|
||||
{{- if hasKey .Values.customSecrets "secretKey" }}
|
||||
{{- with $.Values.customSecrets.secretKey }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "secretKey.secretName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
secret_key: {{ .key | required "customSecrets.secretKey.key is required!" | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
57
.helm/starter/templates/storage/_helpers.tpl
Normal file
57
.helm/starter/templates/storage/_helpers.tpl
Normal file
@@ -0,0 +1,57 @@
|
||||
{{/*
|
||||
Generate the name of the persistent volume for postgres folders
|
||||
*/}}
|
||||
{{- define "postgres.persistentVolumeName" -}}
|
||||
{{ printf "%s-postgres-volume" $.Values.AWX.name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the persistent volume for projects folder
|
||||
*/}}
|
||||
{{- define "projects.persistentVolumeName" -}}
|
||||
{{ printf "%s-projects-volume" $.Values.AWX.name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the persistent volume claim for the projects volume
|
||||
*/}}
|
||||
{{- define "projects.persistentVolumeClaim" -}}
|
||||
{{ printf "%s-projects-claim" $.Values.AWX.name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the storage class to use for the postgres volume
|
||||
*/}}
|
||||
{{- define "postgres.storageClassName" -}}
|
||||
{{ default (printf "%s-postgres-volume" $.Values.AWX.name) (default $.Values.AWX.spec.postgres_storage_class (($.Values.customVolumes).postgres).storageClassName) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the storage class to use for the projects volume
|
||||
*/}}
|
||||
{{- define "projects.storageClassName" -}}
|
||||
{{ default (printf "%s-projects-volume" $.Values.AWX.name) (default $.Values.AWX.spec.projects_storage_class (($.Values.customVolumes).projects).storageClassName) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate the name of the storage class names, expects AWX context passed in
|
||||
*/}}
|
||||
{{- define "spec.storageClassNames" -}}
|
||||
{{- if and (not $.Values.AWX.postgres.enabled) (eq (($.Values.AWX.spec).postgres_configuration_secret | default "") "") -}}
|
||||
{{- if (($.Values.customVolumes).postgres).enabled -}}
|
||||
{{- if not (hasKey $.Values.AWX.spec "postgres_storage_class") }}
|
||||
postgres_storage_class: {{ include "postgres.storageClassName" $ }}
|
||||
{{- end }}
|
||||
{{- if not (hasKey $.Values.AWX.spec "postgres_storage_requirements") }}
|
||||
postgres_storage_requirements:
|
||||
requests:
|
||||
storage: {{ default "8Gi" $.Values.customVolumes.postgres.size | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and ($.Values.AWX.spec.projects_persistence) (eq (($.Values.AWX.spec).projects_existing_claim | default "") "") -}}
|
||||
{{- if (($.Values.customVolumes).projects).enabled }}
|
||||
projects_existing_claim: {{ include "projects.persistentVolumeClaim" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
19
.helm/starter/templates/storage/postgres-pv.yaml
Normal file
19
.helm/starter/templates/storage/postgres-pv.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
{{- if and (not $.Values.AWX.postgres.enabled) (eq (($.Values.AWX.spec).postgres_configuration_secret | default "") "") -}}
|
||||
{{- if (($.Values.customVolumes).postgres).enabled -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: {{ include "postgres.persistentVolumeName" $ }}
|
||||
{{- with $.Values.customVolumes.postgres }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ default "ReadWriteOnce" .accessModes }}
|
||||
persistentVolumeReclaimPolicy: {{ default "Retain" .reclaimPolicy | quote }}
|
||||
capacity:
|
||||
storage: {{ default "8Gi" .size | quote }}
|
||||
storageClassName: {{ include "postgres.storageClassName" $ }}
|
||||
hostPath:
|
||||
path: {{ required "customVolumes.postgres.hostPath or spec.postgres_data_path are required!" (default ($.Values.AWX.spec).postgres_data_path .hostPath) | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
32
.helm/starter/templates/storage/projects-pv.yaml
Normal file
32
.helm/starter/templates/storage/projects-pv.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
{{- if and ($.Values.AWX.spec.projects_persistence) (eq (($.Values.AWX.spec).projects_existing_claim | default "") "") -}}
|
||||
{{- if (($.Values.customVolumes).projects).enabled -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: {{ include "projects.persistentVolumeName" $ }}
|
||||
{{- with $.Values.customVolumes.projects }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ default "ReadWriteOnce" (default $.Values.AWX.spec.projects_storage_access_mode .accessModes) }}
|
||||
persistentVolumeReclaimPolicy: {{ default "Retain" .reclaimPolicy | quote }}
|
||||
capacity:
|
||||
storage: {{ default "8Gi" (default $.Values.AWX.spec.projects_storage_size .size) | quote }}
|
||||
storageClassName: {{ include "projects.storageClassName" $ }}
|
||||
hostPath:
|
||||
path: {{ required "customVolumes.projects.hostPath is required!" .hostPath | quote }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "projects.persistentVolumeClaim" $ }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ default "ReadWriteOnce" (default $.Values.AWX.spec.projects_storage_access_mode .accessModes) }}
|
||||
volumeMode: Filesystem
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ default "8Gi" (default $.Values.AWX.spec.projects_storage_size .size) | quote }}
|
||||
storageClassName: {{ include "projects.storageClassName" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -25,7 +25,7 @@ Have questions about this document or anything not covered here? Please file a n
|
||||
|
||||
|
||||
## Submmiting your work
|
||||
1. From your fork `devel` branch, create a new brach to stage your changes.
|
||||
1. From your fork `devel` branch, create a new branch to stage your changes.
|
||||
```sh
|
||||
#> git checkout -b <branch-name>
|
||||
```
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
FROM quay.io/operator-framework/ansible-operator:v1.28.1
|
||||
FROM quay.io/operator-framework/ansible-operator:v1.34.0
|
||||
|
||||
USER 0
|
||||
|
||||
RUN dnf install -y openssl
|
||||
USER root
|
||||
RUN dnf update --security --bugfix -y && \
|
||||
dnf install -y openssl
|
||||
|
||||
USER 1001
|
||||
|
||||
|
||||
46
Makefile
46
Makefile
@@ -4,6 +4,7 @@
|
||||
# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
|
||||
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
|
||||
VERSION ?= $(shell git describe --tags)
|
||||
PREV_VERSION ?= $(shell git describe --abbrev=0 --tags $(shell git rev-list --tags --skip=1 --max-count=1))
|
||||
|
||||
CONTAINER_CMD ?= docker
|
||||
|
||||
@@ -88,6 +89,10 @@ all: docker-build
|
||||
help: ## Display this help.
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
.PHONY: print-%
|
||||
print-%: ## Print any variable from the Makefile. Use as `make print-VARIABLE`
|
||||
@echo $($*)
|
||||
|
||||
##@ Build
|
||||
|
||||
.PHONY: run
|
||||
@@ -102,6 +107,21 @@ docker-build: ## Build docker image with the manager.
|
||||
docker-push: ## Push docker image with the manager.
|
||||
${CONTAINER_CMD} push ${IMG}
|
||||
|
||||
# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
|
||||
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
|
||||
# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
|
||||
# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
|
||||
# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> than the export will fail)
|
||||
# To properly provided solutions that supports more than one platform you should use this option.
|
||||
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
|
||||
.PHONY: docker-buildx
|
||||
docker-buildx: ## Build and push docker image for the manager for cross-platform support
|
||||
- docker buildx create --name project-v3-builder
|
||||
docker buildx use project-v3-builder
|
||||
- docker buildx build --push $(BUILD_ARGS) --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile .
|
||||
- docker buildx rm project-v3-builder
|
||||
|
||||
|
||||
##@ Deployment
|
||||
|
||||
.PHONY: install
|
||||
@@ -149,6 +169,22 @@ KUSTOMIZE = $(shell which kustomize)
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: operator-sdk
|
||||
OPERATOR_SDK = $(shell pwd)/bin/operator-sdk
|
||||
operator-sdk: ## Download operator-sdk locally if necessary, preferring the $(pwd)/bin path over global if both exist.
|
||||
ifeq (,$(wildcard $(OPERATOR_SDK)))
|
||||
ifeq (,$(shell which operator-sdk 2>/dev/null))
|
||||
@{ \
|
||||
set -e ;\
|
||||
mkdir -p $(dir $(OPERATOR_SDK)) ;\
|
||||
curl -sSLo $(OPERATOR_SDK) https://github.com/operator-framework/operator-sdk/releases/download/v1.33.0/operator-sdk_$(OS)_$(ARCHA) ;\
|
||||
chmod +x $(OPERATOR_SDK) ;\
|
||||
}
|
||||
else
|
||||
OPERATOR_SDK = $(shell which operator-sdk)
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: ansible-operator
|
||||
ANSIBLE_OPERATOR = $(shell pwd)/bin/ansible-operator
|
||||
ansible-operator: ## Download ansible-operator locally if necessary, preferring the $(pwd)/bin path over global if both exist.
|
||||
@@ -157,7 +193,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.26.0/ansible-operator_$(OS)_$(ARCHA) ;\
|
||||
curl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/ansible-operator-plugins/releases/download/v1.34.0/ansible-operator_$(OS)_$(ARCHA) ;\
|
||||
chmod +x $(ANSIBLE_OPERATOR) ;\
|
||||
}
|
||||
else
|
||||
@@ -166,11 +202,11 @@ endif
|
||||
endif
|
||||
|
||||
.PHONY: bundle
|
||||
bundle: kustomize ## Generate bundle manifests and metadata, then validate generated files.
|
||||
operator-sdk generate kustomize manifests -q
|
||||
bundle: kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
|
||||
$(OPERATOR_SDK) generate kustomize manifests -q
|
||||
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
|
||||
$(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
|
||||
operator-sdk bundle validate ./bundle
|
||||
$(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
|
||||
$(OPERATOR_SDK) bundle validate ./bundle
|
||||
|
||||
.PHONY: bundle-build
|
||||
bundle-build: ## Build the bundle image.
|
||||
|
||||
11
PROJECT
11
PROJECT
@@ -1,3 +1,7 @@
|
||||
# Code generated by tool. DO NOT EDIT.
|
||||
# This file is used to track the info used to scaffold your project
|
||||
# and allow the plugins properly work.
|
||||
# More info: https://book.kubebuilder.io/reference/project-config.html
|
||||
domain: ansible.com
|
||||
layout:
|
||||
- ansible.sdk.operatorframework.io/v1
|
||||
@@ -27,4 +31,11 @@ resources:
|
||||
group: awx
|
||||
kind: AWXRestore
|
||||
version: v1beta1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
domain: ansible.com
|
||||
group: awx
|
||||
kind: AWXMeshIngress
|
||||
version: v1alpha1
|
||||
version: "3"
|
||||
|
||||
72
README.md
72
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://github.com/ansible/awx-operator/actions)
|
||||
[](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
|
||||
[](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
|
||||
[](https://groups.google.com/g/awx-project)
|
||||
[](https://libera.chat)
|
||||
|
||||
@@ -12,74 +12,11 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
|
||||
<!-- gh-md-toc --insert README.md -->
|
||||
<!--ts-->
|
||||
|
||||
**Note**: We are in the process of moving this readme into official docs in the /docs folder. Please go there to find additional sections during this interim move phase.
|
||||
# AWX Operator Documentation
|
||||
|
||||
The AWX Operator documentation is now available at https://awx-operator.readthedocs.io/
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
- [AWX Operator](#awx-operator)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Install and Configuration](#install-and-configuration)
|
||||
- [Contributing](#contributing)
|
||||
- [Release Process](#release-process)
|
||||
- [Author](#author)
|
||||
- [Code of Conduct](#code-of-conduct)
|
||||
- [Get Involved](#get-involved)
|
||||
|
||||
<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
|
||||
|
||||
<!--te-->
|
||||
|
||||
|
||||
|
||||
## Install and Configuration
|
||||
|
||||
All of our usage and configuration docs are nested in the `docs/` directory. Below is a Table of Contents for those.
|
||||
|
||||
- Introduction
|
||||
- [Introduction](./docs/introduction/introduction.md)
|
||||
- Contributors Guide
|
||||
- [Code of Conduct](./docs/contributors-guide/code-of-conduct.md)
|
||||
- [Get Involved](./docs/contributors-guide/get-involved.md)
|
||||
- [Contributing](./docs/contributors-guide/contributing.md)
|
||||
- [Release Process](./docs/contributors-guide/release-process.md)
|
||||
- [Authors](./docs/contributors-guide/author.md)
|
||||
- Installation
|
||||
- [Basic Install](./docs/installation/basic-install.md)
|
||||
- [Creating a Minikube cluster for testing](./docs/installation/creating-a-minikube-cluster-for-testing.md)
|
||||
- [Helm Install](./docs/installation/helm-install-on-existing-cluster.md)
|
||||
- [Migration](./docs/migration/migration.md)
|
||||
- [Uninstall](./docs/uninstall/uninstall.md)
|
||||
- User Guide
|
||||
- [Admin User Configuration](./docs/user-guide/admin-user-account-configuration.md)
|
||||
- [Database Configuration](./docs/user-guide/database-configuration.md)
|
||||
- [Network and TLS Configuration](./docs/user-guide/network-and-tls-configuration.md)
|
||||
- Advanced Configuration
|
||||
- [No Log](./docs/user-guide/advanced-configuration/no-log.md)
|
||||
- [Deploy a Specific Version of AWX](./docs/user-guide/advanced-configuration/deploying-a-specific-version-of-awx.md)
|
||||
- [Resource Requirements](./docs/user-guide/advanced-configuration/containers-resource-requirements.md)
|
||||
- [Extra Settings](./docs/user-guide/advanced-configuration/extra-settings.md)
|
||||
- [Environment Variables](./docs/user-guide/advanced-configuration/exporting-environment-variables-to-containers.md)
|
||||
- [Custom Labels](./docs/user-guide/advanced-configuration/labeling-operator-managed-objects.md)
|
||||
- [Custom Volumes](./docs/user-guide/advanced-configuration/custom-volume-and-volume-mount-options.md)
|
||||
- [Scaling Deployments](./docs/user-guide/advanced-configuration/scaling-the-web-and-task-pods-independently.md)
|
||||
- [Auto Update Upon Operator Upgrade](./docs/user-guide/advanced-configuration/auto-upgrade.md)
|
||||
- [Termination Grace Period](./docs/user-guide/advanced-configuration/pods-termination-grace-period.md)
|
||||
- [Node Selector for Deployments](./docs/user-guide/advanced-configuration/assigning-awx-pods-to-specific-nodes.md)
|
||||
- [Default EE from Private Registries](./docs/user-guide/advanced-configuration/default-execution-environments-from-private-registries.md)
|
||||
- [CSRF Cookie Secure](./docs/user-guide/advanced-configuration/csrf-cookie-secure-setting.md)
|
||||
- [Disable IPv6](./docs/user-guide/advanced-configuration/disable-ipv6.md)
|
||||
- [LDAP](./docs/user-guide/advanced-configuration/enabling-ldap-integration-at-awx-bootstrap.md)
|
||||
- [Priority Clases](./docs/user-guide/advanced-configuration/priority-classes.md)
|
||||
- [Priveleged Tasks](./docs/user-guide/advanced-configuration/privileged-tasks.md)
|
||||
- [Redis Container Capabilities](./docs/user-guide/advanced-configuration/redis-container-capabilities.md)
|
||||
- [Trusting a Custom Certificate Authority](./docs/user-guide/advanced-configuration/trusting-a-custom-certificate-authority.md)
|
||||
- [Service Account](./docs/user-guide/advanced-configuration/service-account.md)
|
||||
- [Persisting the Projects Directory](./docs/user-guide/advanced-configuration/persisting-projects-directory.md)
|
||||
- Troubleshooting
|
||||
- [General Debugging](./docs/troubleshooting/debugging.md)
|
||||
|
||||
For docs changes, create PRs on the appropriate files in the /docs folder.
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -110,4 +47,3 @@ We welcome your feedback and ideas. The AWX operator uses the same mailing list
|
||||
|
||||
- Join the [Ansible AWX channel on Matrix](https://matrix.to/#/#awx:ansible.com)
|
||||
- Join the [Ansible Community Forum](https://forum.ansible.com)
|
||||
- Join the [mailing list](https://groups.google.com/forum/#!forum/awx-project)
|
||||
|
||||
7
awxmeshingress-demo.yml
Normal file
7
awxmeshingress-demo.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1alpha1
|
||||
kind: AWXMeshIngress
|
||||
metadata:
|
||||
name: awx-mesh-ingress-demo
|
||||
spec:
|
||||
deployment_name: awx-demo
|
||||
@@ -92,7 +92,8 @@ spec:
|
||||
type: string
|
||||
precreate_partition_hours:
|
||||
description: Number of hours worth of events table partitions to precreate before backup to avoid pg_dump locks.
|
||||
type: string
|
||||
type: integer
|
||||
format: int32
|
||||
image_pull_policy:
|
||||
description: The image pull policy
|
||||
type: string
|
||||
|
||||
81
config/crd/bases/awx.ansible.com_awxmeshingresses.yaml
Normal file
81
config/crd/bases/awx.ansible.com_awxmeshingresses.yaml
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxmeshingresses.awx.ansible.com
|
||||
spec:
|
||||
group: awx.ansible.com
|
||||
names:
|
||||
kind: AWXMeshIngress
|
||||
listKind: AWXMeshIngressList
|
||||
plural: awxmeshingresses
|
||||
singular: awxmeshingress
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: AWXMeshIngress is the Schema for the awxmeshingresses API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec defines the desired state of AWXMeshIngress
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- deployment_name
|
||||
properties:
|
||||
deployment_name:
|
||||
description: Name of the AWX deployment to create the Mesh Ingress for.
|
||||
type: string
|
||||
external_hostname:
|
||||
description: External hostname to use for the Mesh Ingress.
|
||||
type: string
|
||||
external_ipaddress:
|
||||
description: External IP address to use for the Mesh Ingress.
|
||||
type: string
|
||||
ingress_type:
|
||||
description: The ingress type to use to reach the deployed instance
|
||||
type: string
|
||||
enum:
|
||||
- none
|
||||
- Ingress
|
||||
- ingress
|
||||
- IngressRouteTCP
|
||||
- ingressroutetcp
|
||||
- Route
|
||||
- route
|
||||
ingress_api_version:
|
||||
description: The Ingress API version to use
|
||||
type: string
|
||||
ingress_annotations:
|
||||
description: Annotations to add to the Ingress Controller
|
||||
type: string
|
||||
ingress_class_name:
|
||||
description: The name of ingress class to use instead of the cluster default.
|
||||
type: string
|
||||
ingress_controller:
|
||||
description: Special configuration for specific Ingress Controllers
|
||||
type: string
|
||||
status:
|
||||
description: Status defines the observed state of AWXMeshIngress
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -121,6 +121,10 @@ spec:
|
||||
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
|
||||
type: boolean
|
||||
default: true
|
||||
force_drop_db:
|
||||
description: Force drop the database before restoring. USE WITH CAUTION!
|
||||
type: boolean
|
||||
default: false
|
||||
status:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
|
||||
@@ -54,8 +54,8 @@ spec:
|
||||
description: Username to use for the admin account
|
||||
type: string
|
||||
default: admin
|
||||
hostname:
|
||||
description: The hostname of the instance
|
||||
hostname: # deprecated
|
||||
description: (Deprecated) The hostname of the instance
|
||||
type: string
|
||||
admin_email:
|
||||
description: The admin user email
|
||||
@@ -123,12 +123,24 @@ spec:
|
||||
ingress_annotations:
|
||||
description: Annotations to add to the Ingress Controller
|
||||
type: string
|
||||
ingress_tls_secret:
|
||||
description: Secret where the Ingress TLS secret can be found
|
||||
ingress_tls_secret: # deprecated
|
||||
description: (Deprecated) 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
|
||||
ingress_hosts:
|
||||
description: Ingress hostnames of the instance
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
hostname:
|
||||
description: Hostname of the instance
|
||||
type: string
|
||||
tls_secret:
|
||||
description: Secret where the Ingress TLS secret can be found
|
||||
type: string
|
||||
ingress_controller:
|
||||
description: Special configuration for specific Ingress Controllers
|
||||
type: string
|
||||
@@ -1608,6 +1620,9 @@ spec:
|
||||
web_extra_volume_mounts:
|
||||
description: Specify volume mounts to be added to the Web container
|
||||
type: string
|
||||
postgres_extra_volume_mounts:
|
||||
description: Specify volume mounts to be added to Postgres container
|
||||
type: string
|
||||
uwsgi_processes:
|
||||
description: Set the number of uwsgi processes to run in a web container
|
||||
type: integer
|
||||
@@ -1715,6 +1730,9 @@ spec:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
postgres_extra_volumes:
|
||||
description: Specify extra volumes to add to the application pod
|
||||
type: string
|
||||
postgres_keepalives:
|
||||
description: Controls whether client-side TCP keepalives are used for Postgres connections.
|
||||
default: true
|
||||
@@ -1779,6 +1797,10 @@ spec:
|
||||
session_cookie_secure:
|
||||
description: Set session cookie secure mode for web
|
||||
type: string
|
||||
postgres_security_context_settings:
|
||||
description: Key/values that will be set under the pod-level securityContext field
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
receptor_log_level:
|
||||
description: Set log level of receptor service
|
||||
type: string
|
||||
|
||||
@@ -5,4 +5,5 @@ resources:
|
||||
- bases/awx.ansible.com_awxs.yaml
|
||||
- bases/awx.ansible.com_awxbackups.yaml
|
||||
- bases/awx.ansible.com_awxrestores.yaml
|
||||
- bases/awx.ansible.com_awxmeshingresses.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizeresource
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1
|
||||
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0
|
||||
args:
|
||||
- "--secure-listen-address=0.0.0.0:8443"
|
||||
- "--upstream=http://127.0.0.1:8080/"
|
||||
|
||||
@@ -39,6 +39,7 @@ spec:
|
||||
- --leader-elect
|
||||
- --leader-election-id=awx-operator
|
||||
image: controller:latest
|
||||
imagePullPolicy: Always
|
||||
name: awx-manager
|
||||
env:
|
||||
- name: ANSIBLE_GATHERING
|
||||
@@ -72,8 +73,8 @@ spec:
|
||||
memory: "32Mi"
|
||||
cpu: "50m"
|
||||
limits:
|
||||
memory: "4096Mi"
|
||||
cpu: "2000m"
|
||||
memory: "960Mi"
|
||||
cpu: "1500m"
|
||||
serviceAccountName: controller-manager
|
||||
imagePullSecrets:
|
||||
- name: redhat-operators-pull-secret
|
||||
|
||||
@@ -10,12 +10,55 @@ metadata:
|
||||
description: AWX provides a web-based user interface, REST API, and task engine
|
||||
built on top of Ansible.
|
||||
repository: https://github.com/ansible/awx-operator
|
||||
support: forum.ansible.com
|
||||
name: awx-operator.v0.0.0
|
||||
namespace: placeholder
|
||||
spec:
|
||||
apiservicedefinitions: {}
|
||||
customresourcedefinitions:
|
||||
owned:
|
||||
- description: Deploy a instance of AWX Mesh ingress to allow inbound connection
|
||||
to the AWX Receptor Mesh.
|
||||
displayName: AWX Mesh Ingress
|
||||
kind: AWXMeshIngress
|
||||
name: awxmeshingresses.awx.ansible.com
|
||||
specDescriptors:
|
||||
- displayName: Deployment Name
|
||||
path: deployment_name
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: External Hostname
|
||||
path: external_hostname
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: External IP Address
|
||||
path: external_ipaddress
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Ingress Type
|
||||
path: ingress_type
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:none
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Ingress
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:IngressRouteTCP
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Route
|
||||
- displayName: Ingress API Version
|
||||
path: ingress_api_version
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Ingress Annotations
|
||||
path: ingress_annotations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Ingress Class Name
|
||||
path: ingress_class_name
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Ingress Controller
|
||||
path: ingress_controller
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
version: v1alpha1
|
||||
- description: Back up a deployment of the awx, including jobs, inventories, and
|
||||
credentials
|
||||
displayName: AWX Backup
|
||||
@@ -53,7 +96,7 @@ spec:
|
||||
- displayName: Precreate Partition Hours
|
||||
path: precreate_partition_hours
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:number
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Database Backup Label Selector
|
||||
@@ -61,6 +104,11 @@ spec:
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Security Context Settings
|
||||
path: postgres_security_context_settings
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image
|
||||
path: postgres_image
|
||||
x-descriptors:
|
||||
@@ -189,6 +237,11 @@ spec:
|
||||
path: db_management_pod_node_selector
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- displayName: Force drop database before restore
|
||||
path: force_drop_db
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
statusDescriptors:
|
||||
- description: The state of the restore
|
||||
displayName: Restore Status
|
||||
@@ -202,7 +255,7 @@ spec:
|
||||
kind: AWX
|
||||
name: awxs.awx.ansible.com
|
||||
specDescriptors:
|
||||
- displayName: Hostname
|
||||
- displayName: Hostname (Deprecated)
|
||||
path: hostname
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
@@ -292,12 +345,17 @@ spec:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
|
||||
- displayName: Ingress TLS Secret
|
||||
- displayName: Ingress TLS Secret (Deprecated)
|
||||
path: ingress_tls_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:ingress_type:Ingress
|
||||
- displayName: Ingress Hosts
|
||||
path: ingress_hosts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Ingress Controller
|
||||
path: ingress_controller
|
||||
x-descriptors:
|
||||
@@ -578,6 +636,18 @@ spec:
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Specify extra volumes to add to the postgres pod
|
||||
displayName: Postgres Extra Volumes
|
||||
path: postgres_extra_volumes
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- description: Specify volume mounts to be added to Postgres container
|
||||
displayName: Postgres Extra Volume Mounts
|
||||
path: postgres_extra_volume_mounts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Enable Postgres Keepalives
|
||||
path: postgres_keepalives
|
||||
x-descriptors:
|
||||
|
||||
31
config/rbac/awxmeshingress_editor_role.yaml
Normal file
31
config/rbac/awxmeshingress_editor_role.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
# permissions for end users to edit awxmeshingresses.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: clusterrole
|
||||
app.kubernetes.io/instance: awxmeshingress-editor-role
|
||||
app.kubernetes.io/component: rbac
|
||||
app.kubernetes.io/created-by: awx-operator
|
||||
app.kubernetes.io/part-of: awx-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: awxmeshingress-editor-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- awxmeshingresses
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- awxmeshingresses/status
|
||||
verbs:
|
||||
- get
|
||||
27
config/rbac/awxmeshingress_viewer_role.yaml
Normal file
27
config/rbac/awxmeshingress_viewer_role.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
# permissions for end users to view awxmeshingresses.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: clusterrole
|
||||
app.kubernetes.io/instance: awxmeshingress-viewer-role
|
||||
app.kubernetes.io/component: rbac
|
||||
app.kubernetes.io/created-by: awx-operator
|
||||
app.kubernetes.io/part-of: awx-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: awxmeshingress-viewer-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- awxmeshingresses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- awxmeshingresses/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -124,3 +124,16 @@ rules:
|
||||
- awxrestores
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
- traefik.io
|
||||
resources:
|
||||
- ingressroutetcps
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- create
|
||||
- delete
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
|
||||
8
config/samples/awx_v1alpha1_awxmeshingress.yaml
Normal file
8
config/samples/awx_v1alpha1_awxmeshingress.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# Placeholder to pass CI and allow bundle generation
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1alpha1
|
||||
kind: AWXMeshIngress
|
||||
metadata:
|
||||
name: example-awx-mesh-ingress
|
||||
spec:
|
||||
deployment_name: example-awx
|
||||
55
config/samples/awx_v1beta1_awx_resource_limits.yaml
Normal file
55
config/samples/awx_v1beta1_awx_resource_limits.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx-with-limits
|
||||
spec:
|
||||
task_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
web_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
ee_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
redis_resource_requirements:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
rsyslog_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
init_container_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
postgres_init_container_resource_requirements:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
@@ -3,4 +3,5 @@ resources:
|
||||
- awx_v1beta1_awx.yaml
|
||||
- awx_v1beta1_awxbackup.yaml
|
||||
- awx_v1beta1_awxrestore.yaml
|
||||
- awx_v1alpha1_awxmeshingress.yaml
|
||||
#+kubebuilder:scaffold:manifestskustomizesamples
|
||||
|
||||
@@ -9,7 +9,7 @@ After the draft release is created, publish it and the [Promote AWX Operator ima
|
||||
- Publish image to Quay
|
||||
- Release Helm chart
|
||||
|
||||
After the GHA is complete, the final step is to run the [publish-to-operator-hub.sh](./hack/publish-to-operator-hub.sh) script, which will create a PR in the following repos to add the new awx-operator bundle version to OperatorHub:
|
||||
After the GHA is complete, the final step is to run the [publish-to-operator-hub.sh](https://github.com/ansible/awx-operator/blob/devel/hack/publish-to-operator-hub.sh) script, which will create a PR in the following repos to add the new awx-operator bundle version to OperatorHub:
|
||||
* https://github.com/k8s-operatorhub/community-operators (community operator index)
|
||||
* https://github.com/redhat-openshift-ecosystem/community-operators-prod (operator index shipped with Openshift)
|
||||
|
||||
|
||||
@@ -1,7 +1,29 @@
|
||||
### Basic Install
|
||||
|
||||
After cloning this repository, you must choose the tag to run:
|
||||
```sh
|
||||
git clone git@github.com:ansible/awx-operator.git
|
||||
cd awx-operator
|
||||
git tag
|
||||
git checkout tags/<tag>
|
||||
|
||||
# For instance:
|
||||
git checkout tags/2.7.2
|
||||
```
|
||||
|
||||
If you work from a fork and made modifications since the tag was issued, you must provide the VERSION number to deploy. Otherwise the operator will get stuck in "ImagePullBackOff" state:
|
||||
|
||||
```sh
|
||||
export VERSION=<tag>
|
||||
|
||||
# For instance:
|
||||
export VERSION=2.7.2
|
||||
```
|
||||
|
||||
Once you have a running Kubernetes cluster, you can deploy AWX Operator into your cluster using [Kustomize](https://kubectl.docs.kubernetes.io/guides/introduction/kustomize/). Since kubectl version 1.14 kustomize functionality is built-in (otherwise, follow the instructions here to install the latest version of Kustomize: https://kubectl.docs.kubernetes.io/installation/kustomize/ )
|
||||
|
||||
> Some things may need to be configured slightly differently for different Kubernetes flavors for the networking aspects. When installing on Kind, see the [kind install docs](./kind-install.md) for more details.
|
||||
|
||||
There is a make target you can run:
|
||||
```
|
||||
make deploy
|
||||
@@ -67,7 +89,7 @@ So we don't have to keep repeating `-n awx`, let's set the current namespace for
|
||||
$ kubectl config set-context --current --namespace=awx
|
||||
```
|
||||
|
||||
Next, create a file named `awx-demo.yaml` in the same folder with the suggested content below. The `metadata.name` you provide will be the name of the resulting AWX deployment.
|
||||
Next, create a file named `awx-demo.yml` in the same folder with the suggested content below. The `metadata.name` you provide will be the name of the resulting AWX deployment.
|
||||
|
||||
**Note:** If you deploy more than one AWX instance to the same namespace, be sure to use unique names.
|
||||
|
||||
@@ -81,7 +103,7 @@ spec:
|
||||
service_type: nodeport
|
||||
```
|
||||
|
||||
> 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).
|
||||
> 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](../user-guide/admin-user-account-configuration.md#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.
|
||||
|
||||
@@ -104,7 +126,7 @@ Make sure to add this new file to the list of "resources" in your `kustomization
|
||||
resources:
|
||||
- github.com/ansible/awx-operator/config/default?ref=<tag>
|
||||
# Add this extra line:
|
||||
- awx-demo.yaml
|
||||
- awx-demo.yml
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
|
||||
This Kubernetes Operator is meant to be deployed in your Kubernetes cluster(s) and can manage one or more AWX instances in any namespace.
|
||||
This Kubernetes Operator is meant to be deployed in your Kubernetes cluster(s) and can be used to install and manage the lifecycle of an AWX instance in the same namespace.
|
||||
|
||||
125
docs/installation/kind-install.md
Normal file
125
docs/installation/kind-install.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# AWX Operator on Kind
|
||||
|
||||
## Kind Install
|
||||
|
||||
Install Kind by running the following
|
||||
|
||||
```
|
||||
# For Intel Macs
|
||||
[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-darwin-amd64
|
||||
# For M1 / ARM Macs
|
||||
[ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-darwin-arm64
|
||||
chmod +x ./kind
|
||||
mv ./kind /some-dir-in-your-PATH/kind
|
||||
```
|
||||
|
||||
> https://kind.sigs.k8s.io/docs/user/quick-start/
|
||||
|
||||
|
||||
### Create the Kind cluster
|
||||
|
||||
Create a file called `kind.config`
|
||||
|
||||
```yaml
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
kind: Cluster
|
||||
nodes:
|
||||
- role: control-plane
|
||||
extraPortMappings:
|
||||
- containerPort: 32000
|
||||
hostPort: 32000
|
||||
listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
|
||||
protocol: tcp # Optional, defaults to tcp
|
||||
- role: worker
|
||||
```
|
||||
|
||||
Then create a cluster using that config
|
||||
|
||||
```
|
||||
kind create cluster --config=kind.config
|
||||
```
|
||||
|
||||
Set cluster context for kubectl
|
||||
|
||||
```
|
||||
kubectl cluster-info --context kind-kind
|
||||
```
|
||||
|
||||
Install NGINX Ingress Controller
|
||||
|
||||
```
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
|
||||
```
|
||||
|
||||
|
||||
## AWX
|
||||
|
||||
Set the namespace context
|
||||
|
||||
```
|
||||
kubectl config set-context --current --namespace=awx
|
||||
```
|
||||
|
||||
Checkout the tag you want to install from
|
||||
|
||||
```
|
||||
git checkout 2.7.2
|
||||
```
|
||||
|
||||
Create a file named `kustomization.yaml` in the root of your local awx-operator clone. Include the following:
|
||||
|
||||
```
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
# Find the latest tag here: https://github.com/ansible/awx-operator/releases
|
||||
- github.com/ansible/awx-operator/config/default?ref=2.7.2
|
||||
|
||||
# Set the image tags to match the git version from above
|
||||
images:
|
||||
- name: quay.io/ansible/awx-operator
|
||||
newTag: 2.7.2
|
||||
|
||||
# Specify a custom namespace in which to install AWX
|
||||
namespace: awx
|
||||
```
|
||||
|
||||
Run the following to apply the yaml
|
||||
|
||||
```
|
||||
kubectl apply -k .
|
||||
```
|
||||
|
||||
|
||||
Create a file called `awx-cr.yaml` with the following contents and any configuration changes you may wish to add.
|
||||
|
||||
```
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx-demo
|
||||
spec:
|
||||
service_type: nodeport
|
||||
nodeport_port: 32000
|
||||
```
|
||||
|
||||
Create your AWX CR
|
||||
|
||||
```
|
||||
oc create -f awx-cr.yaml
|
||||
```
|
||||
|
||||
Your AWX instance should now be reacheable at http://localhost:32000/
|
||||
|
||||
> If you configured a custom nodeport_port, you can find it by running `kubectl -n awx get svc awx-demo-service`
|
||||
|
||||
|
||||
|
||||
## Cleanup
|
||||
|
||||
When you are done, you can delete all of this by running
|
||||
|
||||
```
|
||||
kind delete cluster
|
||||
```
|
||||
@@ -41,7 +41,7 @@ stringData:
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
> For `host`, a URL resolvable by the cluster could look something like `postgresql.<namespace>.svc.cluster.local`, where `<namespace>` is filled in with the namespace of the AWX deployment you are migrating data from.
|
||||
> For `host`, a URL resolvable by the cluster could look something like `postgresql.<namespace>.svc.<cluster domain>`, where `<namespace>` is filled in with the namespace of the AWX deployment you are migrating data from, and `<cluster domain>` is filled in with the internal kubernretes cluster domain (In most cases it's `cluster.local`).
|
||||
|
||||
If your AWX deployment is already using an external database server or its database is otherwise not managed
|
||||
by the AWX deployment, you can instead create the same secret as above but omit the `-old-` from the `name`.
|
||||
|
||||
@@ -7,6 +7,6 @@ mkdocs-material>=9.1.18
|
||||
mkdocs
|
||||
mkdocstrings-python>=1.1.0
|
||||
mkdocstrings>=0.22.0
|
||||
pillow==9.5.0
|
||||
pillow==10.0.1
|
||||
pipdeptree==2.7.1
|
||||
pymdown-extensions==10.0.1
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
### Upgrading
|
||||
|
||||
To upgrade AWX, it is recommended to upgrade the awx-operator to the version that maps to the desired version of AWX. To find the version of AWX that will be installed by the awx-operator by default, check the version specified in the `image_version` variable in `roles/installer/defaults/main.yml` for that particular release.
|
||||
To upgrade AWX, it is recommended to upgrade the awx-operator to the version that maps to the desired version of AWX. To find the version of AWX that will be installed by the awx-operator by default, check the version specified in the `DEFAULT_AWX_VERSION` variable for that particular release. You can do so by running the following command
|
||||
```shell
|
||||
AWX_OPERATOR_VERSION=2.8.0
|
||||
docker run --entrypoint="" quay.io/ansible/awx-operator:$AWX_OPERATOR_VERSION bash -c "env | grep DEFAULT_AWX_VERSION"
|
||||
```
|
||||
|
||||
Apply the awx-operator.yml for that release to upgrade the operator, and in turn also upgrade your AWX deployment.
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
### 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 [Managing Capacity With Instances](https://ansible.readthedocs.io/projects/awx/en/latest/administration/instances.html) chapter of the AWX Administration Guide for information about this feature.
|
||||
|
||||
@@ -26,7 +26,13 @@ The resource requirements for both, the task and the web containers are configur
|
||||
| -------------------------- | ------------------------------------------------ | ------------------------------------ |
|
||||
| web_resource_requirements | Web container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| task_resource_requirements | Task container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| ee_resource_requirements | EE control plane container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| ee_resource_requirements | EE control plane container resource requirements | requests: {cpu: 50m, memory: 64Mi} |
|
||||
| redis_resource_requirements | Redis container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| postgres_resource_requirements | Postgres container resource requirements | requests: {cpu: 10m, memory: 64Mi} |
|
||||
| rsyslog_resource_requirements | Rsyslog container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| init_container_resource_requirements | Init Container resource requirements | requests: {cpu: 100m, memory: 128Mi} |
|
||||
| postgres_init_container_resource_requirements | Postgres Init Container resource requirements | requests: {cpu: 10m, memory: 64Mi} |
|
||||
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
@@ -34,31 +40,63 @@ Example of customization could be:
|
||||
---
|
||||
spec:
|
||||
...
|
||||
web_resource_requirements:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 2Gi
|
||||
ephemeral-storage: 100M
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
ephemeral-storage: 500M
|
||||
|
||||
task_resource_requirements:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 1Gi
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
ephemeral-storage: 100M
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2Gi
|
||||
memory: 4Gi
|
||||
ephemeral-storage: 500M
|
||||
web_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
ee_resource_requirements:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 100Mi
|
||||
ephemeral-storage: 100M
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
redis_resource_requirements:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 4Gi
|
||||
rsyslog_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
init_container_resource_requirements:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
postgres_init_container_resource_requirements:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
ephemeral-storage: 500M
|
||||
```
|
||||
|
||||
|
||||
#### Limits and ResourceQuotas
|
||||
|
||||
If the cluster you are deploying in has a ResoruceQuota, you will need to configure resource limits for all of the pods deployed in that cluster. This can be done for AWX pods on the AWX spec in the manner shown above.
|
||||
|
||||
There is an example you can use in [`awx_v1beta1_awx_resource_limits.yaml`](https://raw.githubusercontent.com/ansible/awx-operator/devel/config/samples/awx_v1beta1_awx_resource_limits.yaml).
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
### 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.
|
||||
@@ -16,30 +16,3 @@ The following variables are customizable
|
||||
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.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
224
docs/user-guide/advanced-configuration/mesh-ingress.md
Normal file
224
docs/user-guide/advanced-configuration/mesh-ingress.md
Normal file
@@ -0,0 +1,224 @@
|
||||
# Mesh Ingress
|
||||
|
||||
The mesh ingress allows users to peer external execution and hop nodes into the AWX control plane.
|
||||
This guide focuses on how to enable and configure the mesh ingress.
|
||||
For more information about remote execution and hop nodes and how to create them, refer to the [Managing Capacity With Instances](https://ansible.readthedocs.io/projects/awx/en/latest/administration/instances.html) chapter of the AWX Administration Guide.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- AWX operator version > 2.11.0
|
||||
- AWX > 23.8.0
|
||||
|
||||
## Deploy and configure AWXMeshIngress
|
||||
|
||||
!!! note
|
||||
The mesh ingress uses the `control_plane_ee_image` and `image_pull_policy` fields of the AWX instance to determine image and policy to be adopted.
|
||||
Defaulted to `quay.io/ansible/awx-ee:latest` and `Always`.
|
||||
Currently there are no dedicated parameters to specify the image and policy.
|
||||
|
||||
### On Red Hat OpenShift with Operator managed Route
|
||||
|
||||
To deploy a mesh ingress on OpenShift, create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1alpha1
|
||||
kind: AWXMeshIngress
|
||||
metadata:
|
||||
name: <mesh ingress name>
|
||||
spec:
|
||||
deployment_name: <awx instance name>
|
||||
```
|
||||
|
||||
### On Kubernetes with Operator managed Ingress (NGINX)
|
||||
|
||||
To deploy a mesh ingress on Kubernetes cluster which has [NGINX Ingress Controller](https://www.nginx.com/products/nginx-ingress-controller/), create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
|
||||
|
||||
Note that AWXMeshIngress requires [SSL Passthrough](https://kubernetes.github.io/ingress-nginx/user-guide/tls/#ssl-passthrough) enabled which is disabled by default. Ensure it is enabled on your NGINX Ingress Controller.
|
||||
|
||||
By specifying `ingress_controller` as `nginx`, AWX Operator will generate Ingress resource that has `nginx.ingress.kubernetes.io/ssl-passthrough` annotation set to `"true"`.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1alpha1
|
||||
kind: AWXMeshIngress
|
||||
metadata:
|
||||
name: <mesh ingress name>
|
||||
spec:
|
||||
deployment_name: <awx instance name>
|
||||
|
||||
ingress_type: Ingress
|
||||
ingress_controller: nginx
|
||||
ingress_class_name: nginx
|
||||
|
||||
external_hostname: <fqdn for mesh ingress>
|
||||
```
|
||||
|
||||
### On Kubernetes with Operator managed Ingress (Traefik)
|
||||
|
||||
To deploy a mesh ingress on Kubernetes cluster which has [Traefik Kubernetes Ingress provider](https://doc.traefik.io/traefik/providers/kubernetes-ingress/), create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
|
||||
|
||||
Note that by deploying following AWXMeshIngress, AWX Operator will generate IngressRouteTCP resource that has `websecure` as an `entryPoints`. If this does not satisfy your requirement, refer to [User managed Ingress section](#on-kubernetes-with-user-managed-ingress) and create an IngressRouteTCP resource manually.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1alpha1
|
||||
kind: AWXMeshIngress
|
||||
metadata:
|
||||
name: <mesh ingress name>
|
||||
spec:
|
||||
deployment_name: <awx instance name>
|
||||
|
||||
ingress_type: IngressRouteTCP
|
||||
ingress_controller: traefik
|
||||
ingress_class_name: traefik
|
||||
ingress_api_version: traefik.io/v1alpha1
|
||||
|
||||
external_hostname: <fqdn for mesh ingress>
|
||||
```
|
||||
|
||||
### On Kubernetes with User managed Ingress
|
||||
|
||||
To deploy a mesh ingress on Kubernetes cluster, create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
|
||||
|
||||
Alternatively, if you wish to create your own Ingress resource, you can deploy a mesh ingress with `ingress_type` set to `none` and then manually create an Ingress resource with any configuration.
|
||||
|
||||
In this case, the `external_hostname` is still required as it is used to generate the certificate that will be used by Receptor.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1alpha1
|
||||
kind: AWXMeshIngress
|
||||
metadata:
|
||||
name: <mesh ingress name>
|
||||
spec:
|
||||
deployment_name: <awx instance name>
|
||||
|
||||
ingress_type: none # This line can be omitted since this is the default value
|
||||
external_hostname: <fqdn for mesh ingress>
|
||||
```
|
||||
|
||||
The requirements for user managed Ingress resource are as follows:
|
||||
|
||||
- Supports WebSocket
|
||||
- SSL/TLS Passthrough enabled
|
||||
- Accessible over port `443`
|
||||
- Having the same hostname as `external_hostname` in the AWXMeshIngress resource
|
||||
- Routing the traffic to port `27199` of the Service of the same name as the AWXMeshIngress resource
|
||||
|
||||
These are example Ingress resources for NGINX and Traefik.
|
||||
|
||||
```yaml
|
||||
# Ingress for NGINX Ingress Controller
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: <mesh ingress name>
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: <fqdn for mesh ingress>
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: <mesh ingress name>
|
||||
port:
|
||||
number: 27199
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Ingress for Traefik Kubernetes Ingress provider
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRouteTCP
|
||||
metadata:
|
||||
name: <mesh ingress name>
|
||||
spec:
|
||||
entryPoints:
|
||||
- websecure
|
||||
routes:
|
||||
- match: HostSNI(`<fqdn for mesh ingress>`)
|
||||
services:
|
||||
- name: <mesh ingress name>
|
||||
port: 27199
|
||||
tls:
|
||||
passthrough: true
|
||||
```
|
||||
|
||||
## Validating setup of Mesh Ingress
|
||||
|
||||
After AWXMeshIngress has been successfully created, a new Instance with the same name will be registered to AWX and will be visible on the Instance UI page
|
||||
|
||||

|
||||
|
||||
The Instance should have at least 2 listener addresses.
|
||||
|
||||
In this example, the mesh ingress has two listener addresses:
|
||||
|
||||
- one for internal, that is used for peering to by all control nodes (top)
|
||||
- one for external, that is exposed to a route so external execution nodes can peer into it (bottom))
|
||||
|
||||

|
||||
|
||||
When selecting peer for new instance the mesh ingress instance should now be present as a option.
|
||||

|
||||
|
||||
For more information about how to create external remote execution and hop nodes and configuring the mesh, see AWX Documentation on [Add a instance](https://ansible.readthedocs.io/projects/awx/en/latest/administration/instances.html#add-an-instance).
|
||||
|
||||
## Custom Resource Definitions
|
||||
|
||||
### AWXMeshIngress
|
||||
|
||||
AWXMeshIngress controls the deployment and configuration of mesh ingress on AWX
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`apiVersion`** | awx.ansible.com/v1alpha1 |
|
||||
| **`kind`** | AWXMeshIngress |
|
||||
| **`metadata`** ([ObjectMeta](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/object-meta/#ObjectMeta)) | Standard object's metadata. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata) |
|
||||
| **`spec`** ([AWXMeshIngressSpec](#awxmeshingressspec)) | Spec is the desired state of the AWXMeshIngress. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) |
|
||||
| **`status`** ([AWXMeshIngressStatus](#awxmeshingressstatus)) | Status is the current state of the AWXMeshIngress. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) |
|
||||
|
||||
#### AWXMeshIngressSpec
|
||||
|
||||
AWXMeshIngressSpec is the description of the configuration for AWXMeshIngress.
|
||||
|
||||
| Name | Description | Default |
|
||||
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
||||
| **`deployment_name`** (string), required | Name of the AWX deployment to create the Mesh Ingress for. | `awx` |
|
||||
| **`ingress_type`** (string) | Ingress type for ingress managed by the operator. Options: `none`, `Ingress`, `IngressRouteTCP`, `Route` | `Route` (on OpenShift), `none` (on Kubernetes) |
|
||||
| **`external_hostname`** (string) | External hostname is an optional field used for specifying the external hostname defined in an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/). This parameter is automatically generated on OpenShift | N/A |
|
||||
| **`external_ipaddress`** (string) | External IP Address is an optional field used for specifying the external IP address defined in an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) | N/A |
|
||||
| **`ingress_api_version`** (string) | API Version for ingress managed by the operator. This parameter is ignored when `ingress_type` is `Route` | `networking.k8s.io/v1` |
|
||||
| **`ingress_annotations`** (string) | Additional annotation on the ingress managed by the operator. This parameter is ignored when `ingress_type` is `Route` | `""` |
|
||||
| **`ingress_controller`** (string) | Special configuration for specific Ingress Controllers. This parameter is ignored when `ingress_type` is `Route` | `""` |
|
||||
| **`ingress_class_name`** (string) | The name of ingress class to use instead of the cluster default. see [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec). This parameter is ignored when `ingress_type` is `Route` | `""` |
|
||||
|
||||
#### AWXMeshIngressStatus
|
||||
|
||||
AWXMeshIngressStatus describe the current state of the AWXMeshIngress.
|
||||
|
||||
### AWXMeshIngressList
|
||||
|
||||
AWXMeshIngressList is a collection of AWXMeshIngress.
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`items`** ([AWXMeshIngress](#awxmeshingress)) | items is the list of Ingress. |
|
||||
| **`apiVersion`** (string) | APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources) |
|
||||
| **`kind`** (string) | Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds) |
|
||||
| **`metadata`** ([ListMeta](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/list-meta/#ListMeta)) | Standard object's metadata. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata) |
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 205 KiB |
@@ -5,4 +5,4 @@ You can scale replicas up or down for each deployment by using the `web_replicas
|
||||
- If you specify the `replicas` field, the key passed will scale both the `web` and `task` replicas to the same number.
|
||||
- If `web_replicas` or `task_replicas` is ever passed, it will override the existing `replicas` field on the specific deployment with the new key value.
|
||||
|
||||
These new replicas can be constrained in a similar manner to previous single deployments by appending the particular deployment name in front of the constraint used. More about those new constraints can be found below in the [Assigning AWX pods to specific nodes](#assigning-awx-pods-to-specific-nodes) section.
|
||||
These new replicas can be constrained in a similar manner to previous single deployments by appending the particular deployment name in front of the constraint used. More about those new constraints can be found in the [Assigning AWX pods to specific nodes](./assigning-awx-pods-to-specific-nodes.md) page.
|
||||
|
||||
27
docs/user-guide/advanced-configuration/security-context.md
Normal file
27
docs/user-guide/advanced-configuration/security-context.md
Normal file
@@ -0,0 +1,27 @@
|
||||
#### Service Account
|
||||
|
||||
It is possible to modify some `SecurityContext` proprieties of the various deployments and stateful sets if needed.
|
||||
|
||||
| Name | Description | Default |
|
||||
| ---------------------------------- | -------------------------------------------- | ------- |
|
||||
| security_context_settings | SecurityContext for Task and Web deployments | {} |
|
||||
| postgres_security_context_settings | SecurityContext for Task and Web deployments | {} |
|
||||
|
||||
|
||||
Example configuration securityContext for the Task and Web deployments:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
security_context_settings:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
```
|
||||
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
postgres_security_context_settings:
|
||||
runAsNonRoot: true
|
||||
```
|
||||
@@ -32,7 +32,7 @@ The following variables are customizable only when `service_type=LoadBalancer`
|
||||
| --------------------- | ---------------------------------------- | ------- |
|
||||
| loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
|
||||
| loadbalancer_port | Port used for Loadbalancer ingress | 80 |
|
||||
| loadbalancer_ip | Assign Loadbalancer IP | '' |
|
||||
| loadbalancer_ip | Assign Loadbalancer IP | '' |
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -86,22 +86,26 @@ spec:
|
||||
|
||||
The following variables are customizable when `ingress_type=ingress`. The `ingress` type creates an Ingress resource as [documented](https://kubernetes.io/docs/concepts/services-networking/ingress/) which can be shared with many other Ingress Controllers as [listed](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/).
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------- | ---------------------------------------- | --------------------------- |
|
||||
| ingress_annotations | Ingress annotations | Empty string |
|
||||
| ingress_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
| 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' |
|
||||
| Name | Description | Default |
|
||||
| ---------------------------------- | ---------------------------------------------------------------------------------- | --------------------------- |
|
||||
| ingress_annotations | Ingress annotations | Empty string |
|
||||
| ingress_tls_secret _(deprecated)_ | Secret that contains the TLS information | Empty string |
|
||||
| ingress_class_name | Define the ingress class name | Cluster default |
|
||||
| hostname _(deprecated)_ | Define the FQDN | {{ meta.name }}.example.com |
|
||||
| ingress_hosts | Define one or multiple FQDN with optional Secret that contains the TLS information | Empty string |
|
||||
| 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
|
||||
---
|
||||
spec:
|
||||
...
|
||||
ingress_type: ingress
|
||||
hostname: awx-demo.example.com
|
||||
ingress_hosts:
|
||||
- hostname: awx-demo.example.com
|
||||
- hostname: awx-demo.sample.com
|
||||
tls_secret: sample-tls-secret
|
||||
ingress_annotations: |
|
||||
environment: testing
|
||||
```
|
||||
@@ -119,7 +123,10 @@ Some Ingress Controllers need a special configuration to fully support AWX, add
|
||||
spec:
|
||||
...
|
||||
ingress_type: ingress
|
||||
hostname: awx-demo.example.com
|
||||
ingress_hosts:
|
||||
- hostname: awx-demo.example.com
|
||||
- hostname: awx-demo.sample.com
|
||||
tls_secret: sample-tls-secret
|
||||
ingress_controller: contour
|
||||
```
|
||||
|
||||
|
||||
100
hack/publish-to-operator-hub.sh
Normal file → Executable file
100
hack/publish-to-operator-hub.sh
Normal file → Executable file
@@ -15,43 +15,42 @@
|
||||
#
|
||||
# Usage:
|
||||
# First, check out awx-operator tag you intend to release, in this case, 1.0.0
|
||||
# $ VERSION=1.1.2 PREV_VERSION=1.1.1 FORK=<your-fork> ./publish-operator.sh
|
||||
# $ VERSION=1.1.2 PREV_VERSION=1.1.1 FORK=<your-fork> ./hack/publish-to-operator-hub.sh
|
||||
#
|
||||
# Remember to change update the VERSION and PREV_VERSION before running!!!
|
||||
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=${VERSION:-blah2}
|
||||
PREV_VERSION=${PREV_VERSION:-blah1}
|
||||
VERSION=${VERSION:-$(make print-VERSION)}
|
||||
PREV_VERSION=${PREV_VERSION:-$(make print-PREV_VERSION)}
|
||||
|
||||
BRANCH=publish-awx-operator-$VERSION
|
||||
FORK=${FORK:-fork}
|
||||
FORK=${FORK:-awx-auto}
|
||||
GITHUB_TOKEN=${GITHUB_TOKEN:-$AWX_AUTO_GITHUB_TOKEN}
|
||||
|
||||
IMG=quay.io/ansible/awx-operator:$VERSION
|
||||
CATALOG_IMG=quay.io/ansible/awx-operator-catalog:$VERSION
|
||||
BUNDLE_IMG=quay.io/ansible/awx-operator-bundle:$VERSION
|
||||
IMG_REPOSITORY=${IMG_REPOSITORY:-quay.io/ansible}
|
||||
|
||||
# Set path variables
|
||||
OPERATOR_PATH=${OPERATOR_PATH:-~/awx-operator}
|
||||
OPERATOR_IMG=$IMG_REPOSITORY/awx-operator:$VERSION
|
||||
CATALOG_IMG=$IMG_REPOSITORY/awx-operator-catalog:$VERSION
|
||||
BUNDLE_IMG=$IMG_REPOSITORY/awx-operator-bundle:$VERSION
|
||||
|
||||
# Build & Push Operator Image # Not needed because it is done as part of the GHA release automation
|
||||
# make docker-build docker-push IMG=$IMG
|
||||
COMMUNITY_OPERATOR_GITHUB_ORG=${COMMUNITY_OPERATOR_GITHUB_ORG:-k8s-operatorhub}
|
||||
COMMUNITY_OPERATOR_PROD_GITHUB_ORG=${COMMUNITY_OPERATOR_PROD_GITHUB_ORG:-redhat-openshift-ecosystem}
|
||||
|
||||
# Build bundle directory
|
||||
rm -rf bundle/
|
||||
make bundle IMG=$IMG
|
||||
make bundle IMG=$OPERATOR_IMG
|
||||
|
||||
# Build bundle and catalog images
|
||||
make bundle-build bundle-push BUNDLE_IMG=$BUNDLE_IMG IMG=$IMG
|
||||
make catalog-build catalog-push CATALOG_IMG=$CATALOG_IMG BUNDLE_IMGS=$BUNDLE_IMG BUNDLE_IMG=$BUNDLE_IMG IMG=$IMG
|
||||
make bundle-build bundle-push BUNDLE_IMG=$BUNDLE_IMG IMG=$OPERATOR_IMG
|
||||
make catalog-build catalog-push CATALOG_IMG=$CATALOG_IMG BUNDLE_IMGS=$BUNDLE_IMG BUNDLE_IMG=$BUNDLE_IMG IMG=$OPERATOR_IMG
|
||||
|
||||
# Set containerImage & namespace variables in CSV
|
||||
sed -i -e "s|containerImage: quay.io/ansible/awx-operator:devel|containerImage: quay.io/ansible/awx-operator:${VERSION}|g" bundle/manifests/awx-operator.clusterserviceversion.yaml
|
||||
sed -i -e "s|namespace: placeholder|namespace: awx|g" bundle/manifests/awx-operator.clusterserviceversion.yaml
|
||||
sed -i.bak -e "s|containerImage: quay.io/ansible/awx-operator:devel|containerImage: ${OPERATOR_IMG}|g" bundle/manifests/awx-operator.clusterserviceversion.yaml
|
||||
sed -i.bak -e "s|namespace: placeholder|namespace: awx|g" bundle/manifests/awx-operator.clusterserviceversion.yaml
|
||||
|
||||
# Add replaces to dependency graph for upgrade path
|
||||
if ! grep -qF 'replaces: awx-operator.v${PREV_VERSION}' bundle/manifests/awx-operator.clusterserviceversion.yaml; then
|
||||
sed -i -e "/version: ${VERSION}/a \\
|
||||
sed -i.bak -e "/version: ${VERSION}/a \\
|
||||
replaces: awx-operator.v$PREV_VERSION" bundle/manifests/awx-operator.clusterserviceversion.yaml
|
||||
fi
|
||||
|
||||
@@ -60,21 +59,20 @@ mv bundle/manifests/awx-operator.clusterserviceversion.yaml bundle/manifests/awx
|
||||
|
||||
# Set Openshift Support Range (bump minKubeVersion in CSV when changing)
|
||||
if ! grep -qF 'openshift.versions' bundle/metadata/annotations.yaml; then
|
||||
sed -i -e "/annotations:/a \\
|
||||
com.redhat.openshift.versions: v4.10-v4.13\n" bundle/metadata/annotations.yaml
|
||||
sed -i.bak -e "/annotations:/a \\
|
||||
com.redhat.openshift.versions: v4.11" bundle/metadata/annotations.yaml
|
||||
fi
|
||||
|
||||
# -- Put up community-operators PR
|
||||
cd $OPERATOR_PATH
|
||||
git clone git@github.com:k8s-operatorhub/community-operators.git
|
||||
# Remove .bak files from bundle result from sed commands
|
||||
find bundle -name "*.bak" -type f -delete
|
||||
|
||||
echo "-- Create branch on community-operators fork --"
|
||||
git clone https://github.com/$COMMUNITY_OPERATOR_GITHUB_ORG/community-operators.git
|
||||
|
||||
mkdir -p community-operators/operators/awx-operator/$VERSION/
|
||||
cp -r bundle/* community-operators/operators/awx-operator/$VERSION/
|
||||
cd community-operators/operators/awx-operator/$VERSION/
|
||||
pwd
|
||||
ls -la
|
||||
pushd community-operators/operators/awx-operator/$VERSION/
|
||||
|
||||
# Commit and push PR
|
||||
git checkout -b $BRANCH
|
||||
git add ./
|
||||
git status
|
||||
@@ -83,26 +81,26 @@ message='operator [N] [CI] awx-operator'
|
||||
commitMessage="${message} ${VERSION}"
|
||||
git commit -m "$commitMessage" -s
|
||||
|
||||
git remote add upstream git@github.com:$FORK/community-operators.git
|
||||
git remote add upstream https://$GITHUB_TOKEN@github.com/$FORK/community-operators.git
|
||||
|
||||
git push upstream --delete $BRANCH || true
|
||||
git push upstream $BRANCH
|
||||
|
||||
gh pr create \
|
||||
--title "operator awx-operator (${VERSION})" \
|
||||
--body "operator awx-operator (${VERSION})" \
|
||||
--base main \
|
||||
--head $FORK:$BRANCH \
|
||||
--repo $COMMUNITY_OPERATOR_GITHUB_ORG/community-operators
|
||||
popd
|
||||
|
||||
# -- Put up community-operators-prod PR
|
||||
# Reset directory
|
||||
cd $OPERATOR_PATH
|
||||
|
||||
pwd
|
||||
|
||||
git clone git@github.com:redhat-openshift-ecosystem/community-operators-prod.git
|
||||
echo "-- Create branch on community-operators-prod fork --"
|
||||
git clone https://github.com/$COMMUNITY_OPERATOR_PROD_GITHUB_ORG/community-operators-prod.git
|
||||
|
||||
mkdir -p community-operators-prod/operators/awx-operator/$VERSION/
|
||||
cp -r bundle/* community-operators-prod/operators/awx-operator/$VERSION/
|
||||
cd community-operators-prod/operators/awx-operator/$VERSION/
|
||||
pushd community-operators-prod/operators/awx-operator/$VERSION/
|
||||
|
||||
pwd
|
||||
ls -la
|
||||
|
||||
# Commit and push PR
|
||||
git checkout -b $BRANCH
|
||||
git add ./
|
||||
git status
|
||||
@@ -111,15 +109,15 @@ message='operator [N] [CI] awx-operator'
|
||||
commitMessage="${message} ${VERSION}"
|
||||
git commit -m "$commitMessage" -s
|
||||
|
||||
git remote add upstream git@github.com:$FORK/community-operators-prod.git
|
||||
git remote add upstream https://$GITHUB_TOKEN@github.com/$FORK/community-operators-prod.git
|
||||
|
||||
git push upstream --delete $BRANCH || true
|
||||
git push upstream $BRANCH
|
||||
|
||||
|
||||
# -- Print Links to Branches
|
||||
echo "Commnity Operators: https://github.com/$FORK/community-operators/pull/new/$BRANCH"
|
||||
echo "Commnity Operators Prod: https://github.com/$FORK/community-operators-prod/pull/new/$BRANCH"
|
||||
|
||||
# -- Cleanup
|
||||
|
||||
rm -rf $OPERATOR_PATH/community-operators
|
||||
rm -rf $OPERATOR_PATH/community-operators-prod
|
||||
gh pr create \
|
||||
--title "operator awx-operator (${VERSION})" \
|
||||
--body "operator awx-operator (${VERSION})" \
|
||||
--base main \
|
||||
--head $FORK:$BRANCH \
|
||||
--repo $COMMUNITY_OPERATOR_PROD_GITHUB_ORG/community-operators-prod
|
||||
popd
|
||||
|
||||
@@ -63,9 +63,11 @@ nav:
|
||||
- user-guide/advanced-configuration/privileged-tasks.md
|
||||
- user-guide/advanced-configuration/containers-resource-requirements.md
|
||||
- user-guide/advanced-configuration/priority-classes.md
|
||||
- user-guide/advanced-configuration/adding-execution-nodes.md
|
||||
- user-guide/advanced-configuration/scaling-the-web-and-task-pods-independently.md
|
||||
- user-guide/advanced-configuration/assigning-awx-pods-to-specific-nodes.md
|
||||
- user-guide/advanced-configuration/trusting-a-custom-certificate-authority.md
|
||||
- user-guide/advanced-configuration/custom-receptor-certs.md
|
||||
- user-guide/advanced-configuration/enabling-ldap-integration-at-awx-bootstrap.md
|
||||
- user-guide/advanced-configuration/persisting-projects-directory.md
|
||||
- user-guide/advanced-configuration/custom-volume-and-volume-mount-options.md
|
||||
@@ -80,6 +82,7 @@ nav:
|
||||
- user-guide/advanced-configuration/labeling-operator-managed-objects.md
|
||||
- user-guide/advanced-configuration/pods-termination-grace-period.md
|
||||
- user-guide/advanced-configuration/disable-ipv6.md
|
||||
- user-guide/advanced-configuration/mesh-ingress.md
|
||||
- Troubleshooting:
|
||||
- troubleshooting/debugging.md
|
||||
|
||||
|
||||
19
molecule/default/tasks/awxmeshingress_test.yml
Normal file
19
molecule/default/tasks/awxmeshingress_test.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
# TODO: Add tests for AWXMeshIngress
|
||||
# ---
|
||||
# - name: Create the awx.ansible.com/v1alpha1.AWXMeshIngress
|
||||
# k8s:
|
||||
# state: present
|
||||
# namespace: '{{ namespace }}'
|
||||
# definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}"
|
||||
# wait: yes
|
||||
# wait_timeout: 300
|
||||
# wait_condition:
|
||||
# type: Successful
|
||||
# status: "True"
|
||||
# vars:
|
||||
# cr_file: 'awx_v1alpha1_awxmeshingress.yaml'
|
||||
|
||||
# - name: Add assertions here
|
||||
# assert:
|
||||
# that: false
|
||||
# fail_msg: FIXME Add real assertions for your operator
|
||||
@@ -3,4 +3,4 @@ collections:
|
||||
- name: kubernetes.core
|
||||
version: '>=2.3.2'
|
||||
- name: operator_sdk.util
|
||||
version: "0.4.0"
|
||||
version: "0.5.0"
|
||||
|
||||
24
roles/backup/tasks/dump_ingress_tls_secrets.yml
Normal file
24
roles/backup/tasks/dump_ingress_tls_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
|
||||
@@ -70,16 +70,9 @@
|
||||
command: >-
|
||||
touch {{ backup_dir }}/tower.db
|
||||
|
||||
- name: Set permissions on file for database dump
|
||||
k8s_exec:
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: >-
|
||||
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:
|
||||
resolvable_db_host: '{{ (awx_postgres_type == "managed") | ternary(awx_postgres_host + "." + ansible_operator_meta.namespace + ".svc.cluster.local", awx_postgres_host) }}' # yamllint disable-line rule:line-length
|
||||
resolvable_db_host: '{{ (awx_postgres_type == "managed") | ternary(awx_postgres_host + "." + ansible_operator_meta.namespace + ".svc", awx_postgres_host) }}' # yamllint disable-line rule:line-length
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Get the current resource task pod information.
|
||||
@@ -88,7 +81,7 @@
|
||||
kind: Pod
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
label_selectors:
|
||||
- "app.kubernetes.io/name={{ ansible_operator_meta.name }}-task"
|
||||
- "app.kubernetes.io/name={{ deployment_name }}-task"
|
||||
- "app.kubernetes.io/managed-by={{ deployment_type }}-operator"
|
||||
- "app.kubernetes.io/component={{ deployment_type }}"
|
||||
field_selectors:
|
||||
@@ -134,11 +127,27 @@
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
pod: "{{ ansible_operator_meta.name }}-db-management"
|
||||
command: |
|
||||
bash -c """
|
||||
bash -c "
|
||||
function end_keepalive {
|
||||
rc=$?
|
||||
rm -f \"$1\"
|
||||
kill $(cat /proc/$2/task/$2/children 2>/dev/null) 2>/dev/null || true
|
||||
wait $2 || true
|
||||
exit $rc
|
||||
}
|
||||
keepalive_file=\"$(mktemp)\"
|
||||
while [[ -f \"$keepalive_file\" ]]; do
|
||||
echo 'Dumping data from database...'
|
||||
sleep 60
|
||||
done &
|
||||
keepalive_pid=$!
|
||||
trap 'end_keepalive \"$keepalive_file\" \"$keepalive_pid\"' EXIT SIGINT SIGTERM
|
||||
echo keepalive_pid: $keepalive_pid
|
||||
set -e -o pipefail
|
||||
PGPASSWORD='{{ awx_postgres_pass }}' {{ pgdump }} > {{ backup_dir }}/tower.db
|
||||
set +e +o pipefail
|
||||
echo 'Successful'
|
||||
"""
|
||||
"
|
||||
register: data_migration
|
||||
no_log: "{{ no_log }}"
|
||||
failed_when: "'Successful' not in data_migration.stdout"
|
||||
|
||||
@@ -12,11 +12,18 @@
|
||||
include_tasks: dump_secret.yml
|
||||
loop:
|
||||
- route_tls_secret
|
||||
# ingress_tls_secret is deprecated in favor of ingress_hosts.tls_secret
|
||||
- ingress_tls_secret
|
||||
- ldap_cacert_secret
|
||||
- bundle_cacert_secret
|
||||
- ee_pull_credentials_secret
|
||||
|
||||
- name: Dump ingress tls secret names from awx spec and data into file
|
||||
include_tasks: dump_ingress_tls_secrets.yml
|
||||
with_items:
|
||||
- "{{ awx_spec.spec['ingress_hosts'] | default('') | map(attribute='tls_secret', default='') | select() | list }}"
|
||||
when: "{{ awx_spec.spec['ingress_hosts'] | default('') | map(attribute='tls_secret', default='') | select() | list | length }}"
|
||||
|
||||
- name: Dump receptor secret names and data into file
|
||||
include_tasks: dump_receptor_secrets.yml
|
||||
loop:
|
||||
|
||||
@@ -40,6 +40,16 @@ ingress_tls_secret: ''
|
||||
# ingress_controller: contour
|
||||
ingress_controller: ''
|
||||
|
||||
# One or multiple FQDN with optional Secret that contains the TLS information.
|
||||
# The TLS secret either has to exist before hand with
|
||||
# the corresponding cert and key or just be an indicator for where an automated
|
||||
# process like cert-manager (enabled via annotations) will store the TLS
|
||||
# certificate and key.
|
||||
# ingress_hosts:
|
||||
# - hostname: awx-demo.example.com
|
||||
# tls_secret: example-com-tls
|
||||
ingress_hosts: ''
|
||||
|
||||
loadbalancer_protocol: 'http'
|
||||
loadbalancer_port: '80'
|
||||
service_annotations: ''
|
||||
@@ -233,6 +243,12 @@ ee_pull_credentials_secret: ''
|
||||
# emptyDir: {}
|
||||
extra_volumes: ''
|
||||
|
||||
# Add extra volumes to the Postgres pod. Specify as literal block. E.g.:
|
||||
# postgres_extra_volumes: |
|
||||
# - name: my-volume
|
||||
# emptyDir: {}
|
||||
postgres_extra_volumes: ''
|
||||
|
||||
# Use these image versions for Ansible AWX.
|
||||
|
||||
_image: quay.io/ansible/awx
|
||||
@@ -340,13 +356,14 @@ ee_extra_env: ''
|
||||
|
||||
# Mount extra volumes on the AWX task/web containers. Specify as literal block.
|
||||
# E.g.:
|
||||
# task_extra_volume_mounts: ''
|
||||
# task_extra_volume_mounts: |
|
||||
# - name: my-volume
|
||||
# mountPath: /some/path
|
||||
task_extra_volume_mounts: ''
|
||||
web_extra_volume_mounts: ''
|
||||
rsyslog_extra_volume_mounts: ''
|
||||
ee_extra_volume_mounts: ''
|
||||
postgres_extra_volume_mounts: ''
|
||||
|
||||
# Add a nodeSelector for the Postgres pods.
|
||||
# It must match a node's labels for the pod to be scheduled on that node.
|
||||
@@ -424,6 +441,7 @@ garbage_collect_secrets: false
|
||||
development_mode: false
|
||||
|
||||
security_context_settings: {}
|
||||
postgres_security_context_settings: {}
|
||||
|
||||
# Set no_log settings on certain tasks
|
||||
no_log: true
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
- name: Delete old deployment for before installing during upgrade
|
||||
k8s:
|
||||
kind: Deployment
|
||||
api_version: v1
|
||||
api_version: apps/v1
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
name: "{{ ansible_operator_meta.name }}"
|
||||
state: absent
|
||||
@@ -77,6 +77,20 @@
|
||||
- ingress_type | lower == 'route'
|
||||
- route_tls_secret != ''
|
||||
|
||||
- name: Wait for {{ deployment_type }}restore to complete
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: "{{ api_version }}"
|
||||
kind: "{{ deployment_type }}restore"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: restore_status_check
|
||||
until:
|
||||
# yamllint disable-line rule:line-length
|
||||
- (restore_status_check.resources | length == 0) or (restore_status_check.resources | selectattr('spec.deployment_name', 'equalto', ansible_operator_meta.name) | map(attribute='status') | selectattr('restoreComplete', 'defined') | map(attribute='restoreComplete') | list | length > 0)
|
||||
delay: 10
|
||||
retries: 8640
|
||||
ignore_errors: yes
|
||||
changed_when: false
|
||||
|
||||
- name: Include resources configuration tasks
|
||||
include_tasks: resources_configuration.yml
|
||||
|
||||
@@ -91,13 +105,31 @@
|
||||
when: awx_task_pod_name != ''
|
||||
register: database_check
|
||||
|
||||
- name: Migrate the database if the K8s resources were updated. # noqa 305
|
||||
- name: Migrate the database if the K8s resources were updated # noqa 305
|
||||
k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ awx_task_pod_name }}"
|
||||
container: "{{ ansible_operator_meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage migrate --noinput"
|
||||
command: |
|
||||
bash -c "
|
||||
function end_keepalive {
|
||||
rc=$?
|
||||
rm -f \"$1\"
|
||||
kill $(cat /proc/$2/task/$2/children 2>/dev/null) 2>/dev/null || true
|
||||
wait $2 || true
|
||||
exit $rc
|
||||
}
|
||||
keepalive_file=\"$(mktemp)\"
|
||||
while [[ -f \"$keepalive_file\" ]]; do
|
||||
echo 'Database schema migration in progress...'
|
||||
sleep 60
|
||||
done &
|
||||
keepalive_pid=$!
|
||||
trap 'end_keepalive \"$keepalive_file\" \"$keepalive_pid\"' EXIT SIGINT SIGTERM
|
||||
echo keepalive_pid: $keepalive_pid
|
||||
awx-manage migrate --noinput
|
||||
echo 'Successful'
|
||||
"
|
||||
register: migrate_result
|
||||
when:
|
||||
- awx_task_pod_name != ''
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
- name: Check for presence of awx-task Deployment
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
api_version: apps/v1
|
||||
kind: Deployment
|
||||
name: "{{ ansible_operator_meta.name }}-task"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
- name: Check for presence of awx-web Deployment
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
api_version: apps/v1
|
||||
kind: Deployment
|
||||
name: "{{ ansible_operator_meta.name }}-web"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
}
|
||||
keepalive_file=\"$(mktemp)\"
|
||||
while [[ -f \"$keepalive_file\" ]]; do
|
||||
echo 'Migrating data to new PostgreSQL {{ supported_postgres_version }} Database...'
|
||||
echo 'Migrating data to new PostgreSQL {{ supported_pg_version }} Database...'
|
||||
sleep 60
|
||||
done &
|
||||
keepalive_pid=$!
|
||||
|
||||
@@ -54,9 +54,6 @@ data:
|
||||
|
||||
INTERNAL_API_URL = 'http://127.0.0.1:8052'
|
||||
|
||||
# Sets Ansible Collection path
|
||||
AWX_ANSIBLE_COLLECTIONS_PATHS = '/var/lib/awx/vendor/awx_ansible_collections'
|
||||
|
||||
# Container environments don't like chroots
|
||||
AWX_PROOT_ENABLED = False
|
||||
|
||||
@@ -191,7 +188,7 @@ data:
|
||||
alias /var/lib/awx/public/static/media/favicon.ico;
|
||||
}
|
||||
|
||||
location {{ (ingress_path + '/websocket').replace('//', '/') }} {
|
||||
location ~ ^({{ (ingress_path + '/websocket/').replace('//', '/') }}|{{ (ingress_path + '/api/websocket/').replace('//', '/') }}) {
|
||||
# Pass request to the upstream alias
|
||||
proxy_pass http://daphne;
|
||||
# Require http version 1.1 to allow for upgrade requests
|
||||
|
||||
@@ -340,6 +340,10 @@ spec:
|
||||
{% elif affinity %}
|
||||
affinity:
|
||||
{{ affinity | to_nice_yaml | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if security_context_settings|length %}
|
||||
securityContext:
|
||||
{{ security_context_settings | to_nice_yaml | indent(8) }}
|
||||
{% endif %}
|
||||
volumes:
|
||||
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
|
||||
|
||||
@@ -24,6 +24,7 @@ spec:
|
||||
ingressClassName: '{{ ingress_class_name }}'
|
||||
{% endif %}
|
||||
rules:
|
||||
{% if not ingress_hosts %}
|
||||
- http:
|
||||
paths:
|
||||
- path: '{{ ingress_path }}'
|
||||
@@ -33,6 +34,37 @@ spec:
|
||||
name: '{{ ansible_operator_meta.name }}-service'
|
||||
port:
|
||||
number: 80
|
||||
{% if hostname %}
|
||||
host: {{ hostname }}
|
||||
{% endif %}
|
||||
{% if ingress_controller|lower == "contour" %}
|
||||
- path: '{{ ingress_path.rstrip("/") }}/websocket'
|
||||
pathType: '{{ ingress_path_type }}'
|
||||
backend:
|
||||
service:
|
||||
name: '{{ ansible_operator_meta.name }}-service'
|
||||
port:
|
||||
number: 80
|
||||
{% endif %}
|
||||
{% if ingress_tls_secret %}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ hostname }}
|
||||
secretName: {{ ingress_tls_secret }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if ingress_hosts %}
|
||||
{% for item in ingress_hosts %}
|
||||
- host: {{ item.hostname }}
|
||||
http:
|
||||
paths:
|
||||
- path: '{{ ingress_path }}'
|
||||
pathType: '{{ ingress_path_type }}'
|
||||
backend:
|
||||
service:
|
||||
name: '{{ ansible_operator_meta.name }}-service'
|
||||
port:
|
||||
number: 80
|
||||
{% if ingress_controller|lower == "contour" %}
|
||||
- path: '{{ ingress_path.rstrip("/") }}/websocket'
|
||||
pathType: '{{ ingress_path_type }}'
|
||||
@@ -42,14 +74,15 @@ spec:
|
||||
port:
|
||||
number: 80
|
||||
{% endif %}
|
||||
{% if hostname %}
|
||||
host: {{ hostname }}
|
||||
{% endif %}
|
||||
{% if ingress_tls_secret %}
|
||||
{% endfor %}
|
||||
tls:
|
||||
{% for item in ingress_hosts %}
|
||||
{% if 'tls_secret' in item %}
|
||||
- hosts:
|
||||
- {{ hostname }}
|
||||
secretName: {{ ingress_tls_secret }}
|
||||
- {{ item.hostname }}
|
||||
secretName: {{ item.tls_secret }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ spec:
|
||||
type: NodePort
|
||||
{% elif service_type | lower == "loadbalancer" %}
|
||||
type: LoadBalancer
|
||||
{% if loadbalancer_ip is defined and loadbalancer_ip|length %}
|
||||
{% if loadbalancer_ip is defined and loadbalancer_ip | length %}
|
||||
loadbalancerip: '{{ loadbalancer_ip }}'
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
||||
@@ -11,13 +11,20 @@ DATABASES = {
|
||||
{% if awx_postgres_sslmode in ['verify-ca', 'verify-full'] %}
|
||||
'sslrootcert': '{{ ca_trust_bundle }}',
|
||||
{% endif %}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
LISTENER_DATABASES = {
|
||||
'default': {
|
||||
'OPTIONS': {
|
||||
{% if postgres_keepalives %}
|
||||
'keepalives': 1,
|
||||
'keepalives_idle': {{ postgres_keepalives_idle }},
|
||||
'keepalives_interval': {{ postgres_keepalives_interval }},
|
||||
'keepalives_count': {{ postgres_keepalives_count }},
|
||||
'keepalives': 1,
|
||||
'keepalives_idle': {{ postgres_keepalives_idle }},
|
||||
'keepalives_interval': {{ postgres_keepalives_interval }},
|
||||
'keepalives_count': {{ postgres_keepalives_count }},
|
||||
{% else %}
|
||||
'keepalives': 0,
|
||||
'keepalives': 0,
|
||||
{% endif %}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ spec:
|
||||
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/component: 'database'
|
||||
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
|
||||
spec:
|
||||
{% if image_pull_secret is defined %}
|
||||
imagePullSecrets:
|
||||
@@ -51,6 +51,10 @@ spec:
|
||||
- image: '{{ _postgres_image }}'
|
||||
imagePullPolicy: '{{ image_pull_policy }}'
|
||||
name: postgres
|
||||
{% if postgres_security_context_settings|length %}
|
||||
securityContext:
|
||||
{{ postgres_security_context_settings | to_nice_yaml | indent(12) }}
|
||||
{% endif %}
|
||||
{% if postgres_extra_args %}
|
||||
args: {{ postgres_extra_args }}
|
||||
{% endif %}
|
||||
@@ -108,6 +112,9 @@ spec:
|
||||
- name: postgres-{{ supported_pg_version }}
|
||||
mountPath: '{{ postgres_data_path | dirname }}'
|
||||
subPath: '{{ postgres_data_path | dirname | basename }}'
|
||||
{% if postgres_extra_volume_mounts -%}
|
||||
{{ postgres_extra_volume_mounts | indent(width=12, first=True) }}
|
||||
{% endif %}
|
||||
resources: {{ postgres_resource_requirements }}
|
||||
{% if postgres_selector %}
|
||||
nodeSelector:
|
||||
@@ -116,6 +123,10 @@ spec:
|
||||
{% if postgres_tolerations %}
|
||||
tolerations:
|
||||
{{ postgres_tolerations | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if postgres_extra_volumes %}
|
||||
volumes:
|
||||
{{ postgres_extra_volumes | indent(width=8, first=False) }}
|
||||
{% endif %}
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
@@ -126,7 +137,15 @@ spec:
|
||||
{% if postgres_storage_class is defined %}
|
||||
storageClassName: '{{ postgres_storage_class }}'
|
||||
{% endif %}
|
||||
resources: {{ postgres_storage_requirements }}
|
||||
resources:
|
||||
{% if postgres_storage_requirements.limits.storage | default("", true) %}
|
||||
limits:
|
||||
storage: {{ postgres_storage_requirements.limits.storage }}
|
||||
{% endif %}
|
||||
{% if postgres_storage_requirements.requests.storage | default("", true) %}
|
||||
requests:
|
||||
storage: {{ postgres_storage_requirements.requests.storage }}
|
||||
{% endif %}
|
||||
|
||||
# Postgres Service.
|
||||
---
|
||||
|
||||
15
roles/mesh_ingress/defaults/main.yml
Normal file
15
roles/mesh_ingress/defaults/main.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
deployment_type: awx
|
||||
|
||||
ingress_type: none
|
||||
ingress_api_version: 'networking.k8s.io/v1'
|
||||
ingress_annotations: ''
|
||||
ingress_class_name: ''
|
||||
ingress_controller: ''
|
||||
|
||||
set_self_owneref: true
|
||||
|
||||
_control_plane_ee_image: quay.io/ansible/awx-ee:latest
|
||||
_image_pull_policy: Always
|
||||
|
||||
finalizer_run: false
|
||||
150
roles/mesh_ingress/tasks/creation.yml
Normal file
150
roles/mesh_ingress/tasks/creation.yml
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
- name: Import common role
|
||||
import_role:
|
||||
name: common
|
||||
|
||||
- name: Debug is_openshift
|
||||
debug:
|
||||
msg: "is_openshift={{ is_openshift }}"
|
||||
|
||||
- name: Check for presence of AWX instance that we will use to create the Mesh Ingress for.
|
||||
k8s_info:
|
||||
api_version: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
name: "{{ deployment_name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
register: awx_instance
|
||||
|
||||
- name: Fail if awx_deployment does not exist in the same namespace
|
||||
fail:
|
||||
msg: "AWX instance {{ deployment_name }} does not exist in the same namespace as the AWXMeshIngress instance."
|
||||
when: awx_instance.resources | length == 0
|
||||
|
||||
- name: Set awx_spec
|
||||
set_fact:
|
||||
awx_spec: "{{ awx_instance.resources[0].spec }}"
|
||||
|
||||
- name: Set owner_reference of AWXMeshIngress to related AWX instance
|
||||
k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
name: "{{ deployment_name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
metadata:
|
||||
name: "{{ deployment_name }}"
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
ownerReferences:
|
||||
- apiVersion: awx.ansible.com/v1beta1
|
||||
blockOwnerDeletion: true
|
||||
controller: true
|
||||
kind: AWX
|
||||
name: "{{ deployment_name }}"
|
||||
uid: "{{ awx_instance.resources[0].metadata.uid }}"
|
||||
when: set_self_owneref | bool
|
||||
|
||||
- name: Set user provided control plane ee image
|
||||
set_fact:
|
||||
_custom_control_plane_ee_image: "{{ awx_spec.control_plane_ee_image }}"
|
||||
when:
|
||||
- awx_spec.control_plane_ee_image | default([]) | length
|
||||
|
||||
- name: Set Control Plane EE image URL
|
||||
set_fact:
|
||||
_control_plane_ee_image: "{{ _custom_control_plane_ee_image | default(lookup('env', 'RELATED_IMAGE_CONTROL_PLANE_EE')) | default(_control_plane_ee_image, true) }}"
|
||||
|
||||
- name: Set Image Pull Policy
|
||||
set_fact:
|
||||
_image_pull_policy: "{{ awx_spec.image_pull_policy | default(_image_pull_policy, true) }}"
|
||||
|
||||
- name: Default ingress_type to Route if OpenShift
|
||||
set_fact:
|
||||
ingress_type: route
|
||||
when: is_openshift | bool and ingress_type | lower == 'none'
|
||||
|
||||
- name: Apply Ingress resource
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'ingress.yml.j2') }}"
|
||||
wait: yes
|
||||
wait_timeout: "120"
|
||||
register: ingress
|
||||
|
||||
# TODO: need to wait until the route is ready before we can get the hostname
|
||||
# right now this will rereconcile until the route is ready
|
||||
|
||||
- name: Set external_hostname
|
||||
set_fact:
|
||||
external_hostname: "{{ ingress.result.status.ingress[0].host }}"
|
||||
when: ingress_type | lower == 'route'
|
||||
|
||||
- name: Create other resources
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', '{{ item }}.yml.j2') }}"
|
||||
wait: yes
|
||||
wait_timeout: "120"
|
||||
loop:
|
||||
- service_account
|
||||
- receptor_conf.configmap
|
||||
- service
|
||||
- deployment
|
||||
|
||||
- name: Get the current resource task pod information.
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
kind: Pod
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
label_selectors:
|
||||
- "app.kubernetes.io/name={{ deployment_name }}-task"
|
||||
- "app.kubernetes.io/managed-by={{ deployment_type }}-operator"
|
||||
- "app.kubernetes.io/component={{ deployment_type }}"
|
||||
field_selectors:
|
||||
- status.phase=Running
|
||||
register: awx_task_pod
|
||||
|
||||
- name: Set the resource pod as a variable.
|
||||
set_fact:
|
||||
awx_task_pod: >-
|
||||
{{ awx_task_pod['resources']
|
||||
| rejectattr('metadata.deletionTimestamp', 'defined')
|
||||
| sort(attribute='metadata.creationTimestamp')
|
||||
| first | default({}) }}
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
awx_task_pod_name: "{{ awx_task_pod['metadata']['name'] | default('') }}"
|
||||
|
||||
- name: Add new instance to AWX
|
||||
kubernetes.core.k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ awx_task_pod_name }}"
|
||||
container: "{{ deployment_name }}-task"
|
||||
command: |
|
||||
awx-manage provision_instance
|
||||
--hostname {{ ansible_operator_meta.name }}
|
||||
--node_type hop
|
||||
|
||||
- name: Add internal receptor address
|
||||
kubernetes.core.k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ awx_task_pod_name }}"
|
||||
container: "{{ deployment_name }}-task"
|
||||
command: |
|
||||
awx-manage add_receptor_address
|
||||
--instance {{ ansible_operator_meta.name }}
|
||||
--address {{ ansible_operator_meta.name }}
|
||||
--port 27199 --protocol ws
|
||||
--peers_from_control_nodes --is_internal --canonical
|
||||
|
||||
- name: Add external receptor address
|
||||
kubernetes.core.k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ awx_task_pod_name }}"
|
||||
container: "{{ deployment_name }}-task"
|
||||
command: |
|
||||
awx-manage add_receptor_address
|
||||
--instance {{ ansible_operator_meta.name }}
|
||||
--address {{ external_hostname }}
|
||||
--port 443 --protocol ws
|
||||
33
roles/mesh_ingress/tasks/finalizer.yml
Normal file
33
roles/mesh_ingress/tasks/finalizer.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
- name: Get the current resource task pod information.
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
kind: Pod
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
label_selectors:
|
||||
- "app.kubernetes.io/name={{ deployment_name }}-task"
|
||||
- "app.kubernetes.io/managed-by={{ deployment_type }}-operator"
|
||||
- "app.kubernetes.io/component={{ deployment_type }}"
|
||||
field_selectors:
|
||||
- status.phase=Running
|
||||
register: awx_task_pod
|
||||
|
||||
- name: Set the resource pod as a variable.
|
||||
set_fact:
|
||||
awx_task_pod: >-
|
||||
{{ awx_task_pod['resources']
|
||||
| rejectattr('metadata.deletionTimestamp', 'defined')
|
||||
| sort(attribute='metadata.creationTimestamp')
|
||||
| first | default({}) }}
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
awx_task_pod_name: "{{ awx_task_pod['metadata']['name'] | default('') }}"
|
||||
|
||||
- name: Deprovision mesh ingress instance in AWX
|
||||
kubernetes.core.k8s_exec:
|
||||
namespace: "{{ ansible_operator_meta.namespace }}"
|
||||
pod: "{{ awx_task_pod_name }}"
|
||||
container: "{{ deployment_name }}-task"
|
||||
command: "awx-manage deprovision_instance --hostname {{ ansible_operator_meta.name }}"
|
||||
register: result
|
||||
12
roles/mesh_ingress/tasks/main.yml
Normal file
12
roles/mesh_ingress/tasks/main.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Lowercase the ingress_type
|
||||
set_fact:
|
||||
ingress_type: "{{ ingress_type | lower }}"
|
||||
|
||||
- name: Run creation tasks
|
||||
include_tasks: creation.yml
|
||||
when: not finalizer_run
|
||||
|
||||
- name: Run finalizer tasks
|
||||
include_tasks: finalizer.yml
|
||||
when: finalizer_run
|
||||
78
roles/mesh_ingress/templates/deployment.yml.j2
Normal file
78
roles/mesh_ingress/templates/deployment.yml.j2
Normal file
@@ -0,0 +1,78 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ ansible_operator_meta.name }}
|
||||
namespace: {{ ansible_operator_meta.namespace }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ ansible_operator_meta.name }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ ansible_operator_meta.name }}
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
internal_hostname={{ ansible_operator_meta.name }}
|
||||
{% if external_hostname is defined %}
|
||||
external_hostname={{ external_hostname }}
|
||||
{% endif %}
|
||||
{% if external_ipaddress is defined %}
|
||||
external_ipaddress={{ external_ipaddress }}
|
||||
{% endif %}
|
||||
receptor --cert-makereq bits=2048 \
|
||||
commonname=$internal_hostname \
|
||||
dnsname=$internal_hostname \
|
||||
nodeid=$internal_hostname \
|
||||
{% if external_hostname is defined %}
|
||||
dnsname=$external_hostname \
|
||||
{% endif %}
|
||||
{% if external_ipaddress is defined %}
|
||||
ipaddress=$external_ipaddress \
|
||||
{% endif %}
|
||||
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/mesh-CA.crt \
|
||||
cakey=/etc/receptor/tls/ca/mesh-CA.key \
|
||||
outcert=/etc/receptor/tls/receptor.crt \
|
||||
verify=yes
|
||||
exec receptor --config /etc/receptor/receptor.conf
|
||||
image: '{{ _control_plane_ee_image }}'
|
||||
imagePullPolicy: '{{ _image_pull_policy }}'
|
||||
name: {{ ansible_operator_meta.name }}-mesh-ingress
|
||||
volumeMounts:
|
||||
- mountPath: /etc/receptor/receptor.conf
|
||||
name: {{ ansible_operator_meta.name }}-receptor-config
|
||||
subPath: receptor.conf
|
||||
- mountPath: /etc/receptor/tls/ca/mesh-CA.crt
|
||||
name: {{ ansible_operator_meta.name }}-receptor-ca
|
||||
readOnly: true
|
||||
subPath: tls.crt
|
||||
- mountPath: /etc/receptor/tls/ca/mesh-CA.key
|
||||
name: {{ ansible_operator_meta.name }}-receptor-ca
|
||||
readOnly: true
|
||||
subPath: tls.key
|
||||
- mountPath: /etc/receptor/tls/
|
||||
name: {{ ansible_operator_meta.name }}-receptor-tls
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
serviceAccount: {{ ansible_operator_meta.name }}
|
||||
volumes:
|
||||
- name: {{ ansible_operator_meta.name }}-receptor-tls
|
||||
- name: {{ ansible_operator_meta.name }}-receptor-ca
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: {{ deployment_name }}-receptor-ca
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
items:
|
||||
- key: receptor_conf
|
||||
path: receptor.conf
|
||||
name: {{ ansible_operator_meta.name }}-receptor-config
|
||||
name: {{ ansible_operator_meta.name }}-receptor-config
|
||||
83
roles/mesh_ingress/templates/ingress.yml.j2
Normal file
83
roles/mesh_ingress/templates/ingress.yml.j2
Normal file
@@ -0,0 +1,83 @@
|
||||
{% if ingress_type|lower == "ingress" %}
|
||||
---
|
||||
{% if ingress_api_version is defined %}
|
||||
apiVersion: '{{ ingress_api_version }}'
|
||||
{% endif %}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ ansible_operator_meta.name }}
|
||||
namespace: {{ ansible_operator_meta.namespace }}
|
||||
annotations:
|
||||
{% if ingress_annotations %}
|
||||
{{ ingress_annotations | indent(width=4) }}
|
||||
{% endif %}
|
||||
{% if ingress_controller|lower == "nginx" %}
|
||||
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
|
||||
{% endif %}
|
||||
spec:
|
||||
{% if ingress_class_name %}
|
||||
ingressClassName: '{{ ingress_class_name }}'
|
||||
{% endif %}
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ ansible_operator_meta.name }}
|
||||
port:
|
||||
number: 27199
|
||||
{% if external_hostname %}
|
||||
host: {{ external_hostname }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if ingress_type|lower == "ingressroutetcp" %}
|
||||
---
|
||||
{% if ingress_api_version is defined %}
|
||||
apiVersion: '{{ ingress_api_version }}'
|
||||
{% endif %}
|
||||
kind: IngressRouteTCP
|
||||
metadata:
|
||||
name: {{ ansible_operator_meta.name }}
|
||||
namespace: {{ ansible_operator_meta.namespace }}
|
||||
annotations:
|
||||
{% if ingress_annotations %}
|
||||
{{ ingress_annotations | indent(width=4) }}
|
||||
{% endif %}
|
||||
spec:
|
||||
entryPoints:
|
||||
- websecure
|
||||
routes:
|
||||
- services:
|
||||
- name: {{ ansible_operator_meta.name }}
|
||||
port: 27199
|
||||
{% if external_hostname %}
|
||||
match: HostSNI(`{{ external_hostname }}`)
|
||||
{% endif %}
|
||||
tls:
|
||||
passthrough: true
|
||||
{% endif %}
|
||||
|
||||
{% if ingress_type|lower == "route" %}
|
||||
---
|
||||
apiVersion: route.openshift.io/v1
|
||||
kind: Route
|
||||
metadata:
|
||||
annotations:
|
||||
openshift.io/host.generated: "true"
|
||||
name: {{ ansible_operator_meta.name }}
|
||||
namespace: {{ ansible_operator_meta.namespace }}
|
||||
spec:
|
||||
port:
|
||||
targetPort: ws
|
||||
tls:
|
||||
insecureEdgeTerminationPolicy: None
|
||||
termination: passthrough
|
||||
to:
|
||||
kind: Service
|
||||
name: {{ ansible_operator_meta.name }}
|
||||
weight: 100
|
||||
wildcardPolicy: None
|
||||
{% endif %}
|
||||
24
roles/mesh_ingress/templates/receptor_conf.configmap.yml.j2
Normal file
24
roles/mesh_ingress/templates/receptor_conf.configmap.yml.j2
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ ansible_operator_meta.name }}-receptor-config
|
||||
namespace: {{ ansible_operator_meta.namespace }}
|
||||
data:
|
||||
receptor_conf: |
|
||||
---
|
||||
- node:
|
||||
id: {{ ansible_operator_meta.name }}
|
||||
- log-level: debug
|
||||
- control-service:
|
||||
service: control
|
||||
- ws-listener:
|
||||
port: 27199
|
||||
tls: tlsserver
|
||||
- tls-server:
|
||||
cert: /etc/receptor/tls/receptor.crt
|
||||
key: /etc/receptor/tls/receptor.key
|
||||
name: tlsserver
|
||||
clientcas: /etc/receptor/tls/ca/mesh-CA.crt
|
||||
requireclientcert: true
|
||||
mintls13: false
|
||||
14
roles/mesh_ingress/templates/service.yml.j2
Normal file
14
roles/mesh_ingress/templates/service.yml.j2
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ ansible_operator_meta.name }}
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: ws
|
||||
port: 27199
|
||||
targetPort: 27199
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ ansible_operator_meta.name }}
|
||||
6
roles/mesh_ingress/templates/service_account.yml.j2
Normal file
6
roles/mesh_ingress/templates/service_account.yml.j2
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: '{{ ansible_operator_meta.name }}'
|
||||
namespace: '{{ ansible_operator_meta.namespace }}'
|
||||
@@ -34,7 +34,7 @@
|
||||
backup_pvc: "{{ this_backup['resources'][0]['status']['backupClaim'] }}"
|
||||
backup_dir: "{{ this_backup['resources'][0]['status']['backupDirectory'] }}"
|
||||
when:
|
||||
- backup_name != '' or backup_name is defined
|
||||
- backup_name is defined and backup_name != ''
|
||||
|
||||
# Check to make sure provided pvc exists, error loudly if not. Otherwise, the management pod will just stay in pending state forever.
|
||||
- name: Check provided PVC exists
|
||||
|
||||
@@ -82,6 +82,35 @@
|
||||
-p {{ awx_postgres_port }}
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Force drop and create database if force_drop_db is true
|
||||
block:
|
||||
- name: Set drop db command
|
||||
set_fact:
|
||||
pg_drop_db: >-
|
||||
echo 'DROP DATABASE {{ awx_postgres_database }} WITH (FORCE);' | PGPASSWORD='{{ awx_postgres_pass }}' psql
|
||||
-U {{ awx_postgres_user }}
|
||||
-h {{ resolvable_db_host }}
|
||||
-d postgres
|
||||
-p {{ awx_postgres_port }} ;
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set create db command
|
||||
set_fact:
|
||||
pg_create_db: >-
|
||||
echo 'CREATE DATABASE {{ awx_postgres_database }} WITH OWNER = {{ awx_postgres_user }};' | PGPASSWORD='{{ awx_postgres_pass }}' psql
|
||||
-U {{ awx_postgres_user }}
|
||||
-h {{ resolvable_db_host }}
|
||||
-d postgres
|
||||
-p {{ awx_postgres_port }} ;
|
||||
no_log: "{{ no_log }}"
|
||||
|
||||
- name: Set complete pg restore command
|
||||
set_fact:
|
||||
pg_drop_create: >-
|
||||
{{ pg_drop_db }}
|
||||
{{ pg_create_db }}
|
||||
when: force_drop_db
|
||||
|
||||
- name: Restore database dump to the new postgresql container
|
||||
k8s_exec:
|
||||
namespace: "{{ backup_pvc_namespace }}"
|
||||
@@ -104,10 +133,11 @@
|
||||
trap 'end_keepalive \"$keepalive_file\" \"$keepalive_pid\"' EXIT SIGINT SIGTERM
|
||||
echo keepalive_pid: $keepalive_pid
|
||||
set -e -o pipefail
|
||||
{{ pg_drop_create }}
|
||||
cat {{ backup_dir }}/tower.db | PGPASSWORD='{{ awx_postgres_pass }}' {{ pg_restore }}
|
||||
PG_RC=$?
|
||||
set +e +o pipefail
|
||||
echo 'Successful'
|
||||
exit $PG_RC
|
||||
"
|
||||
register: data_migration
|
||||
no_log: "{{ no_log }}"
|
||||
failed_when: "'Successful' not in data_migration.stdout"
|
||||
|
||||
@@ -14,3 +14,7 @@ broadcast_websocket_secret: '{{ deployment_name }}-broadcast-websocket'
|
||||
postgres_configuration_secret: '{{ deployment_name }}-postgres-configuration'
|
||||
supported_pg_version: 13
|
||||
image_pull_policy: IfNotPresent
|
||||
|
||||
# If set to true, the restore process will delete the existing database and create a new one
|
||||
force_drop_db: false
|
||||
pg_drop_create: ''
|
||||
|
||||
11
watches.yaml
11
watches.yaml
@@ -22,4 +22,15 @@
|
||||
kind: AWXRestore
|
||||
role: restore
|
||||
snakeCaseParameters: False
|
||||
|
||||
- version: v1alpha1
|
||||
group: awx.ansible.com
|
||||
kind: AWXMeshIngress
|
||||
role: mesh_ingress
|
||||
snakeCaseParameters: False
|
||||
finalizer:
|
||||
name: awx.ansible.com/awx-mesh-ingress-finalizer
|
||||
role: mesh_ingress
|
||||
vars:
|
||||
finalizer_run: true
|
||||
# +kubebuilder:scaffold:watch
|
||||
|
||||
Reference in New Issue
Block a user