mirror of
https://github.com/ansible/awx-operator.git
synced 2026-03-27 05:43:11 +00:00
Compare commits
193 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8b7ed81b5 | ||
|
|
f4980917d2 | ||
|
|
1c9173f48a | ||
|
|
f6b7a32a33 | ||
|
|
aa03a7f268 | ||
|
|
136b2c47f8 | ||
|
|
0043c375d8 | ||
|
|
c44c3fb095 | ||
|
|
cb70e97366 | ||
|
|
1d21dc7f20 | ||
|
|
4d4ed3e827 | ||
|
|
0eb4286b71 | ||
|
|
f73cff3cb3 | ||
|
|
54c8a7beef | ||
|
|
584d45d315 | ||
|
|
43aa01ce5f | ||
|
|
a0c6565e59 | ||
|
|
bac795a36a | ||
|
|
c9acc30009 | ||
|
|
0cf0fd52c7 | ||
|
|
2b8530b3e2 | ||
|
|
550756c33c | ||
|
|
4230120884 | ||
|
|
90b88676c5 | ||
|
|
862123e2d6 | ||
|
|
c1a2f6e649 | ||
|
|
c0d3047dab | ||
|
|
1a50cd339e | ||
|
|
30db53d250 | ||
|
|
1309cc63c9 | ||
|
|
32b862c79b | ||
|
|
e09a468d2c | ||
|
|
adb896f294 | ||
|
|
2fd3158c7b | ||
|
|
ba2672a0b0 | ||
|
|
7c02a9728a | ||
|
|
9b327f6ad5 | ||
|
|
2a3f700fde | ||
|
|
d221c64f62 | ||
|
|
0f1cc494fe | ||
|
|
be68adbf01 | ||
|
|
185238c199 | ||
|
|
210ac2c419 | ||
|
|
658cf92a3b | ||
|
|
d3f7594aea | ||
|
|
939dd0b295 | ||
|
|
51e384292c | ||
|
|
f27f1d188c | ||
|
|
8974e3446a | ||
|
|
57a408e384 | ||
|
|
1fa391a9f1 | ||
|
|
7885f8e454 | ||
|
|
32ac0941dc | ||
|
|
371d826dd4 | ||
|
|
aeebe6cc4b | ||
|
|
257a3ba807 | ||
|
|
ecdfaf6c0d | ||
|
|
bc28071205 | ||
|
|
8962d501b3 | ||
|
|
e91031fa73 | ||
|
|
cb2a059e16 | ||
|
|
5e5c7bbdaf | ||
|
|
8b241e7871 | ||
|
|
0740fc2bc1 | ||
|
|
a3cf6c4ea8 | ||
|
|
697ff11fa7 | ||
|
|
0d6980b9b4 | ||
|
|
387932e960 | ||
|
|
79e62755b8 | ||
|
|
746dc2738f | ||
|
|
7e67838adb | ||
|
|
7010ab1fc6 | ||
|
|
4eb4abf4f5 | ||
|
|
451e2b6497 | ||
|
|
60479971b8 | ||
|
|
76092c366e | ||
|
|
e09c48d67c | ||
|
|
556cb23a14 | ||
|
|
62ec946e4f | ||
|
|
693ce5a17e | ||
|
|
385a4f65a1 | ||
|
|
3df272da27 | ||
|
|
60199f79aa | ||
|
|
d713dce7e0 | ||
|
|
b00de51fb9 | ||
|
|
c81266af66 | ||
|
|
c320dc835b | ||
|
|
f47604998e | ||
|
|
7d6743c44d | ||
|
|
bb519664cd | ||
|
|
92a7bf22a1 | ||
|
|
851ff16c0f | ||
|
|
79534a1465 | ||
|
|
64c10f29c4 | ||
|
|
94a4861d13 | ||
|
|
da26472a03 | ||
|
|
76acd335b9 | ||
|
|
1570c0a883 | ||
|
|
c22577bc80 | ||
|
|
a65834dbf3 | ||
|
|
e990c6bed2 | ||
|
|
4297b158dc | ||
|
|
f099b15ff8 | ||
|
|
add62c2973 | ||
|
|
084e0b38a8 | ||
|
|
c6c94ce48d | ||
|
|
781d3e0ec7 | ||
|
|
1cd93c6752 | ||
|
|
e83e54419a | ||
|
|
5b89c5c433 | ||
|
|
0e1b12f4b1 | ||
|
|
93d53c712c | ||
|
|
6a5bdaf2f7 | ||
|
|
6cc3c47e33 | ||
|
|
1beae86c1d | ||
|
|
7a559b9f3b | ||
|
|
cc3a752550 | ||
|
|
7442555869 | ||
|
|
10566b46b1 | ||
|
|
d32cf447ea | ||
|
|
07dda4c8ef | ||
|
|
a860b0f459 | ||
|
|
9683dc23a4 | ||
|
|
e4fd5aeb32 | ||
|
|
b1788be272 | ||
|
|
92efe37100 | ||
|
|
21f284fb49 | ||
|
|
d53245b984 | ||
|
|
9595c6c008 | ||
|
|
9545acd301 | ||
|
|
1ff4d8f6c9 | ||
|
|
d839088521 | ||
|
|
32a53f3747 | ||
|
|
70690ccd50 | ||
|
|
c579537d66 | ||
|
|
e589a999a8 | ||
|
|
53f3f07645 | ||
|
|
b8d12d93fb | ||
|
|
5f60f6d004 | ||
|
|
87a6db538a | ||
|
|
733d739124 | ||
|
|
c7abc4b8d6 | ||
|
|
9271cd464e | ||
|
|
f04017ca95 | ||
|
|
5690fa7cc1 | ||
|
|
a44cfb676d | ||
|
|
d3e7c308c4 | ||
|
|
53fd88a4e1 | ||
|
|
3b9b4225ae | ||
|
|
1a58392804 | ||
|
|
78eab6873e | ||
|
|
25fc21a6cd | ||
|
|
a39b914963 | ||
|
|
a4ee609a76 | ||
|
|
fbae5cf590 | ||
|
|
6f965c9180 | ||
|
|
4e8308c90d | ||
|
|
e5e996569c | ||
|
|
fd4e3b2d4c | ||
|
|
025dfa54df | ||
|
|
1fe7c4dd20 | ||
|
|
b5536ffd80 | ||
|
|
c895ca0f6d | ||
|
|
121c034e6c | ||
|
|
452bb128c6 | ||
|
|
821198c05e | ||
|
|
8049dfac9c | ||
|
|
8481390bac | ||
|
|
0eab2f9686 | ||
|
|
72fd95994b | ||
|
|
e858f34f2c | ||
|
|
90bfe5073b | ||
|
|
dfb96d1e18 | ||
|
|
5cf9f72f60 | ||
|
|
e5f1041350 | ||
|
|
f5ac42dfe2 | ||
|
|
0149afcd9e | ||
|
|
5efd45570e | ||
|
|
357e8ad2c9 | ||
|
|
c5cd12e662 | ||
|
|
ad476e4782 | ||
|
|
3a2d3d889a | ||
|
|
285be0faff | ||
|
|
38c57a61d0 | ||
|
|
7837db6e53 | ||
|
|
2daae08790 | ||
|
|
c378e0da9f | ||
|
|
470870526b | ||
|
|
ae7aae4048 | ||
|
|
90023b8d75 | ||
|
|
9189333611 | ||
|
|
4e11d45386 | ||
|
|
9c53c4067e |
@@ -1,3 +1,4 @@
|
||||
---
|
||||
skip_list:
|
||||
- '306'
|
||||
- '602'
|
||||
@@ -5,3 +6,4 @@ skip_list:
|
||||
|
||||
exclude_paths:
|
||||
- deploy/
|
||||
- .cache/
|
||||
|
||||
44
.github/workflows/ci.yaml
vendored
Normal file
44
.github/workflows/ci.yaml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [devel]
|
||||
|
||||
push:
|
||||
branches: [devel]
|
||||
|
||||
jobs:
|
||||
pull_request:
|
||||
runs-on: ubuntu-18.04
|
||||
name: pull_request
|
||||
env:
|
||||
DOCKER_API_VERSION: "1.38"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.8"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
pip install \
|
||||
molecule \
|
||||
molecule-docker \
|
||||
yamllint \
|
||||
ansible-lint \
|
||||
openshift \
|
||||
jmespath \
|
||||
ansible
|
||||
|
||||
- name: Install Collections
|
||||
run: |
|
||||
ansible-galaxy collection install community.kubernetes operator_sdk.util
|
||||
|
||||
- name: Run Molecule
|
||||
env:
|
||||
MOLECULE_VERBOSITY: 3
|
||||
run: |
|
||||
molecule test -s test-local
|
||||
34
.github/workflows/release.yaml
vendored
Normal file
34
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [devel]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-18.04
|
||||
name: release
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install Operator-SDK
|
||||
run: |
|
||||
mkdir -p $GITHUB_WORKSPACE/bin
|
||||
wget -O $GITHUB_WORKSPACE/bin/operator-sdk https://github.com/operator-framework/operator-sdk/releases/download/v0.19.4/operator-sdk-v0.19.4-x86_64-linux-gnu
|
||||
chmod +x $GITHUB_WORKSPACE/bin/operator-sdk
|
||||
echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Build Image
|
||||
run: |
|
||||
operator-sdk build awx-operator:devel
|
||||
|
||||
- name: Push To Quay
|
||||
uses: redhat-actions/push-to-registry@v2.1.1
|
||||
with:
|
||||
image: awx-operator
|
||||
tags: devel
|
||||
registry: quay.io/ansible/
|
||||
username: ${{ secrets.QUAY_USERNAME }}
|
||||
password: ${{ secrets.QUAY_TOKEN }}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
*~
|
||||
.cache/
|
||||
|
||||
19
.travis.yml
19
.travis.yml
@@ -1,19 +0,0 @@
|
||||
---
|
||||
services: docker
|
||||
language: python
|
||||
|
||||
before_install:
|
||||
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
|
||||
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||
|
||||
env:
|
||||
- DOCKER_API_VERSION=1.38
|
||||
|
||||
install:
|
||||
- pip3 install docker molecule molecule-docker yamllint ansible-lint openshift jmespath
|
||||
- ansible-galaxy collection install community.kubernetes
|
||||
|
||||
script:
|
||||
- molecule test -s test-local
|
||||
@@ -1,7 +1,12 @@
|
||||
---
|
||||
extends: default
|
||||
|
||||
ignore: |
|
||||
.cache/
|
||||
deploy/olm-catalog
|
||||
|
||||
rules:
|
||||
truthy: disable
|
||||
line-length:
|
||||
max: 160
|
||||
max: 170
|
||||
level: warning
|
||||
|
||||
201
LICENSE
Normal file
201
LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
543
README.md
543
README.md
@@ -1,127 +1,403 @@
|
||||
# AWX Operator
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0) [](https://github.com/ansible/awx-operator/actions)
|
||||
|
||||
An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built with [Operator SDK](https://github.com/operator-framework/operator-sdk) and Ansible.
|
||||
|
||||
# Table of Contents
|
||||
|
||||
<!--ts-->
|
||||
* [AWX Operator](#awx-operator)
|
||||
* [Table of Contents](#table-of-contents)
|
||||
* [Purpose](#purpose)
|
||||
* [Usage](#usage)
|
||||
* [Basic Install](#basic-install)
|
||||
* [Admin user account configuration](#admin-user-account-configuration)
|
||||
* [Network and TLS Configuration](#network-and-tls-configuration)
|
||||
* [Ingress Type](#ingress-type)
|
||||
* [TLS Termination](#tls-termination)
|
||||
* [Database Configuration](#database-configuration)
|
||||
* [External PostgreSQL Service](#external-postgresql-service)
|
||||
* [Migrating data from an old AWX instance](#migrating-data-from-an-old-awx-instance)
|
||||
* [Managed PostgreSQL Service](#managed-postgresql-service)
|
||||
* [Advanced Configuration](#advanced-configuration)
|
||||
* [Deploying a specific version of AWX](#deploying-a-specific-version-of-awx)
|
||||
* [Privileged Tasks](#privileged-tasks)
|
||||
* [Containers Resource Requirements](#containers-resource-requirements)
|
||||
* [LDAP Certificate Authority](#ldap-certificate-authority)
|
||||
* [Persisting Projects Directory](#persisting-projects-directory)
|
||||
* [Development](#development)
|
||||
* [Testing](#testing)
|
||||
* [Testing in Docker](#testing-in-docker)
|
||||
* [Testing in Minikube](#testing-in-minikube)
|
||||
* [Generating a bundle](#generating-a-bundle)
|
||||
* [Release Process](#release-process)
|
||||
* [Build a new release](#build-a-new-release)
|
||||
* [Build a new version of the operator yaml file](#build-a-new-version-of-the-operator-yaml-file)
|
||||
* [Author](#author)
|
||||
<!--te-->
|
||||
|
||||
## Purpose
|
||||
|
||||
This operator is meant to provide a more Kubernetes-native installation method for AWX via an AWX Custom Resource Definition (CRD).
|
||||
|
||||
Note that the operator is not supported by Red Hat, and is in alpha status. For now, use it at your own risk!
|
||||
Note that the operator is not supported by Red Hat, and is in **alpha** status. For now, use it at your own risk!
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Install
|
||||
|
||||
This Kubernetes Operator is meant to be deployed in your Kubernetes cluster(s) and can manage one or more AWX instances in any namespace.
|
||||
|
||||
First you need to deploy AWX Operator into your cluster:
|
||||
|
||||
kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml
|
||||
```bash
|
||||
#> kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml
|
||||
```
|
||||
|
||||
Then you can create instances of AWX, for example:
|
||||
|
||||
1. Make sure the namespace you're deploying into already exists (e.g. `kubectl create namespace ansible-awx`).
|
||||
2. Create a file named `my-awx.yml` with the following contents:
|
||||
|
||||
```
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx
|
||||
namespace: ansible-awx
|
||||
spec:
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
```
|
||||
|
||||
3. Use `kubectl` to create the awx instance in your cluster:
|
||||
|
||||
```
|
||||
kubectl apply -f my-awx.yml
|
||||
```
|
||||
|
||||
After a few minutes, your new AWX instance will be accessible at `http://awx.mycompany.com/` (assuming your cluster has an Ingress controller configured). Log in using the `tower_admin_` credentials configured in the `spec`.
|
||||
|
||||
|
||||
### Deploying a specific version of AWX
|
||||
|
||||
To achieve this, please add the following variable under spec within your CR (Custom Resource) file:
|
||||
Then create a file named `my-awx.yml` with the following contents:
|
||||
|
||||
```yaml
|
||||
tower_image: ansible/awx:15.0.0 # replace this with desired image
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx
|
||||
```
|
||||
You may also override any default variables from `roles/awx/defaults/main.yml` using the same process, i.e. by adding those variables within your CR spec.
|
||||
|
||||
### Ingress Types
|
||||
> The metadata.name you provide, will be the name of the resulting AWX deployment. If you deploy more than one to the same namespace, be sure to use unique names.
|
||||
|
||||
Depending on the cluster that you're running on, you may wish to use an `Ingress` to access AWX, or you may wish to use a `Route` to access your AWX. To toggle between these two options, you can add the following to your AWX CR:
|
||||
Finally, use `kubectl` to create the awx instance in your cluster:
|
||||
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_ingress_type: Route
|
||||
```bash
|
||||
#> kubectl apply -f my-awx.yml
|
||||
```
|
||||
|
||||
OR
|
||||
After a few minutes, the new AWX instance will be deployed. One can look at the operator pod logs in order to know where the installation process is at. This can be done by running the following command: `kubectl logs -f deployments/awx-operator`.
|
||||
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_ingress_type: Ingress
|
||||
tower_hostname: awx.mycompany.com
|
||||
Once deployed, the AWX instance will be accessible at `http://awx.mycompany.com/` (assuming your cluster has an Ingress controller configured).
|
||||
|
||||
By default, no ingress/route is deployed as the default is set to `none`.
|
||||
By default, the admin user is `admin` and the password is available in the `<resourcename>-admin-password` secret. To retrieve the admin password, run `kubectl get secret <resourcename>-admin-password -o jsonpath="{.data.password}" | base64 --decode`
|
||||
|
||||
### Privileged Tasks
|
||||
|
||||
You just completed the most basic install of an AWX instance via this operator. Congratulations !
|
||||
|
||||
### Admin user account configuration
|
||||
|
||||
There are three variables that are customizable for the admin user account creation.
|
||||
|
||||
| Name | Description | Default |
|
||||
| --------------------------- | -------------------------------------------- | ---------------- |
|
||||
| tower_admin_user | Name of the admin user | admin |
|
||||
| tower_admin_email | Email of the admin user | test@example.com |
|
||||
| tower_admin_password_secret | Secret that contains the admin user password | Empty string |
|
||||
|
||||
|
||||
> :warning: **tower_admin_password_secret must be a Kubernetes secret and not your text clear password**.
|
||||
|
||||
If `tower_admin_password_secret` is not provided, the operator will look for a secret named `<resourcename>-admin-password` for the admin password. If it is not present, the operator will generate a password and create a Secret from it named `<resourcename>-admin-password`.
|
||||
|
||||
To retrieve the admin password, run `kubectl get secret <resourcename>-admin-password -o jsonpath="{.data.password}" | base64 --decode`
|
||||
|
||||
The secret that is expected to be passed should be formatted as follow:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <resourcename>-admin-password
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
password: mysuperlongpassword
|
||||
```
|
||||
|
||||
|
||||
### Network and TLS Configuration
|
||||
|
||||
#### Ingress Type
|
||||
|
||||
By default, the AWX operator is not opinionated and won't force a specific ingress type on you. So, if `tower_ingress_type` is not specified as part of the Custom Resource specification, it will default to `none` and nothing ingress-wise will be created.
|
||||
|
||||
The AWX operator provides support for three kinds of `Ingress` to access AWX: `Ingress`, `Route` and `LoadBalancer`, To toggle between these options, you can add the following to your AWX CR:
|
||||
|
||||
* Route
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_ingress_type: Route
|
||||
```
|
||||
|
||||
* Ingress
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_ingress_type: Ingress
|
||||
tower_hostname: awx.mycompany.com
|
||||
```
|
||||
|
||||
* LoadBalancer
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_ingress_type: LoadBalancer
|
||||
tower_ingress_protocol: http
|
||||
```
|
||||
|
||||
#### TLS Termination
|
||||
|
||||
* Route
|
||||
|
||||
The following variables are customizable to specify the TLS termination procedure when `Route` is picked as an Ingress
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------------- | --------------------------------------------- | --------------------------------- |
|
||||
| tower_route_host | Common name the route answers for | Empty string |
|
||||
| tower_route_tls_termination_mechanism | TLS Termination mechanism (Edge, Passthrough) | Edge |
|
||||
| tower_route_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
|
||||
* Ingress
|
||||
|
||||
The following variables are customizable to specify the TLS termination procedure when `Ingress` is picked as an Ingress
|
||||
|
||||
| Name | Description | Default |
|
||||
| -------------------------- | ---------------------------------------- | ------------- |
|
||||
| tower_ingress_annotations | Ingress annotations | Empty string |
|
||||
| tower_ingress_tls_secret | Secret that contains the TLS information | Empty string |
|
||||
|
||||
* LoadBalancer
|
||||
|
||||
The following variables are customizable to specify the TLS termination procedure when `LoadBalancer` is picked as an Ingress
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------ | ---------------------------------------- | ------------- |
|
||||
| tower_loadbalancer_annotations | LoadBalancer annotations | Empty string |
|
||||
| tower_loadbalancer_protocol | Protocol to use for Loadbalancer ingress | http |
|
||||
| tower_loadbalancer_port | Port used for Loadbalancer ingress | 80 |
|
||||
|
||||
When setting up a Load Balancer for HTTPS you will be required to set the `tower_loadbalancer_port` to move the port away from `80`.
|
||||
|
||||
The HTTPS Load Balancer also uses SSL termination at the Load Balancer level and will offload traffic to AWX over HTTP.
|
||||
|
||||
### Database Configuration
|
||||
|
||||
#### External PostgreSQL Service
|
||||
|
||||
In order for the AWX instance to rely on an external database, the Custom Resource needs to know about the connection details. Those connection details should be stored as a secret and either specified as `tower_postgres_configuration_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-postgres-configuration`.
|
||||
|
||||
|
||||
The secret should be formatted as follows:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <resourcename>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
host: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
#### Migrating data from an old AWX instance
|
||||
|
||||
For instructions on how to migrate from an older version of AWX, see [migration.md](./docs/migration.md).
|
||||
|
||||
#### Managed PostgreSQL Service
|
||||
|
||||
If you don't have access to an external PostgreSQL service, the AWX operator can deploy one for you along side the AWX instance itself.
|
||||
|
||||
The following variables are customizable for the managed PostgreSQL service
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------------------------ | ------------------------------------------ | --------------------------------- |
|
||||
| tower_postgres_image | Path of the image to pull | postgres:12 |
|
||||
| tower_postgres_resource_requirements | PostgreSQL container resource requirements | requests: {storage: 8Gi} |
|
||||
| tower_postgres_storage_class | PostgreSQL PV storage class | Empty string |
|
||||
| tower_postgres_data_path | PostgreSQL data path | `/var/lib/postgresql/data/pgdata` |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_postgres_resource_requirements:
|
||||
requests:
|
||||
memory: 2Gi
|
||||
storage: 8Gi
|
||||
limits:
|
||||
memory: 4Gi
|
||||
storage: 50Gi
|
||||
tower_postgres_storage_class: fast-ssd
|
||||
```
|
||||
|
||||
**Note**: If `tower_postgres_storage_class` is not defined, Postgres will store it's data on a volume using the default storage class for your cluster.
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
#### Deploying a specific version of AWX
|
||||
|
||||
There are a few variables that are customizable for awx the image management.
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------- | -------------------------- |
|
||||
| tower_image | Path of the image to pull |
|
||||
| tower_image_pull_policy | The pull policy to adopt |
|
||||
| tower_image_pull_secret | The pull secret to use |
|
||||
| tower_ee_images | A list of EEs to register |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_image: myorg/my-custom-awx
|
||||
tower_image_pull_policy: Always
|
||||
tower_image_pull_secret: pull_secret_name
|
||||
tower_ee_images:
|
||||
- name: my-custom-awx-ee
|
||||
image: myorg/my-custom-awx-ee
|
||||
```
|
||||
|
||||
#### Privileged Tasks
|
||||
|
||||
Depending on the type of tasks that you'll be running, you may find that you need the task pod to run as `privileged`. This can open yourself up to a variety of security concerns, so you should be aware (and verify that you have the privileges) to do this if necessary. In order to toggle this feature, you can add the following to your custom resource:
|
||||
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_task_privileged: true
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_task_privileged: true
|
||||
```
|
||||
|
||||
If you are attempting to do this on an OpenShift cluster, you will need to grant the `awx` ServiceAccount the `privileged` SCC, which can be done with:
|
||||
|
||||
oc adm policy add-scc-to-user privileged -z awx
|
||||
```sh
|
||||
#> oc adm policy add-scc-to-user privileged -z awx
|
||||
```
|
||||
|
||||
Again, this is the most relaxed SCC that is provided by OpenShift, so be sure to familiarize yourself with the security concerns that accompany this action.
|
||||
|
||||
### Connecting to an external Postgres Service
|
||||
|
||||
When the Operator installs the AWX services and generates a Postgres deployment it will lay down a config file to enable AWX to connect to that service. To use an external database you just need to create a `Secret` that the AWX deployment will use instead and then set a property in the CR:
|
||||
#### Containers Resource Requirements
|
||||
|
||||
---
|
||||
spec:
|
||||
...
|
||||
external_database: true
|
||||
The resource requirements for both, the task and the web containers are configurable - both the lower end (requests) and the upper end (limits).
|
||||
|
||||
The secret should have the name: *crname*-postgres-configuration and
|
||||
should look like:
|
||||
| Name | Description | Default |
|
||||
| -------------------------------- | ------------------------------------ | ----------------------------------- |
|
||||
| tower_web_resource_requirements | Web container resource requirements | requests: {cpu: 1000m, memory: 2Gi} |
|
||||
| tower_task_resource_requirements | Task container resource requirements | requests: {cpu: 500m, memory: 1Gi} |
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <crname>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
host: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
Example of customization could be:
|
||||
|
||||
### Persistent storage for Postgres
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_web_resource_requirements:
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
tower_task_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
```
|
||||
|
||||
If you need to use a specific storage class for Postgres' storage, specify `tower_postgres_storage_class` in your AWX spec:
|
||||
#### Assigning AWX pods to specific nodes
|
||||
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_postgres_storage_class: fast-ssd
|
||||
You can constrain the AWX pods created by the operator to run on a certain subset of nodes. `tower_node_selector` constrains
|
||||
the AWX pods to run only on the nodes that match all the specified key/value pairs. `tower_tolerations` allow the AWX
|
||||
pods to be scheduled onto nodes with matching taints.
|
||||
|
||||
If it's not specified, Postgres will store it's data on a volume using the default storage class for your cluster.
|
||||
|
||||
| Name | Description | Default |
|
||||
| ------------------- | ---------------------- | ------- |
|
||||
| tower_node_selector | AWX pods' nodeSelector | '' |
|
||||
| tower_tolerations | AWX pods' tolerations | '' |
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_node_selector: |
|
||||
disktype: ssd
|
||||
kubernetes.io/arch: amd64
|
||||
kubernetes.io/os: linux
|
||||
tower_tolerations: |
|
||||
- key: "dedicated"
|
||||
operator: "Equal"
|
||||
value: "AWX"
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
#### LDAP Certificate Authority
|
||||
|
||||
If the variable `ldap_cacert_secret` is provided, the operator will look for a the data field `ldap-ca.crt` in the specified secret.
|
||||
|
||||
| Name | Description | Default |
|
||||
| -------------------------------- | --------------------------------------- | --------|
|
||||
| ldap_cacert_secret | LDAP Certificate Authority secret name | '' |
|
||||
|
||||
|
||||
Example of customization could be:
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
ldap_cacert_secret: <resourcename>-ldap-ca-cert
|
||||
```
|
||||
|
||||
To create the secret, you can use the command below:
|
||||
|
||||
```sh
|
||||
# kubectl create secret generic <resourcename>-ldap-ca-cert --from-file=ldap-ca.crt=<PATH/TO/YOUR/CA/PEM/FILE>
|
||||
```
|
||||
|
||||
#### Persisting Projects Directory
|
||||
|
||||
In cases which you want to persist the `/var/lib/projects` directory, there are few variables that are customizable for the `awx-operator`.
|
||||
|
||||
| Name | Description | Default |
|
||||
| -----------------------------------| ---------------------------------------------------------------------------------------------------- | ---------------|
|
||||
| tower_projects_persistence | Whether or not the /var/lib/projects directory will be persistent | false |
|
||||
| tower_projects_storage_class | Define the PersistentVolume storage class | '' |
|
||||
| tower_projects_storage_size | Define the PersistentVolume size | 8Gi |
|
||||
| tower_projects_storage_access_mode | Define the PersistentVolume access mode | ReadWriteMany |
|
||||
| tower_projects_existing_claim | Define an existing PersistentVolumeClaim to use (cannot be combined with `tower_projects_storage_*`) | '' |
|
||||
|
||||
Example of customization when the `awx-operator` automatically handles the persistent volume could be:
|
||||
|
||||
```yaml
|
||||
---
|
||||
spec:
|
||||
...
|
||||
tower_projects_persistence: true
|
||||
tower_projects_storage_class: rook-ceph
|
||||
tower_projects_storage_size: 20Gi
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
@@ -131,23 +407,29 @@ This Operator includes a [Molecule](https://molecule.readthedocs.io/en/stable/)-
|
||||
|
||||
You need to make sure you have Molecule installed before running the following commands. You can install Molecule with:
|
||||
|
||||
pip install 'molecule[docker]'
|
||||
```sh
|
||||
#> pip install 'molecule[docker]'
|
||||
```
|
||||
|
||||
Running `molecule test` sets up a clean environment, builds the operator, runs all configured tests on an example operator instance, then tears down the environment (at least in the case of Docker).
|
||||
|
||||
If you want to actively develop the operator, use `molecule converge`, which does everything but tear down the environment at the end.
|
||||
|
||||
#### Testing in Docker (standalone)
|
||||
#### Testing in Docker
|
||||
|
||||
molecule test -s test-local
|
||||
```sh
|
||||
#> molecule test -s test-local
|
||||
```
|
||||
|
||||
This environment is meant for headless testing (e.g. in a CI environment, or when making smaller changes which don't need to be verified through a web interface). It is difficult to test things like AWX's web UI or to connect other applications on your local machine to the services running inside the cluster, since it is inside a Docker container with no static IP address.
|
||||
|
||||
#### Testing in Minikube
|
||||
|
||||
minikube start --memory 8g --cpus 4
|
||||
minikube addons enable ingress
|
||||
molecule test -s test-minikube
|
||||
```sh
|
||||
#> minikube start --memory 8g --cpus 4
|
||||
#> minikube addons enable ingress
|
||||
#> molecule test -s test-minikube
|
||||
```
|
||||
|
||||
[Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) is a more full-featured test environment running inside a full VM on your computer, with an assigned IP address. This makes it easier to test things like NodePort services and Ingress from outside the Kubernetes cluster (e.g. in a browser on your computer).
|
||||
|
||||
@@ -157,11 +439,61 @@ Once the operator is deployed, you can visit the AWX UI in your browser by follo
|
||||
2. Visit `http://example-awx.test/` in your browser. (Default admin login is `test`/`changeme`.)
|
||||
|
||||
Alternatively, you can also update the service `awx-service` in your namespace to use the type `NodePort` and use following command to get the URL to access your AWX instance:
|
||||
|
||||
```sh
|
||||
minikube service <serviceName> -n <namespaceName> --url
|
||||
#> minikube service <serviceName> -n <namespaceName> --url
|
||||
```
|
||||
|
||||
### Release Process
|
||||
### Generating a bundle
|
||||
|
||||
> :warning: operator-sdk version 0.19.4 is needed to run the following commands
|
||||
|
||||
If one has the Operator Lifecycle Manager (OLM) installed, the following steps is the process to generate the bundle that would nicely display in the OLM interface.
|
||||
|
||||
At the root of this directory:
|
||||
|
||||
1. Build and publish the operator
|
||||
|
||||
```
|
||||
#> operator-sdk build registry.example.com/ansible/awx-operator:mytag
|
||||
#> podman push registry.example.com/ansible/awx-operator:mytag
|
||||
```
|
||||
|
||||
2. Build and publish the bundle
|
||||
|
||||
```
|
||||
#> podman build . -f bundle.Dockerfile -t registry.example.com/ansible/awx-operator-bundle:mytag
|
||||
#> podman push registry.example.com/ansible/awx-operator-bundle:mytag
|
||||
```
|
||||
|
||||
3. Build and publish an index with your bundle in it
|
||||
|
||||
```
|
||||
#> opm index add --bundles registry.example.com/ansible/awx-operator-bundle:mytag --tag registry.example.com/ansible/awx-operator-catalog:mytag
|
||||
#> podman push registry.example.com/ansible/awx-operator-catalog:mytag
|
||||
```
|
||||
|
||||
4. In your Kubernetes create a new CatalogSource pointing to `registry.example.com/ansible/awx-operator-catalog:mytag`
|
||||
|
||||
```
|
||||
---
|
||||
apiVersion: operators.coreos.com/v1alpha1
|
||||
kind: CatalogSource
|
||||
metadata:
|
||||
name: <catalogsource-name>
|
||||
namespace: <namespace>
|
||||
spec:
|
||||
displayName: 'myoperatorhub'
|
||||
image: registry.example.com/ansible/awx-operator-catalog:mytag
|
||||
publisher: 'myoperatorhub'
|
||||
sourceType: grpc
|
||||
```
|
||||
|
||||
Applying this template will do it. Once the CatalogSource is in a READY state, the bundle should be available on the OperatorHub tab (as part of the custom CatalogSource that just got added)
|
||||
|
||||
5. Enjoy
|
||||
|
||||
## Release Process
|
||||
|
||||
There are a few moving parts to this project:
|
||||
|
||||
@@ -170,17 +502,21 @@ There are a few moving parts to this project:
|
||||
|
||||
Each of these must be appropriately built in preparation for a new tag:
|
||||
|
||||
#### Build a new release of the Operator for Docker Hub
|
||||
### Build a new release
|
||||
|
||||
Run the following command inside this directory:
|
||||
|
||||
operator-sdk build quay.io/ansible/awx-operator:$VERSION
|
||||
```sh
|
||||
#> operator-sdk build quay.io/ansible/awx-operator:$VERSION
|
||||
```
|
||||
|
||||
Then push the generated image to Docker Hub:
|
||||
|
||||
docker push quay.io/ansible/awx-operator:$VERSION
|
||||
```sh
|
||||
#> docker push quay.io/ansible/awx-operator:$VERSION
|
||||
```
|
||||
|
||||
#### Build a new version of the `awx-operator.yaml` file
|
||||
### Build a new version of the operator yaml file
|
||||
|
||||
Update the awx-operator version:
|
||||
|
||||
@@ -188,17 +524,22 @@ Update the awx-operator version:
|
||||
|
||||
Once the version has been updated, run from the root of the repo:
|
||||
|
||||
ansible-playbook ansible/chain-operator-files.yml
|
||||
```sh
|
||||
#> ansible-playbook ansible/chain-operator-files.yml
|
||||
```
|
||||
|
||||
After it is built, test it on a local cluster:
|
||||
|
||||
minikube start --memory 6g --cpus 4
|
||||
minikube addons enable ingress
|
||||
kubectl apply -f deploy/awx-operator.yaml
|
||||
kubectl create namespace example-awx
|
||||
kubectl apply -f deploy/crds/awx_v1beta1_cr.yaml
|
||||
<test everything>
|
||||
minikube delete
|
||||
|
||||
```sh
|
||||
#> minikube start --memory 6g --cpus 4
|
||||
#> minikube addons enable ingress
|
||||
#> ansible-playbook ansible/deploy-operator.yml
|
||||
#> kubectl create namespace example-awx
|
||||
#> ansible-playbook ansible/instantiate-awx-deployment.yml -e tower_namespace=example-awx
|
||||
#> <test everything>
|
||||
#> minikube delete
|
||||
```
|
||||
|
||||
If everything works, commit the updated version, then tag a new repository release with the same tag as the Docker image pushed earlier.
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
template:
|
||||
src: crd.yml.j2
|
||||
dest: "{{ playbook_dir }}/../deploy/crds/awx_v1beta1_crd.yaml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Template awx-operator.yaml
|
||||
template:
|
||||
src: awx-operator.yaml.j2
|
||||
dest: ../deploy/awx-operator.yaml
|
||||
mode: '0644'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
operator_image: quay.io/ansible/awx-operator
|
||||
operator_version: 0.6.0
|
||||
operator_version: 0.8.0
|
||||
pull_policy: Always
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
- name: Deploy AWX
|
||||
k8s:
|
||||
state: "{{ state | default('present') }}"
|
||||
namespace: default
|
||||
namespace: "{{ tower_namespace | default('default') }}"
|
||||
apply: yes
|
||||
wait: yes
|
||||
definition:
|
||||
@@ -20,9 +20,10 @@
|
||||
spec:
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
tower_ingress_type: "{{ tower_ingress_type | default(omit) }}" # Either Route or Ingress
|
||||
tower_ingress_type: "{{ tower_ingress_type | default(omit) }}" # Either Route, Ingress or LoadBalancer
|
||||
tower_image: "{{ tower_image | default(omit) }}"
|
||||
development_mode: "{{ development_mode | default(omit) }}"
|
||||
development_mode: "{{ development_mode | default(omit) | bool }}"
|
||||
tower_image_pull_policy: "{{ tower_image_pull_policy | default(omit) }}"
|
||||
# tower_ee_images:
|
||||
# - name: test-ee
|
||||
# image: quay.io/<user>/awx-ee
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#jinja2: trim_blocks:False
|
||||
# This file is generated by Ansible. Changes will be lost.
|
||||
# Update templates under ansible/templates/
|
||||
{% include 'crd.yml.j2' %}
|
||||
|
||||
{% include 'role.yml.j2' %}
|
||||
|
||||
{% include 'role_binding.yml.j2' %}
|
||||
@@ -8,5 +10,3 @@
|
||||
{% include 'service_account.yml.j2' %}
|
||||
|
||||
{% include 'operator.yml.j2' %}
|
||||
|
||||
{% include 'crd.yml.j2' %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxs.awx.ansible.com
|
||||
@@ -11,40 +11,314 @@ spec:
|
||||
plural: awxs
|
||||
singular: awx
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
version: v1beta1
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
subresources:
|
||||
status: {}
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
properties:
|
||||
external_database:
|
||||
type: boolean
|
||||
description: |
|
||||
If true you must supply a secret containing the location and credentials for
|
||||
connecting to the external database by a user who has permission to create
|
||||
and apply a schema.
|
||||
|
||||
The secret should have the name: <custom resource name>-postgres-configuration and
|
||||
should look like:
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <crname>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
host: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
spec:
|
||||
properties:
|
||||
deployment_type:
|
||||
description: Name of the deployment type
|
||||
type: string
|
||||
tower_task_privileged:
|
||||
description: If a privileged security context should be enabled
|
||||
type: boolean
|
||||
default: false
|
||||
tower_admin_user:
|
||||
description: Username to use for the admin account
|
||||
type: string
|
||||
default: admin
|
||||
tower_hostname:
|
||||
description: The hostname of the instance
|
||||
type: string
|
||||
tower_admin_email:
|
||||
description: The admin user email
|
||||
type: string
|
||||
tower_admin_password_secret:
|
||||
description: Secret where the admin password can be found
|
||||
type: string
|
||||
tower_postgres_configuration_secret:
|
||||
description: Secret where the database configuration can be found
|
||||
type: string
|
||||
tower_old_postgres_configuration_secret:
|
||||
description: Secret where the old database configuration can be found for data migration
|
||||
type: string
|
||||
tower_secret_key_secret:
|
||||
description: Secret where the secret key can be found
|
||||
type: string
|
||||
tower_broadcast_websocket_secret:
|
||||
description: Secret where the broadcast websocket secret can be found
|
||||
type: string
|
||||
tower_extra_volumes:
|
||||
description: Specify extra volumes to add to the application pod
|
||||
type: string
|
||||
tower_ingress_type:
|
||||
description: The ingress type to use to reach the deployed instance
|
||||
type: string
|
||||
enum:
|
||||
- none
|
||||
- Ingress
|
||||
- ingress
|
||||
- Route
|
||||
- route
|
||||
- LoadBalancer
|
||||
- loadbalancer
|
||||
tower_ingress_annotations:
|
||||
description: Annotations to add to the ingress
|
||||
type: string
|
||||
tower_ingress_tls_secret:
|
||||
description: Secret where the ingress TLS secret can be found
|
||||
type: string
|
||||
tower_loadbalancer_annotations:
|
||||
description: Annotations to add to the loadbalancer
|
||||
type: string
|
||||
tower_loadbalancer_protocol:
|
||||
description: Protocol to use for the loadbalancer
|
||||
type: string
|
||||
default: http
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
tower_loadbalancer_port:
|
||||
description: Port to use for the loadbalancer
|
||||
type: integer
|
||||
default: 80
|
||||
tower_route_host:
|
||||
description: The DNS to use to points to the instance
|
||||
type: string
|
||||
tower_route_tls_termination_mechanism:
|
||||
description: The secure TLS termination mechanism to use
|
||||
type: string
|
||||
default: Edge
|
||||
enum:
|
||||
- Edge
|
||||
- edge
|
||||
- Passthrough
|
||||
- passthrough
|
||||
tower_route_tls_secret:
|
||||
description: Secret where the TLS related credentials are stored
|
||||
type: string
|
||||
tower_node_selector:
|
||||
description: nodeSelector for the AWX pods
|
||||
type: string
|
||||
tower_tolerations:
|
||||
description: node tolerations for the AWX pods
|
||||
type: string
|
||||
tower_image:
|
||||
description: Registry path to the application container to use
|
||||
type: string
|
||||
tower_ee_images:
|
||||
description: Registry path to the Execution Environment container to use
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
image:
|
||||
type: string
|
||||
tower_image_pull_policy:
|
||||
description: The image pull policy
|
||||
type: string
|
||||
default: IfNotPresent
|
||||
enum:
|
||||
- Always
|
||||
- always
|
||||
- Never
|
||||
- never
|
||||
- IfNotPresent
|
||||
- ifnotpresent
|
||||
tower_image_pull_secret:
|
||||
description: The image pull secret
|
||||
type: string
|
||||
tower_task_resource_requirements:
|
||||
description: Resource requirements for the task container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_web_resource_requirements:
|
||||
description: Resource requirements for the web container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_replicas:
|
||||
description: Number of instance replicas
|
||||
type: integer
|
||||
default: 1
|
||||
format: int32
|
||||
tower_garbage_collect_secrets:
|
||||
description: Whether or not to remove secrets upon instance removal
|
||||
default: false
|
||||
type: boolean
|
||||
tower_create_preload_data:
|
||||
description: Whether or not to preload data upon Tower instance creation
|
||||
default: true
|
||||
type: boolean
|
||||
tower_task_args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_task_command:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_web_args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_web_command:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_task_extra_env:
|
||||
type: string
|
||||
tower_web_extra_env:
|
||||
type: string
|
||||
tower_task_extra_volume_mounts:
|
||||
type: string
|
||||
tower_web_extra_volume_mounts:
|
||||
type: string
|
||||
tower_redis_image:
|
||||
description: Registry path to the redis container to use
|
||||
type: string
|
||||
tower_postgres_image:
|
||||
description: Registry path to the PostgreSQL container to use
|
||||
type: string
|
||||
tower_postgres_resource_requirements:
|
||||
description: Resource requirements for the PostgreSQL container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_postgres_storage_class:
|
||||
description: Storage class to use for the PostgreSQL PVC
|
||||
type: string
|
||||
tower_postgres_data_path:
|
||||
description: Path where the PostgreSQL data are located
|
||||
type: string
|
||||
ca_trust_bundle:
|
||||
description: Path where the trusted CA bundle is available
|
||||
type: string
|
||||
development_mode:
|
||||
description: If the deployment should be done in development mode
|
||||
type: boolean
|
||||
ldap_cacert_secret:
|
||||
description: Secret where can be found the LDAP trusted Certificate Authority Bundle
|
||||
type: string
|
||||
tower_projects_persistence:
|
||||
description: Whether or not the /var/lib/projects directory will be persistent
|
||||
default: false
|
||||
type: boolean
|
||||
tower_projects_use_existing_claim:
|
||||
description: Using existing PersistentVolumeClaim
|
||||
type: string
|
||||
enum:
|
||||
- _Yes_
|
||||
- _No_
|
||||
tower_projects_existing_claim:
|
||||
description: PersistentVolumeClaim to mount /var/lib/projects directory
|
||||
type: string
|
||||
tower_projects_storage_class:
|
||||
description: Storage class for the /var/lib/projects PersistentVolumeClaim
|
||||
type: string
|
||||
tower_projects_storage_size:
|
||||
description: Size for the /var/lib/projects PersistentVolumeClaim
|
||||
default: 8Gi
|
||||
type: string
|
||||
tower_projects_storage_access_mode:
|
||||
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
|
||||
default: ReadWriteMany
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
towerURL:
|
||||
description: URL to access the deployed instance
|
||||
type: string
|
||||
towerAdminUser:
|
||||
description: Admin user of the deployed instance
|
||||
type: string
|
||||
towerAdminPasswordSecret:
|
||||
description: Admin password of the deployed instance
|
||||
type: string
|
||||
towerMigratedFromSecret:
|
||||
description: The secret used for migrating an old Tower.
|
||||
type: string
|
||||
towerVersion:
|
||||
description: Version of the deployed instance
|
||||
type: string
|
||||
towerImage:
|
||||
description: URL of the image used for the deployed instance
|
||||
type: string
|
||||
conditions:
|
||||
description: The resulting conditions when a Service Telemetry is instantiated
|
||||
items:
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
lastTransitionTime:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
|
||||
@@ -37,8 +37,8 @@ spec:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 6789
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 3
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
volumes:
|
||||
- name: runner
|
||||
emptyDir: {}
|
||||
|
||||
@@ -9,19 +9,24 @@ rules:
|
||||
- route.openshift.io
|
||||
resources:
|
||||
- routes
|
||||
- routes/custom-host
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
- "rbac.authorization.k8s.io"
|
||||
resources:
|
||||
- pods
|
||||
- services
|
||||
- services/finalizers
|
||||
- serviceaccounts
|
||||
- endpoints
|
||||
- persistentvolumeclaims
|
||||
- events
|
||||
- configmaps
|
||||
- secrets
|
||||
- roles
|
||||
- rolebindings
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
@@ -50,6 +55,12 @@ rules:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- deployments/scale
|
||||
verbs:
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
||||
14
bundle.Dockerfile
Normal file
14
bundle.Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
||||
FROM scratch
|
||||
|
||||
LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1
|
||||
LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
|
||||
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/
|
||||
LABEL operators.operatorframework.io.bundle.package.v1=awx-operator
|
||||
LABEL operators.operatorframework.io.bundle.channels.v1=alpha
|
||||
LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha
|
||||
LABEL operators.operatorframework.io.metrics.project_layout=ansible
|
||||
LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1
|
||||
LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v0.19.4
|
||||
|
||||
COPY deploy/olm-catalog/awx-operator/manifests /manifests/
|
||||
COPY deploy/olm-catalog/awx-operator/metadata /metadata/
|
||||
@@ -1,5 +1,330 @@
|
||||
# This file is generated by Ansible. Changes will be lost.
|
||||
# Update templates under ansible/templates/
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxs.awx.ansible.com
|
||||
spec:
|
||||
group: awx.ansible.com
|
||||
names:
|
||||
kind: AWX
|
||||
listKind: AWXList
|
||||
plural: awxs
|
||||
singular: awx
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
properties:
|
||||
spec:
|
||||
properties:
|
||||
deployment_type:
|
||||
description: Name of the deployment type
|
||||
type: string
|
||||
tower_task_privileged:
|
||||
description: If a privileged security context should be enabled
|
||||
type: boolean
|
||||
default: false
|
||||
tower_admin_user:
|
||||
description: Username to use for the admin account
|
||||
type: string
|
||||
default: admin
|
||||
tower_hostname:
|
||||
description: The hostname of the instance
|
||||
type: string
|
||||
tower_admin_email:
|
||||
description: The admin user email
|
||||
type: string
|
||||
tower_admin_password_secret:
|
||||
description: Secret where the admin password can be found
|
||||
type: string
|
||||
tower_postgres_configuration_secret:
|
||||
description: Secret where the database configuration can be found
|
||||
type: string
|
||||
tower_old_postgres_configuration_secret:
|
||||
description: Secret where the old database configuration can be found for data migration
|
||||
type: string
|
||||
tower_secret_key_secret:
|
||||
description: Secret where the secret key can be found
|
||||
type: string
|
||||
tower_broadcast_websocket_secret:
|
||||
description: Secret where the broadcast websocket secret can be found
|
||||
type: string
|
||||
tower_extra_volumes:
|
||||
description: Specify extra volumes to add to the application pod
|
||||
type: string
|
||||
tower_ingress_type:
|
||||
description: The ingress type to use to reach the deployed instance
|
||||
type: string
|
||||
enum:
|
||||
- none
|
||||
- Ingress
|
||||
- ingress
|
||||
- Route
|
||||
- route
|
||||
- LoadBalancer
|
||||
- loadbalancer
|
||||
tower_ingress_annotations:
|
||||
description: Annotations to add to the ingress
|
||||
type: string
|
||||
tower_ingress_tls_secret:
|
||||
description: Secret where the ingress TLS secret can be found
|
||||
type: string
|
||||
tower_loadbalancer_annotations:
|
||||
description: Annotations to add to the loadbalancer
|
||||
type: string
|
||||
tower_loadbalancer_protocol:
|
||||
description: Protocol to use for the loadbalancer
|
||||
type: string
|
||||
default: http
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
tower_loadbalancer_port:
|
||||
description: Port to use for the loadbalancer
|
||||
type: integer
|
||||
default: 80
|
||||
tower_route_host:
|
||||
description: The DNS to use to points to the instance
|
||||
type: string
|
||||
tower_route_tls_termination_mechanism:
|
||||
description: The secure TLS termination mechanism to use
|
||||
type: string
|
||||
default: Edge
|
||||
enum:
|
||||
- Edge
|
||||
- edge
|
||||
- Passthrough
|
||||
- passthrough
|
||||
tower_route_tls_secret:
|
||||
description: Secret where the TLS related credentials are stored
|
||||
type: string
|
||||
tower_node_selector:
|
||||
description: nodeSelector for the AWX pods
|
||||
type: string
|
||||
tower_tolerations:
|
||||
description: node tolerations for the AWX pods
|
||||
type: string
|
||||
tower_image:
|
||||
description: Registry path to the application container to use
|
||||
type: string
|
||||
tower_ee_images:
|
||||
description: Registry path to the Execution Environment container to use
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
image:
|
||||
type: string
|
||||
tower_image_pull_policy:
|
||||
description: The image pull policy
|
||||
type: string
|
||||
default: IfNotPresent
|
||||
enum:
|
||||
- Always
|
||||
- always
|
||||
- Never
|
||||
- never
|
||||
- IfNotPresent
|
||||
- ifnotpresent
|
||||
tower_image_pull_secret:
|
||||
description: The image pull secret
|
||||
type: string
|
||||
tower_task_resource_requirements:
|
||||
description: Resource requirements for the task container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_web_resource_requirements:
|
||||
description: Resource requirements for the web container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_replicas:
|
||||
description: Number of instance replicas
|
||||
type: integer
|
||||
default: 1
|
||||
format: int32
|
||||
tower_garbage_collect_secrets:
|
||||
description: Whether or not to remove secrets upon instance removal
|
||||
default: false
|
||||
type: boolean
|
||||
tower_create_preload_data:
|
||||
description: Whether or not to preload data upon Tower instance creation
|
||||
default: true
|
||||
type: boolean
|
||||
tower_task_args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_task_command:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_web_args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_web_command:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_task_extra_env:
|
||||
type: string
|
||||
tower_web_extra_env:
|
||||
type: string
|
||||
tower_task_extra_volume_mounts:
|
||||
type: string
|
||||
tower_web_extra_volume_mounts:
|
||||
type: string
|
||||
tower_redis_image:
|
||||
description: Registry path to the redis container to use
|
||||
type: string
|
||||
tower_postgres_image:
|
||||
description: Registry path to the PostgreSQL container to use
|
||||
type: string
|
||||
tower_postgres_resource_requirements:
|
||||
description: Resource requirements for the PostgreSQL container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_postgres_storage_class:
|
||||
description: Storage class to use for the PostgreSQL PVC
|
||||
type: string
|
||||
tower_postgres_data_path:
|
||||
description: Path where the PostgreSQL data are located
|
||||
type: string
|
||||
ca_trust_bundle:
|
||||
description: Path where the trusted CA bundle is available
|
||||
type: string
|
||||
development_mode:
|
||||
description: If the deployment should be done in development mode
|
||||
type: boolean
|
||||
ldap_cacert_secret:
|
||||
description: Secret where can be found the LDAP trusted Certificate Authority Bundle
|
||||
type: string
|
||||
tower_projects_persistence:
|
||||
description: Whether or not the /var/lib/projects directory will be persistent
|
||||
default: false
|
||||
type: boolean
|
||||
tower_projects_use_existing_claim:
|
||||
description: Using existing PersistentVolumeClaim
|
||||
type: string
|
||||
enum:
|
||||
- _Yes_
|
||||
- _No_
|
||||
tower_projects_existing_claim:
|
||||
description: PersistentVolumeClaim to mount /var/lib/projects directory
|
||||
type: string
|
||||
tower_projects_storage_class:
|
||||
description: Storage class for the /var/lib/projects PersistentVolumeClaim
|
||||
type: string
|
||||
tower_projects_storage_size:
|
||||
description: Size for the /var/lib/projects PersistentVolumeClaim
|
||||
default: 8Gi
|
||||
type: string
|
||||
tower_projects_storage_access_mode:
|
||||
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
|
||||
default: ReadWriteMany
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
towerURL:
|
||||
description: URL to access the deployed instance
|
||||
type: string
|
||||
towerAdminUser:
|
||||
description: Admin user of the deployed instance
|
||||
type: string
|
||||
towerAdminPasswordSecret:
|
||||
description: Admin password of the deployed instance
|
||||
type: string
|
||||
towerMigratedFromSecret:
|
||||
description: The secret used for migrating an old Tower.
|
||||
type: string
|
||||
towerVersion:
|
||||
description: Version of the deployed instance
|
||||
type: string
|
||||
towerImage:
|
||||
description: URL of the image used for the deployed instance
|
||||
type: string
|
||||
conditions:
|
||||
description: The resulting conditions when a Service Telemetry is instantiated
|
||||
items:
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
lastTransitionTime:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -11,19 +336,24 @@ rules:
|
||||
- route.openshift.io
|
||||
resources:
|
||||
- routes
|
||||
- routes/custom-host
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
- "rbac.authorization.k8s.io"
|
||||
resources:
|
||||
- pods
|
||||
- services
|
||||
- services/finalizers
|
||||
- serviceaccounts
|
||||
- endpoints
|
||||
- persistentvolumeclaims
|
||||
- events
|
||||
- configmaps
|
||||
- secrets
|
||||
- roles
|
||||
- rolebindings
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
@@ -52,6 +382,12 @@ rules:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- deployments/scale
|
||||
verbs:
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
@@ -111,7 +447,7 @@ spec:
|
||||
serviceAccountName: awx-operator
|
||||
containers:
|
||||
- name: awx-operator
|
||||
image: "quay.io/ansible/awx-operator:0.6.0"
|
||||
image: "quay.io/ansible/awx-operator:0.8.0"
|
||||
imagePullPolicy: "Always"
|
||||
volumeMounts:
|
||||
- mountPath: /tmp/ansible-operator/runner
|
||||
@@ -132,59 +468,8 @@ spec:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 6789
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 3
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
volumes:
|
||||
- name: runner
|
||||
emptyDir: {}
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxs.awx.ansible.com
|
||||
spec:
|
||||
group: awx.ansible.com
|
||||
names:
|
||||
kind: AWX
|
||||
listKind: AWXList
|
||||
plural: awxs
|
||||
singular: awx
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
version: v1beta1
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
external_database:
|
||||
type: boolean
|
||||
description: |
|
||||
If true you must supply a secret containing the location and credentials for
|
||||
connecting to the external database by a user who has permission to create
|
||||
and apply a schema.
|
||||
|
||||
The secret should have the name: <custom resource name>-postgres-configuration and
|
||||
should look like:
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <crname>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
host: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: example-awx
|
||||
namespace: example-awx
|
||||
spec:
|
||||
tower_ingress_type: none
|
||||
tower_task_privileged: false
|
||||
|
||||
tower_hostname: example-awx.test
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
|
||||
tower_image: ansible/awx:15.0.0
|
||||
|
||||
tower_task_mem_request: 1Gi
|
||||
tower_task_cpu_request: 500m
|
||||
|
||||
tower_web_mem_request: 2Gi
|
||||
tower_web_cpu_request: 1000m
|
||||
|
||||
tower_create_preload_data: true
|
||||
|
||||
tower_memcached_image: memcached:alpine
|
||||
|
||||
tower_redis_image: redis:latest
|
||||
|
||||
tower_postgres_storage_request: 8Gi
|
||||
tower_postgres_storage_class: ''
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxs.awx.ansible.com
|
||||
@@ -11,40 +11,314 @@ spec:
|
||||
plural: awxs
|
||||
singular: awx
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
version: v1beta1
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
subresources:
|
||||
status: {}
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
properties:
|
||||
external_database:
|
||||
type: boolean
|
||||
description: |
|
||||
If true you must supply a secret containing the location and credentials for
|
||||
connecting to the external database by a user who has permission to create
|
||||
and apply a schema.
|
||||
|
||||
The secret should have the name: <custom resource name>-postgres-configuration and
|
||||
should look like:
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <crname>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
host: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
spec:
|
||||
properties:
|
||||
deployment_type:
|
||||
description: Name of the deployment type
|
||||
type: string
|
||||
tower_task_privileged:
|
||||
description: If a privileged security context should be enabled
|
||||
type: boolean
|
||||
default: false
|
||||
tower_admin_user:
|
||||
description: Username to use for the admin account
|
||||
type: string
|
||||
default: admin
|
||||
tower_hostname:
|
||||
description: The hostname of the instance
|
||||
type: string
|
||||
tower_admin_email:
|
||||
description: The admin user email
|
||||
type: string
|
||||
tower_admin_password_secret:
|
||||
description: Secret where the admin password can be found
|
||||
type: string
|
||||
tower_postgres_configuration_secret:
|
||||
description: Secret where the database configuration can be found
|
||||
type: string
|
||||
tower_old_postgres_configuration_secret:
|
||||
description: Secret where the old database configuration can be found for data migration
|
||||
type: string
|
||||
tower_secret_key_secret:
|
||||
description: Secret where the secret key can be found
|
||||
type: string
|
||||
tower_broadcast_websocket_secret:
|
||||
description: Secret where the broadcast websocket secret can be found
|
||||
type: string
|
||||
tower_extra_volumes:
|
||||
description: Specify extra volumes to add to the application pod
|
||||
type: string
|
||||
tower_ingress_type:
|
||||
description: The ingress type to use to reach the deployed instance
|
||||
type: string
|
||||
enum:
|
||||
- none
|
||||
- Ingress
|
||||
- ingress
|
||||
- Route
|
||||
- route
|
||||
- LoadBalancer
|
||||
- loadbalancer
|
||||
tower_ingress_annotations:
|
||||
description: Annotations to add to the ingress
|
||||
type: string
|
||||
tower_ingress_tls_secret:
|
||||
description: Secret where the ingress TLS secret can be found
|
||||
type: string
|
||||
tower_loadbalancer_annotations:
|
||||
description: Annotations to add to the loadbalancer
|
||||
type: string
|
||||
tower_loadbalancer_protocol:
|
||||
description: Protocol to use for the loadbalancer
|
||||
type: string
|
||||
default: http
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
tower_loadbalancer_port:
|
||||
description: Port to use for the loadbalancer
|
||||
type: integer
|
||||
default: 80
|
||||
tower_route_host:
|
||||
description: The DNS to use to points to the instance
|
||||
type: string
|
||||
tower_route_tls_termination_mechanism:
|
||||
description: The secure TLS termination mechanism to use
|
||||
type: string
|
||||
default: Edge
|
||||
enum:
|
||||
- Edge
|
||||
- edge
|
||||
- Passthrough
|
||||
- passthrough
|
||||
tower_route_tls_secret:
|
||||
description: Secret where the TLS related credentials are stored
|
||||
type: string
|
||||
tower_node_selector:
|
||||
description: nodeSelector for the AWX pods
|
||||
type: string
|
||||
tower_tolerations:
|
||||
description: node tolerations for the AWX pods
|
||||
type: string
|
||||
tower_image:
|
||||
description: Registry path to the application container to use
|
||||
type: string
|
||||
tower_ee_images:
|
||||
description: Registry path to the Execution Environment container to use
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
image:
|
||||
type: string
|
||||
tower_image_pull_policy:
|
||||
description: The image pull policy
|
||||
type: string
|
||||
default: IfNotPresent
|
||||
enum:
|
||||
- Always
|
||||
- always
|
||||
- Never
|
||||
- never
|
||||
- IfNotPresent
|
||||
- ifnotpresent
|
||||
tower_image_pull_secret:
|
||||
description: The image pull secret
|
||||
type: string
|
||||
tower_task_resource_requirements:
|
||||
description: Resource requirements for the task container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_web_resource_requirements:
|
||||
description: Resource requirements for the web container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_replicas:
|
||||
description: Number of instance replicas
|
||||
type: integer
|
||||
default: 1
|
||||
format: int32
|
||||
tower_garbage_collect_secrets:
|
||||
description: Whether or not to remove secrets upon instance removal
|
||||
default: false
|
||||
type: boolean
|
||||
tower_create_preload_data:
|
||||
description: Whether or not to preload data upon Tower instance creation
|
||||
default: true
|
||||
type: boolean
|
||||
tower_task_args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_task_command:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_web_args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_web_command:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tower_task_extra_env:
|
||||
type: string
|
||||
tower_web_extra_env:
|
||||
type: string
|
||||
tower_task_extra_volume_mounts:
|
||||
type: string
|
||||
tower_web_extra_volume_mounts:
|
||||
type: string
|
||||
tower_redis_image:
|
||||
description: Registry path to the redis container to use
|
||||
type: string
|
||||
tower_postgres_image:
|
||||
description: Registry path to the PostgreSQL container to use
|
||||
type: string
|
||||
tower_postgres_resource_requirements:
|
||||
description: Resource requirements for the PostgreSQL container
|
||||
properties:
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_postgres_storage_class:
|
||||
description: Storage class to use for the PostgreSQL PVC
|
||||
type: string
|
||||
tower_postgres_data_path:
|
||||
description: Path where the PostgreSQL data are located
|
||||
type: string
|
||||
ca_trust_bundle:
|
||||
description: Path where the trusted CA bundle is available
|
||||
type: string
|
||||
development_mode:
|
||||
description: If the deployment should be done in development mode
|
||||
type: boolean
|
||||
ldap_cacert_secret:
|
||||
description: Secret where can be found the LDAP trusted Certificate Authority Bundle
|
||||
type: string
|
||||
tower_projects_persistence:
|
||||
description: Whether or not the /var/lib/projects directory will be persistent
|
||||
default: false
|
||||
type: boolean
|
||||
tower_projects_use_existing_claim:
|
||||
description: Using existing PersistentVolumeClaim
|
||||
type: string
|
||||
enum:
|
||||
- _Yes_
|
||||
- _No_
|
||||
tower_projects_existing_claim:
|
||||
description: PersistentVolumeClaim to mount /var/lib/projects directory
|
||||
type: string
|
||||
tower_projects_storage_class:
|
||||
description: Storage class for the /var/lib/projects PersistentVolumeClaim
|
||||
type: string
|
||||
tower_projects_storage_size:
|
||||
description: Size for the /var/lib/projects PersistentVolumeClaim
|
||||
default: 8Gi
|
||||
type: string
|
||||
tower_projects_storage_access_mode:
|
||||
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
|
||||
default: ReadWriteMany
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
towerURL:
|
||||
description: URL to access the deployed instance
|
||||
type: string
|
||||
towerAdminUser:
|
||||
description: Admin user of the deployed instance
|
||||
type: string
|
||||
towerAdminPasswordSecret:
|
||||
description: Admin password of the deployed instance
|
||||
type: string
|
||||
towerMigratedFromSecret:
|
||||
description: The secret used for migrating an old Tower.
|
||||
type: string
|
||||
towerVersion:
|
||||
description: Version of the deployed instance
|
||||
type: string
|
||||
towerImage:
|
||||
description: URL of the image used for the deployed instance
|
||||
type: string
|
||||
conditions:
|
||||
description: The resulting conditions when a Service Telemetry is instantiated
|
||||
items:
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
lastTransitionTime:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
|
||||
@@ -5,31 +5,13 @@ metadata:
|
||||
name: example-awx
|
||||
namespace: example-awx
|
||||
spec:
|
||||
deployment_type: awx
|
||||
tower_ingress_type: ingress
|
||||
tower_task_privileged: false
|
||||
|
||||
tower_hostname: example-awx.test
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
|
||||
tower_image: ansible/awx:15.0.0
|
||||
|
||||
tower_task_mem_request: 128M
|
||||
tower_task_cpu_request: 500m
|
||||
|
||||
tower_web_mem_request: 128M
|
||||
tower_web_cpu_request: 500m
|
||||
|
||||
tower_create_preload_data: true
|
||||
|
||||
tower_memcached_image: memcached:alpine
|
||||
|
||||
tower_redis_image: redis:latest
|
||||
|
||||
tower_postgres_pass: awxpass
|
||||
tower_postgres_image: postgres:12
|
||||
tower_postgres_storage_request: 8Gi
|
||||
tower_postgres_storage_class: ''
|
||||
tower_web_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 128M
|
||||
tower_task_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 128M
|
||||
|
||||
5
deploy/kustomization.yaml
Normal file
5
deploy/kustomization.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- ./awx-operator.yaml
|
||||
@@ -1,4 +1,3 @@
|
||||
---
|
||||
apiVersion: operators.coreos.com/v1alpha1
|
||||
kind: ClusterServiceVersion
|
||||
metadata:
|
||||
@@ -13,52 +12,20 @@ metadata:
|
||||
"namespace": "example-awx"
|
||||
},
|
||||
"spec": {
|
||||
"tower_admin_email": "test@example.com",
|
||||
"tower_admin_password": "changeme",
|
||||
"tower_admin_user": "test",
|
||||
"tower_broadcast_websocket_secret": "changeme",
|
||||
"tower_create_preload_data": true,
|
||||
"tower_hostname": "example-awx.test",
|
||||
"tower_ingress_type": "none",
|
||||
"tower_memcached_image": "memcached:alpine",
|
||||
"tower_postgres_storage_class": "",
|
||||
"tower_postgres_storage_request": "8Gi",
|
||||
"tower_redis_image": "redis:latest",
|
||||
"tower_task_cpu_request": "500m",
|
||||
"tower_image": "ansible/awx:15.0.0",
|
||||
"tower_task_mem_request": "1Gi",
|
||||
"tower_task_privileged": false,
|
||||
"tower_web_cpu_request": "1000m"
|
||||
"tower_web_mem_request": "2Gi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "awx.ansible.com/v1beta1",
|
||||
"kind": "AWX",
|
||||
"metadata": {
|
||||
"name": "example-awx",
|
||||
"namespace": "example-awx"
|
||||
},
|
||||
"spec": {
|
||||
"tower_admin_email": "test@example.com",
|
||||
"tower_admin_password": "changeme",
|
||||
"tower_admin_user": "test",
|
||||
"tower_broadcast_websocket_secret": "changeme",
|
||||
"tower_create_preload_data": true,
|
||||
"tower_hostname": "example-awx.test",
|
||||
"deployment_type": "awx",
|
||||
"tower_ingress_type": "ingress",
|
||||
"tower_memcached_image": "memcached:alpine",
|
||||
"tower_postgres_image": "postgres:12",
|
||||
"tower_postgres_pass": "awxpass",
|
||||
"tower_postgres_storage_class": "",
|
||||
"tower_postgres_storage_request": "8Gi",
|
||||
"tower_redis_image": "redis:latest",
|
||||
"tower_task_cpu_request": "500m",
|
||||
"tower_image": "ansible/awx:15.0.0",
|
||||
"tower_task_mem_request": "128M",
|
||||
"tower_task_privileged": false,
|
||||
"tower_web_cpu_request": "500m",
|
||||
"tower_web_mem_request": "128M"
|
||||
"tower_task_resource_requirements": {
|
||||
"requests": {
|
||||
"cpu": "500m",
|
||||
"memory": "128M"
|
||||
}
|
||||
},
|
||||
"tower_web_resource_requirements": {
|
||||
"requests": {
|
||||
"cpu": "500m",
|
||||
"memory": "128M"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -71,149 +38,471 @@ spec:
|
||||
apiservicedefinitions: {}
|
||||
customresourcedefinitions:
|
||||
owned:
|
||||
- kind: AWX
|
||||
name: awxs.awx.ansible.com
|
||||
version: v1beta1
|
||||
- description: A AWX Instance
|
||||
displayName: AWX
|
||||
kind: AWX
|
||||
name: awxs.awx.ansible.com
|
||||
specDescriptors:
|
||||
- displayName: Hostname
|
||||
path: tower_hostname
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Admin account username
|
||||
path: tower_admin_user
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Admin email address
|
||||
path: tower_admin_email
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Admin password secret
|
||||
path: tower_admin_password_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Database configuration secret
|
||||
path: tower_postgres_configuration_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Old Database configuration secret
|
||||
path: tower_old_postgres_configuration_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Secret key secret
|
||||
path: tower_secret_key_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Broadcast Websocket Secret
|
||||
path: tower_broadcast_websocket_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Ingress Type
|
||||
path: tower_ingress_type
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:none
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Ingress
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Route
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:LoadBalancer
|
||||
- displayName: Tower Ingress Annotations
|
||||
path: tower_ingress_annotations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Ingress
|
||||
- displayName: Tower Ingress TLS Secret
|
||||
path: tower_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:tower_ingress_type:Ingress
|
||||
- displayName: Tower LoadBalancer Annotations
|
||||
path: tower_loadbalancer_annotations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:LoadBalancer
|
||||
- displayName: Tower LoadBalancer Protocol
|
||||
path: tower_loadbalancer_protocol
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:http
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:https
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:LoadBalancer
|
||||
- displayName: Tower LoadBalancer Port
|
||||
path: tower_loadbalancer_port
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:number
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:LoadBalancer
|
||||
- displayName: Route DNS host
|
||||
path: tower_route_host
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Route
|
||||
- displayName: Route TLS termination mechanism
|
||||
path: tower_route_tls_termination_mechanism
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Edge
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:Passthrough
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Route
|
||||
- displayName: Route TLS credential secret
|
||||
path: tower_route_tls_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_ingress_type:Route
|
||||
- displayName: Image Pull Policy
|
||||
path: tower_image_pull_policy
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:imagePullPolicy
|
||||
- displayName: Image Pull Secret
|
||||
path: tower_image_pull_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:imagePullSecret
|
||||
- displayName: Web container resource requirements
|
||||
path: tower_web_resource_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: Task container resource requirements
|
||||
path: tower_task_resource_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: PostgreSQL container resource requirements (when using a managed
|
||||
instance)
|
||||
path: tower_postgres_resource_requirements
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:resourceRequirements
|
||||
- displayName: Replicas
|
||||
path: tower_replicas
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:number
|
||||
- displayName: Remove used secrets on instance removal ?
|
||||
path: tower_garbage_collect_secrets
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- displayName: Preload instance with data upon creation ?
|
||||
path: tower_create_preload_data
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- displayName: Deploy the instance in development mode ?
|
||||
path: development_mode
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Should Tower Task container deployed with privileged level ?
|
||||
path: tower_task_privileged
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Deployment Type
|
||||
path: deployment_type
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Image
|
||||
path: tower_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Redis Image
|
||||
path: tower_redis_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: PostgreSQL Image
|
||||
path: tower_postgres_image
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Postgres Storage Class
|
||||
path: tower_postgres_storage_class
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Postgres Datapath
|
||||
path: tower_postgres_data_path
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Certificate Authorirty Trust Bundle
|
||||
path: ca_trust_bundle
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: LDAP Certificate Authority Trust Bundle
|
||||
path: ldap_cacert_secret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- displayName: Tower Task Args
|
||||
path: tower_task_args
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Enable persistence for /var/lib/projects directory?
|
||||
path: tower_projects_persistence
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
|
||||
- displayName: Use existing Persistent Claim?
|
||||
path: tower_projects_use_existing_claim
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:_Yes_
|
||||
- urn:alm:descriptor:com.tectonic.ui:select:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_persistence:true
|
||||
- displayName: Tower Projects Existing Persistent Claim
|
||||
path: tower_projects_existing_claim
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_Yes_
|
||||
- urn:alm:descriptor:io.kubernetes:PersistentVolumeClaim
|
||||
- description: Tower Projects Storage Class Name. If not present, the default
|
||||
storage class will be used.
|
||||
displayName: Tower Projects Storage Class Name
|
||||
path: tower_projects_storage_class
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Tower Projects Storage Size
|
||||
displayName: Tower Projects Storage Size
|
||||
path: tower_projects_storage_size
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Tower Projects Storage Access Mode
|
||||
displayName: Tower Projects Storage Access Mode
|
||||
path: tower_projects_storage_access_mode
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:fieldDependency:tower_projects_use_existing_claim:_No_
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- displayName: Tower Task Command
|
||||
path: tower_task_command
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Task Extra Env
|
||||
path: tower_task_extra_env
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Task Extra Volume Mounts
|
||||
path: tower_task_extra_volume_mounts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Web Args
|
||||
path: tower_web_args
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Web Command
|
||||
path: tower_web_command
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Web Extra Env
|
||||
path: tower_web_extra_env
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Web Extra Volume Mounts
|
||||
path: tower_web_extra_volume_mounts
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Extra Volumes
|
||||
path: tower_extra_volumes
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Node Selector
|
||||
path: tower_node_selector
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
- displayName: Tower Tolerations
|
||||
path: tower_tolerations
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:advanced
|
||||
- urn:alm:descriptor:com.tectonic.ui:hidden
|
||||
statusDescriptors:
|
||||
- description: Route to access the instance deployed
|
||||
displayName: URL
|
||||
path: towerURL
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:org.w3:link
|
||||
- description: Admin user for the instance deployed
|
||||
displayName: Admin User
|
||||
path: towerAdminUser
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Admin password for the instance deployed
|
||||
displayName: Admin Password
|
||||
path: towerAdminPasswordSecret
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:io.kubernetes:Secret
|
||||
- description: Version of the instance deployed
|
||||
displayName: Version
|
||||
path: towerVersion
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
- description: Image of the instance deployed
|
||||
displayName: Image
|
||||
path: towerImage
|
||||
x-descriptors:
|
||||
- urn:alm:descriptor:com.tectonic.ui:text
|
||||
version: v1beta1
|
||||
description: AWX operator
|
||||
displayName: AWX
|
||||
icon:
|
||||
- base64data: ""
|
||||
mediatype: ""
|
||||
- base64data: ""
|
||||
mediatype: ""
|
||||
install:
|
||||
spec:
|
||||
clusterPermissions:
|
||||
- rules:
|
||||
- apiGroups:
|
||||
- route.openshift.io
|
||||
resources:
|
||||
- routes
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- services
|
||||
- services/finalizers
|
||||
- endpoints
|
||||
- persistentvolumeclaims
|
||||
- events
|
||||
- configmaps
|
||||
- secrets
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- apps
|
||||
- extensions
|
||||
resources:
|
||||
- deployments
|
||||
- daemonsets
|
||||
- replicasets
|
||||
- statefulsets
|
||||
- ingresses
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- monitoring.coreos.com
|
||||
resources:
|
||||
- servicemonitors
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- apiGroups:
|
||||
- apps
|
||||
resourceNames:
|
||||
- awx-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- replicasets
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
serviceAccountName: awx-operator
|
||||
- rules:
|
||||
- apiGroups:
|
||||
- route.openshift.io
|
||||
resources:
|
||||
- routes
|
||||
- routes/custom-host
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- pods
|
||||
- services
|
||||
- services/finalizers
|
||||
- serviceaccounts
|
||||
- endpoints
|
||||
- persistentvolumeclaims
|
||||
- events
|
||||
- configmaps
|
||||
- secrets
|
||||
- roles
|
||||
- rolebindings
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- apps
|
||||
- extensions
|
||||
resources:
|
||||
- deployments
|
||||
- daemonsets
|
||||
- replicasets
|
||||
- statefulsets
|
||||
- ingresses
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- monitoring.coreos.com
|
||||
resources:
|
||||
- servicemonitors
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- apiGroups:
|
||||
- apps
|
||||
resourceNames:
|
||||
- awx-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- deployments/scale
|
||||
verbs:
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- replicasets
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
serviceAccountName: awx-operator
|
||||
deployments:
|
||||
- name: awx-operator
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
- name: awx-operator
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
name: awx-operator
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: awx-operator
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: awx-operator
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /usr/local/bin/ao-logs
|
||||
- /tmp/ansible-operator/runner
|
||||
- stdout
|
||||
image: ansible/awx-operator:0.5.0
|
||||
imagePullPolicy: Always
|
||||
name: ansible
|
||||
resources: {}
|
||||
volumeMounts:
|
||||
- mountPath: /tmp/ansible-operator/runner
|
||||
name: runner
|
||||
readOnly: true
|
||||
- env:
|
||||
- name: WATCH_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.annotations['olm.targetNamespaces']
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: OPERATOR_NAME
|
||||
value: awx-operator
|
||||
image: ansible/awx-operator:0.5.0
|
||||
imagePullPolicy: Always
|
||||
name: operator
|
||||
resources: {}
|
||||
volumeMounts:
|
||||
- mountPath: /tmp/ansible-operator/runner
|
||||
name: runner
|
||||
serviceAccountName: awx-operator
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: runner
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: WATCH_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.annotations['olm.targetNamespaces']
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: OPERATOR_NAME
|
||||
value: awx-operator
|
||||
- name: ANSIBLE_GATHERING
|
||||
value: explicit
|
||||
image: quay.io/ansible/awx-operator:0.8.0
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 6789
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
name: awx-operator
|
||||
resources: {}
|
||||
volumeMounts:
|
||||
- mountPath: /tmp/ansible-operator/runner
|
||||
name: runner
|
||||
serviceAccountName: awx-operator
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: runner
|
||||
strategy: deployment
|
||||
installModes:
|
||||
- supported: true
|
||||
type: OwnNamespace
|
||||
- supported: true
|
||||
type: SingleNamespace
|
||||
- supported: false
|
||||
type: MultiNamespace
|
||||
- supported: true
|
||||
type: AllNamespaces
|
||||
- supported: true
|
||||
type: OwnNamespace
|
||||
- supported: true
|
||||
type: SingleNamespace
|
||||
- supported: false
|
||||
type: MultiNamespace
|
||||
- supported: true
|
||||
type: AllNamespaces
|
||||
keywords:
|
||||
- awx
|
||||
- awx
|
||||
links:
|
||||
- name: Awx Operator
|
||||
url: https://github.com/ansible/awx-operator
|
||||
- name: Awx Operator
|
||||
url: https://github.com/ansible/awx-operator
|
||||
maintainers:
|
||||
- email: yguenane@redhat.com
|
||||
name: Yanis Guenane
|
||||
- email: yguenane@redhat.com
|
||||
name: Yanis Guenane
|
||||
maturity: alpha
|
||||
provider:
|
||||
name: AWX Community
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
@@ -12,43 +11,322 @@ spec:
|
||||
plural: awxs
|
||||
singular: awx
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
properties:
|
||||
spec:
|
||||
properties:
|
||||
external_database:
|
||||
description: |
|
||||
If true you must supply a secret containing the location and credentials for
|
||||
connecting to the external database by a user who has permission to create
|
||||
and apply a schema.
|
||||
|
||||
The secret should have the name: <custom resource name>-postgres-configuration and
|
||||
should look like:
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <crname>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
host: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
type: boolean
|
||||
type: object
|
||||
type: object
|
||||
version: v1beta1
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
- name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
properties:
|
||||
spec:
|
||||
properties:
|
||||
ca_trust_bundle:
|
||||
description: Path where the trusted CA bundle is available
|
||||
type: string
|
||||
deployment_type:
|
||||
description: Name of the deployment type
|
||||
type: string
|
||||
development_mode:
|
||||
description: If the deployment should be done in development mode
|
||||
type: boolean
|
||||
ldap_cacert_secret:
|
||||
description: Secret where can be found the LDAP trusted Certificate
|
||||
Authority Bundle
|
||||
type: string
|
||||
tower_admin_email:
|
||||
description: The admin user email
|
||||
type: string
|
||||
tower_admin_password_secret:
|
||||
description: Secret where the admin password can be found
|
||||
type: string
|
||||
tower_admin_user:
|
||||
default: admin
|
||||
description: Username to use for the admin account
|
||||
type: string
|
||||
tower_broadcast_websocket_secret:
|
||||
description: Secret where the broadcast websocket secret can be found
|
||||
type: string
|
||||
tower_create_preload_data:
|
||||
default: true
|
||||
description: Whether or not to preload data upon Tower instance creation
|
||||
type: boolean
|
||||
tower_ee_images:
|
||||
description: Registry path to the Execution Environment container
|
||||
to use
|
||||
items:
|
||||
properties:
|
||||
image:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
tower_extra_volumes:
|
||||
description: Specify extra volumes to add to the application pod
|
||||
type: string
|
||||
tower_garbage_collect_secrets:
|
||||
default: false
|
||||
description: Whether or not to remove secrets upon instance removal
|
||||
type: boolean
|
||||
tower_hostname:
|
||||
description: The hostname of the instance
|
||||
type: string
|
||||
tower_image:
|
||||
description: Registry path to the application container to use
|
||||
type: string
|
||||
tower_image_pull_policy:
|
||||
default: IfNotPresent
|
||||
description: The image pull policy
|
||||
enum:
|
||||
- Always
|
||||
- always
|
||||
- Never
|
||||
- never
|
||||
- IfNotPresent
|
||||
- ifnotpresent
|
||||
type: string
|
||||
tower_image_pull_secret:
|
||||
description: The image pull secret
|
||||
type: string
|
||||
tower_ingress_annotations:
|
||||
description: Annotations to add to the ingress
|
||||
type: string
|
||||
tower_ingress_tls_secret:
|
||||
description: Secret where the ingress TLS secret can be found
|
||||
type: string
|
||||
tower_ingress_type:
|
||||
description: The ingress type to use to reach the deployed instance
|
||||
enum:
|
||||
- none
|
||||
- Ingress
|
||||
- ingress
|
||||
- Route
|
||||
- route
|
||||
- LoadBalancer
|
||||
- loadbalancer
|
||||
type: string
|
||||
tower_loadbalancer_annotations:
|
||||
description: Annotations to add to the loadbalancer
|
||||
type: string
|
||||
tower_loadbalancer_port:
|
||||
default: 80
|
||||
description: Port to use for the loadbalancer
|
||||
type: integer
|
||||
tower_loadbalancer_protocol:
|
||||
default: http
|
||||
description: Protocol to use for the loadbalancer
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
type: string
|
||||
tower_node_selector:
|
||||
description: nodeSelector for the AWX pods
|
||||
type: string
|
||||
tower_old_postgres_configuration_secret:
|
||||
description: Secret where the old database configuration can be found
|
||||
for data migration
|
||||
type: string
|
||||
tower_postgres_configuration_secret:
|
||||
description: Secret where the database configuration can be found
|
||||
type: string
|
||||
tower_postgres_data_path:
|
||||
description: Path where the PostgreSQL data are located
|
||||
type: string
|
||||
tower_postgres_image:
|
||||
description: Registry path to the PostgreSQL container to use
|
||||
type: string
|
||||
tower_postgres_resource_requirements:
|
||||
description: Resource requirements for the PostgreSQL container
|
||||
properties:
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_postgres_storage_class:
|
||||
description: Storage class to use for the PostgreSQL PVC
|
||||
type: string
|
||||
tower_projects_existing_claim:
|
||||
description: PersistentVolumeClaim to mount /var/lib/projects directory
|
||||
type: string
|
||||
tower_projects_persistence:
|
||||
default: false
|
||||
description: Whether or not the /var/lib/projects directory will be
|
||||
persistent
|
||||
type: boolean
|
||||
tower_projects_storage_access_mode:
|
||||
default: ReadWriteMany
|
||||
description: AccessMode for the /var/lib/projects PersistentVolumeClaim
|
||||
type: string
|
||||
tower_projects_storage_class:
|
||||
description: Storage class for the /var/lib/projects PersistentVolumeClaim
|
||||
type: string
|
||||
tower_projects_storage_size:
|
||||
default: 8Gi
|
||||
description: Size for the /var/lib/projects PersistentVolumeClaim
|
||||
type: string
|
||||
tower_projects_use_existing_claim:
|
||||
description: Using existing PersistentVolumeClaim
|
||||
enum:
|
||||
- _Yes_
|
||||
- _No_
|
||||
type: string
|
||||
tower_redis_image:
|
||||
description: Registry path to the redis container to use
|
||||
type: string
|
||||
tower_replicas:
|
||||
default: 1
|
||||
description: Number of instance replicas
|
||||
format: int32
|
||||
type: integer
|
||||
tower_route_host:
|
||||
description: The DNS to use to points to the instance
|
||||
type: string
|
||||
tower_route_tls_secret:
|
||||
description: Secret where the TLS related credentials are stored
|
||||
type: string
|
||||
tower_route_tls_termination_mechanism:
|
||||
default: Edge
|
||||
description: The secure TLS termination mechanism to use
|
||||
enum:
|
||||
- Edge
|
||||
- edge
|
||||
- Passthrough
|
||||
- passthrough
|
||||
type: string
|
||||
tower_secret_key_secret:
|
||||
description: Secret where the secret key can be found
|
||||
type: string
|
||||
tower_task_args:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
tower_task_command:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
tower_task_extra_env:
|
||||
type: string
|
||||
tower_task_extra_volume_mounts:
|
||||
type: string
|
||||
tower_task_privileged:
|
||||
default: false
|
||||
description: If a privileged security context should be enabled
|
||||
type: boolean
|
||||
tower_task_resource_requirements:
|
||||
description: Resource requirements for the task container
|
||||
properties:
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
tower_tolerations:
|
||||
description: node tolerations for the AWX pods
|
||||
type: string
|
||||
tower_web_args:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
tower_web_command:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
tower_web_extra_env:
|
||||
type: string
|
||||
tower_web_extra_volume_mounts:
|
||||
type: string
|
||||
tower_web_resource_requirements:
|
||||
description: Resource requirements for the web container
|
||||
properties:
|
||||
limits:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
requests:
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
memory:
|
||||
type: string
|
||||
storage:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
conditions:
|
||||
description: The resulting conditions when a Service Telemetry is
|
||||
instantiated
|
||||
items:
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
towerAdminPasswordSecret:
|
||||
description: Admin password of the deployed instance
|
||||
type: string
|
||||
towerAdminUser:
|
||||
description: Admin user of the deployed instance
|
||||
type: string
|
||||
towerImage:
|
||||
description: URL of the image used for the deployed instance
|
||||
type: string
|
||||
towerMigratedFromSecret:
|
||||
description: The secret used for migrating an old Tower.
|
||||
type: string
|
||||
towerURL:
|
||||
description: URL to access the deployed instance
|
||||
type: string
|
||||
towerVersion:
|
||||
description: Version of the deployed instance
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
---
|
||||
annotations:
|
||||
operators.operatorframework.io.bundle.channel.default.v1: alpha
|
||||
operators.operatorframework.io.bundle.channels.v1: alpha
|
||||
|
||||
58
docs/migration.md
Normal file
58
docs/migration.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Migrating data from an old AWX instance
|
||||
|
||||
To migrate data from an older AWX installation, you must provide some information via Secrets.
|
||||
|
||||
## Creating Secrets for Migration
|
||||
|
||||
### Secret Key
|
||||
|
||||
You can find your old secret key in the inventory file you used to deploy AWX in releases prior to version 18.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <resourcename>-secret-key
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
secret_key: <old-secret-key>
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
**Note**: `<resourcename>` must match the `name` of the AWX object you are creating. In our example below, it is `awx`.
|
||||
|
||||
### Old Database Credentials
|
||||
|
||||
The secret should be formatted as follows:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <resourcename>-old-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
host: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
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.
|
||||
|
||||
## Deploy AWX
|
||||
|
||||
When you apply your AWX object, you must specify the name to the database secret you created above:
|
||||
|
||||
```yaml
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: awx
|
||||
spec:
|
||||
tower_old_postgres_configuration_secret: <resourcename>-old-postgres-configuration
|
||||
...
|
||||
```
|
||||
@@ -7,12 +7,31 @@
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
|
||||
tasks:
|
||||
- name: Get AWX Kind data
|
||||
k8s_info:
|
||||
api_version: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
namespace: example-awx
|
||||
label_selectors:
|
||||
- "app.kubernetes.io/name=example-awx"
|
||||
- "app.kubernetes.io/part-of=example-awx"
|
||||
- "app.kubernetes.io/managed-by=awx-operator"
|
||||
- "app.kubernetes.io/component=awx"
|
||||
register: awx_kind
|
||||
|
||||
- name: Verify there is one AWX kind
|
||||
assert:
|
||||
that: '{{ (awx_kind.resources | length) == 1 }}'
|
||||
|
||||
- name: Get AWX Pod data
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: example-awx
|
||||
label_selectors:
|
||||
- app=awx
|
||||
- "app.kubernetes.io/name=example-awx"
|
||||
- "app.kubernetes.io/part-of=example-awx"
|
||||
- "app.kubernetes.io/managed-by=awx-operator"
|
||||
- "app.kubernetes.io/component=awx"
|
||||
register: tower_pods
|
||||
|
||||
- name: Verify there is one AWX pod
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
roles:
|
||||
- awx
|
||||
- installer
|
||||
|
||||
- import_playbook: '{{ playbook_dir }}/asserts.yml'
|
||||
|
||||
2
molecule/test-local/ansible.cfg
Normal file
2
molecule/test-local/ansible.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
[defaults]
|
||||
stdout_callback = yaml
|
||||
@@ -97,8 +97,8 @@
|
||||
kind=custom_resource.kind,
|
||||
api_version=custom_resource.apiVersion,
|
||||
namespace=custom_resource.metadata.namespace,
|
||||
resource_name=custom_resource.metadata.name
|
||||
)}}'
|
||||
resource_name=custom_resource.metadata.name)
|
||||
}}'
|
||||
|
||||
- name: debug awx deployment
|
||||
ignore_errors: yes
|
||||
@@ -110,13 +110,13 @@
|
||||
kind="Deployment",
|
||||
api_version="apps/v1",
|
||||
namespace=custom_resource.metadata.namespace,
|
||||
label_selector="app=awx"
|
||||
)}}'
|
||||
label_selector="app.kubernetes.io/name=example-awx")
|
||||
}}'
|
||||
|
||||
- name: get operator logs
|
||||
ignore_errors: yes
|
||||
failed_when: false
|
||||
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ operator_namespace }} -c operator
|
||||
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ operator_namespace }}
|
||||
environment:
|
||||
KUBECONFIG: '{{ lookup("env", "KUBECONFIG") }}'
|
||||
vars:
|
||||
|
||||
@@ -11,7 +11,7 @@ platforms:
|
||||
- name: kind-test-local
|
||||
groups:
|
||||
- k8s
|
||||
image: bsycorp/kind:latest-1.15
|
||||
image: bsycorp/kind:v1.17.9
|
||||
privileged: True
|
||||
override_command: no
|
||||
exposed_ports:
|
||||
|
||||
@@ -105,8 +105,8 @@
|
||||
kind=custom_resource.kind,
|
||||
api_version=custom_resource.apiVersion,
|
||||
namespace=custom_resource.metadata.namespace,
|
||||
resource_name=custom_resource.metadata.name
|
||||
)}}'
|
||||
resource_name=custom_resource.metadata.name)
|
||||
}}'
|
||||
|
||||
- name: debug awx deployment
|
||||
ignore_errors: yes
|
||||
@@ -118,8 +118,8 @@
|
||||
kind="Deployment",
|
||||
api_version="apps/v1",
|
||||
namespace=custom_resource.metadata.namespace,
|
||||
label_selector="app=awx"
|
||||
)}}'
|
||||
label_selector="app.kubernetes.io/name=example-awx")
|
||||
}}'
|
||||
|
||||
- name: get operator logs
|
||||
ignore_errors: yes
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
---
|
||||
tower_task_privileged: false
|
||||
tower_ingress_type: none
|
||||
|
||||
# Add annotations to the ingress. Specify as literal block. E.g.:
|
||||
# tower_ingress_annotations: |
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s
|
||||
tower_ingress_annotations: ''
|
||||
# TLS secret for the ingress. The 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.
|
||||
tower_ingress_tls_secret: ''
|
||||
|
||||
tower_hostname: example-awx.test
|
||||
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
|
||||
# Add extra volumes to the AWX pod. Specify as literal block. E.g.:
|
||||
# tower_extra_volumes: |
|
||||
# - name: my-volume
|
||||
# emptyDir: {}
|
||||
tower_extra_volumes: ''
|
||||
|
||||
# Use these image versions for Ansible AWX.
|
||||
|
||||
tower_image: ansible/awx:15.0.0
|
||||
tower_image_pull_policy: IfNotPresent
|
||||
|
||||
tower_create_preload_data: true
|
||||
|
||||
tower_replicas: "1"
|
||||
|
||||
tower_task_args:
|
||||
- /usr/bin/launch_awx_task.sh
|
||||
tower_task_command: []
|
||||
tower_web_args: []
|
||||
tower_web_command: []
|
||||
|
||||
tower_task_mem_request: 1Gi
|
||||
tower_task_cpu_request: 500m
|
||||
|
||||
tower_web_mem_request: 2Gi
|
||||
tower_web_cpu_request: 1000m
|
||||
|
||||
# Add extra environment variables to the AWX task/web containers. Specify as
|
||||
# literal block. E.g.:
|
||||
# tower_task_extra_env: |
|
||||
# - name: FOO
|
||||
# value: bar
|
||||
# - name: BAZ
|
||||
# value: bing
|
||||
tower_task_extra_env: ''
|
||||
tower_web_extra_env: ''
|
||||
|
||||
# Mount extra volumes on the AWX task/web containers. Specify as literal block.
|
||||
# E.g.:
|
||||
# tower_task_extra_volume_mounts: ''
|
||||
# - name: my-volume
|
||||
# mountPath: /some/path
|
||||
tower_task_extra_volume_mounts: ''
|
||||
tower_web_extra_volume_mounts: ''
|
||||
|
||||
tower_redis_image: redis:latest
|
||||
|
||||
tower_postgres_pass: awxpass
|
||||
tower_postgres_image: postgres:12
|
||||
tower_postgres_storage_request: 8Gi
|
||||
tower_postgres_storage_class: ''
|
||||
|
||||
tower_postgres_data_path: '/var/lib/postgresql/data/pgdata'
|
||||
|
||||
tower_postgres_port: 5432
|
||||
|
||||
ca_trust_bundle: "/etc/pki/tls/certs/ca-bundle.crt"
|
||||
|
||||
development_mode: false
|
||||
@@ -1,111 +0,0 @@
|
||||
---
|
||||
- name: Check for existing secret key
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
register: secret_key_resources
|
||||
|
||||
- name: Check for existing postgres configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: postgres_config_resources
|
||||
|
||||
- name: Create Database configuration if it doesn't already exist
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower_postgres_secret.yaml.j2') }}"
|
||||
register: k8s_postgres_config_result
|
||||
when: postgres_config_resources['resources'] | length < 1 and not external_database | default(False) | bool
|
||||
|
||||
- name: Create Database if External Database not selected
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower_postgres.yaml.j2') }}"
|
||||
register: k8s_postgres_result
|
||||
when: not external_database | default(False) | bool
|
||||
|
||||
- name: Read Database Configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: postgres_configuration
|
||||
|
||||
- name: Store Database Configuration
|
||||
set_fact:
|
||||
awx_postgres_user: "{{ postgres_configuration['resources'][0]['data']['username'] | b64decode }}"
|
||||
awx_postgres_pass: "{{ postgres_configuration['resources'][0]['data']['password'] | b64decode }}"
|
||||
awx_postgres_database: "{{ postgres_configuration['resources'][0]['data']['database'] | b64decode }}"
|
||||
awx_postgres_port: "{{ postgres_configuration['resources'][0]['data']['port'] | b64decode }}"
|
||||
awx_postgres_host: "{{ postgres_configuration['resources'][0]['data']['host'] | b64decode }}"
|
||||
|
||||
- name: Deploy Tower Secret Key if needed
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower_secret.yaml.j2') }}"
|
||||
register: k8s_tower_secret_result
|
||||
when: secret_key_resources['resources'] | length < 1
|
||||
|
||||
- name: Ensure configured AWX resources exist in the cluster.
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', item) | from_yaml_all | list }}"
|
||||
register: k8s_defs_result
|
||||
with_items:
|
||||
- tower_config.yaml.j2
|
||||
|
||||
- name: Apply Tower Deployment Configuration
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower.yaml.j2') }}"
|
||||
register: tower_deployment_result
|
||||
|
||||
- name: Get the AWX pod information.
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: '{{ meta.namespace }}'
|
||||
label_selectors:
|
||||
- app=awx
|
||||
register: tower_pods
|
||||
until: "tower_pods['resources'][0]['status']['phase'] == 'Running'"
|
||||
delay: 5
|
||||
retries: 60
|
||||
|
||||
- name: Set the awx pod name as a variable.
|
||||
set_fact:
|
||||
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Verify tower_pod_name is populated.
|
||||
assert:
|
||||
that: tower_pod_name != ''
|
||||
fail_msg: "Could not find the tower pod's name."
|
||||
|
||||
- name: Check if database is populated (auth_user table exists).
|
||||
community.kubernetes.k8s_exec:
|
||||
namespace: "{{ meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "echo 'from django.db import connection;
|
||||
tbl = \"auth_user\" in connection.introspection.table_names();
|
||||
exit(0 if tbl else 1)'
|
||||
| awx-manage shell"
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
register: database_check
|
||||
when: k8s_defs_result is not changed
|
||||
|
||||
- name: Migrate the database if the K8s resources were updated. # noqa 305
|
||||
community.kubernetes.k8s_exec:
|
||||
namespace: "{{ meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage migrate --noinput"
|
||||
register: migrate_result
|
||||
when: (k8s_defs_result is changed) or (database_check is defined and database_check.return_code != 0)
|
||||
|
||||
- include_tasks: initialize.yml
|
||||
@@ -1,5 +0,0 @@
|
||||
DATABASE_USER={{ awx_postgres_user }}
|
||||
DATABASE_NAME={{ awx_postgres_database }}
|
||||
DATABASE_HOST={{ awx_postgres_host }}
|
||||
DATABASE_PORT={{ awx_postgres_port }}
|
||||
DATABASE_PASSWORD={{ awx_postgres_pass }}
|
||||
@@ -1,13 +0,0 @@
|
||||
# Postgres Secret.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
stringData:
|
||||
password: '{{ lookup('password', 'p' + meta.name + 'pg length=32 chars=ascii_letters,digits') }}'
|
||||
username: 'awx'
|
||||
database: 'awx'
|
||||
port: '5432'
|
||||
host: {{ meta.name }}-postgres
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
stringData:
|
||||
secret_key: '{{ lookup('password', 'ts' + meta.name + 'pg length=32 chars=ascii_letters,digits') }}'
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
- name: Check for existing secret key
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
register: secret_key_resources
|
||||
|
||||
- name: Check for existing postgres configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: postgres_config_resources
|
||||
|
||||
- name: Remove ownerReferences from PG configuration if it exists
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
ownerReferences: null
|
||||
when: postgres_config_resources['resources'] | length > 0
|
||||
|
||||
- name: Remove ownerReferences from Tower Secret if it exists
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
ownerReferences: null
|
||||
when: secret_key_resources['resources'] | length > 0
|
||||
21
roles/finalizer/defaults/main.yml
Normal file
21
roles/finalizer/defaults/main.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
# Whether secrets should be garbage collected
|
||||
# on teardown
|
||||
#
|
||||
tower_garbage_collect_secrets: false
|
||||
|
||||
# Secret to lookup that provide the admin password
|
||||
#
|
||||
tower_admin_password_secret: ''
|
||||
|
||||
# Secret to lookup that provide the secret key
|
||||
#
|
||||
tower_secret_key_secret: ''
|
||||
|
||||
# Secret to lookup that provide the PostgreSQL configuration
|
||||
#
|
||||
tower_postgres_configuration_secret: ''
|
||||
|
||||
# Secret to lookup that provide the broadcast websocket key
|
||||
#
|
||||
tower_broadcast_websocket_secret: ''
|
||||
27
roles/finalizer/tasks/main.yml
Normal file
27
roles/finalizer/tasks/main.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
- block:
|
||||
- name: Define secrets name
|
||||
set_fact:
|
||||
_admin_password: '{{ tower_admin_password_secret | length | ternary(tower_admin_password_secret, meta.name + "-admin-password") }}'
|
||||
_secret_key: '{{ tower_secret_key_secret | length | ternary(tower_secret_key_secret, meta.name + "-secret-key") }}'
|
||||
# yamllint disable-line rule:line-length
|
||||
_broadcast_websocket_secret: '{{ tower_broadcast_websocket_secret | length | ternary(tower_broadcast_websocket_secret, meta.name + "-broadcast-websocket") }}' # noqa 204
|
||||
# yamllint disable-line rule:line-length
|
||||
_postgres_configuration: '{{ tower_postgres_configuration_secret | length | ternary(tower_postgres_configuration_secret, meta.name + "-postgres-configuration") }}' # noqa 204
|
||||
|
||||
- name: Remove ownerReferences reference
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ item }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
ownerReferences: null
|
||||
loop:
|
||||
- '{{ _admin_password }}'
|
||||
- '{{ _secret_key }}'
|
||||
- '{{ _postgres_configuration }}'
|
||||
- '{{ _broadcast_websocket_secret }}'
|
||||
|
||||
when: not tower_garbage_collect_secrets | bool
|
||||
162
roles/installer/defaults/main.yml
Normal file
162
roles/installer/defaults/main.yml
Normal file
@@ -0,0 +1,162 @@
|
||||
---
|
||||
deployment_type: awx
|
||||
|
||||
database_name: "{{ deployment_type }}"
|
||||
database_username: "{{ deployment_type }}"
|
||||
|
||||
tower_task_privileged: false
|
||||
tower_ingress_type: none
|
||||
|
||||
# Add annotations to the ingress. Specify as literal block. E.g.:
|
||||
# tower_ingress_annotations: |
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s
|
||||
tower_ingress_annotations: ''
|
||||
# TLS secret for the ingress. The 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.
|
||||
tower_ingress_tls_secret: ''
|
||||
|
||||
tower_loadbalancer_protocol: 'http'
|
||||
tower_loadbalancer_port: '80'
|
||||
|
||||
# The TLS termination mechanism to use to access
|
||||
# the services. Supported mechanism are: edge, passthrough
|
||||
#
|
||||
tower_route_tls_termination_mechanism: edge
|
||||
|
||||
# Secret to lookup that provide the TLS specific
|
||||
# credentials to deploy
|
||||
#
|
||||
tower_route_tls_secret: ''
|
||||
|
||||
# Host to create the root with.
|
||||
# If not specific will default to <instance-name>-<namespace>-<routerCanonicalHostname>
|
||||
#
|
||||
tower_route_host: ''
|
||||
|
||||
tower_hostname: '{{ deployment_type }}.example.com'
|
||||
|
||||
# Add a nodeSelector for the AWX pods. It must match a node's labels for the pod
|
||||
# to be scheduled on that node. Specify as literal block. E.g.:
|
||||
# tower_node_selector: |
|
||||
# disktype: ssd
|
||||
# kubernetes.io/arch: amd64
|
||||
# kubernetes.io/os: linux
|
||||
tower_node_selector: ''
|
||||
|
||||
# Add node tolerations for the AWX pods. Specify as literal block. E.g.:
|
||||
# tower_tolerations: |
|
||||
# - key: "dedicated"
|
||||
# operator: "Equal"
|
||||
# value: "AWX"
|
||||
# effect: "NoSchedule"
|
||||
tower_tolerations: ''
|
||||
|
||||
tower_admin_user: admin
|
||||
tower_admin_email: test@example.com
|
||||
|
||||
# Secret to lookup that provide the admin password
|
||||
#
|
||||
tower_admin_password_secret: ''
|
||||
|
||||
# Secret to lookup that provide the broadcast websocket key
|
||||
#
|
||||
tower_broadcast_websocket_secret: ''
|
||||
|
||||
# Secret to lookup that provide the secret key
|
||||
#
|
||||
tower_secret_key_secret: ''
|
||||
|
||||
# Secret to lookup that provides old database credentials (for migration)
|
||||
|
||||
tower_old_postgres_configuration_secret: ''
|
||||
|
||||
# Add extra volumes to the AWX pod. Specify as literal block. E.g.:
|
||||
# tower_extra_volumes: |
|
||||
# - name: my-volume
|
||||
# emptyDir: {}
|
||||
tower_extra_volumes: ''
|
||||
|
||||
# Use these image versions for Ansible AWX.
|
||||
|
||||
tower_image: quay.io/ansible/awx:19.0.0
|
||||
tower_image_pull_policy: IfNotPresent
|
||||
tower_image_pull_secret: ''
|
||||
|
||||
tower_ee_images:
|
||||
- name: AWX EE 0.1.1
|
||||
image: quay.io/ansible/awx-ee:0.1.1
|
||||
|
||||
tower_create_preload_data: true
|
||||
|
||||
tower_replicas: "1"
|
||||
|
||||
tower_task_args:
|
||||
- /usr/bin/launch_awx_task.sh
|
||||
tower_task_command: []
|
||||
tower_web_args: []
|
||||
tower_web_command: []
|
||||
|
||||
tower_task_resource_requirements:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
tower_web_resource_requirements:
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
# Add extra environment variables to the AWX task/web containers. Specify as
|
||||
# literal block. E.g.:
|
||||
# tower_task_extra_env: |
|
||||
# - name: FOO
|
||||
# value: bar
|
||||
# - name: BAZ
|
||||
# value: bing
|
||||
tower_task_extra_env: ''
|
||||
tower_web_extra_env: ''
|
||||
|
||||
# Mount extra volumes on the AWX task/web containers. Specify as literal block.
|
||||
# E.g.:
|
||||
# tower_task_extra_volume_mounts: ''
|
||||
# - name: my-volume
|
||||
# mountPath: /some/path
|
||||
tower_task_extra_volume_mounts: ''
|
||||
tower_web_extra_volume_mounts: ''
|
||||
|
||||
tower_redis_image: redis:latest
|
||||
|
||||
tower_postgres_image: postgres:12
|
||||
tower_postgres_resource_requirements:
|
||||
requests:
|
||||
storage: 8Gi
|
||||
tower_postgres_storage_class: ''
|
||||
tower_postgres_data_path: '/var/lib/postgresql/data/pgdata'
|
||||
|
||||
# Persistence to the AWX project data folder
|
||||
# Whether or not the /var/lib/projects directory will be persistent
|
||||
tower_projects_persistence: false
|
||||
#
|
||||
# Define an existing PersistentVolumeClaim to use
|
||||
tower_projects_existing_claim: ''
|
||||
#
|
||||
# Define the storage_class, size and access_mode
|
||||
# when not using an existing claim
|
||||
tower_projects_storage_class: ''
|
||||
tower_projects_storage_size: 8Gi
|
||||
tower_projects_storage_access_mode: ReadWriteMany
|
||||
|
||||
# Secret to lookup that provide the PostgreSQL configuration
|
||||
#
|
||||
tower_postgres_configuration_secret: ''
|
||||
|
||||
ca_trust_bundle: "/etc/pki/tls/certs/ca-bundle.crt"
|
||||
|
||||
# Secret to lookup that provides the LDAP CACert trusted bundle
|
||||
#
|
||||
ldap_cacert_secret: ''
|
||||
|
||||
development_mode: false
|
||||
@@ -29,3 +29,4 @@ dependencies: []
|
||||
|
||||
collections:
|
||||
- community.kubernetes
|
||||
- operator_sdk.util
|
||||
42
roles/installer/tasks/admin_password_configuration.yml
Normal file
42
roles/installer/tasks/admin_password_configuration.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
- name: Check for specified admin password configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ tower_admin_password_secret }}'
|
||||
register: _custom_admin_password
|
||||
when: tower_admin_password_secret | length
|
||||
|
||||
- name: Check for default admin password configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-admin-password'
|
||||
register: _default_admin_password
|
||||
|
||||
- name: Set admin password secret
|
||||
set_fact:
|
||||
_admin_password_secret: '{{ _custom_admin_password["resources"] | default([]) | length | ternary(_custom_admin_password, _default_admin_password) }}'
|
||||
|
||||
- block:
|
||||
- name: Create admin password secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'tower_admin_password_secret.yaml.j2') }}"
|
||||
|
||||
- name: Read admin password secret
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-admin-password'
|
||||
register: _generated_admin_password
|
||||
|
||||
when: not _admin_password_secret['resources'] | default([]) | length
|
||||
|
||||
- name: Set admin password secret
|
||||
set_fact:
|
||||
admin_password_secret: '{{ _generated_admin_password["resources"] | default([]) | length | ternary(_generated_admin_password, _admin_password_secret) }}'
|
||||
|
||||
- name: Store admin password
|
||||
set_fact:
|
||||
tower_admin_password: "{{ admin_password_secret['resources'][0]['data']['password'] | b64decode }}"
|
||||
44
roles/installer/tasks/broadcast_websocket_configuration.yml
Normal file
44
roles/installer/tasks/broadcast_websocket_configuration.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
- name: Check for specified broadcast websocket secret configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ tower_broadcast_websocket_secret }}'
|
||||
register: _custom_broadcast_websocket
|
||||
when: tower_broadcast_websocket_secret | length
|
||||
|
||||
- name: Check for default broadcast websocket secret configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-broadcast-websocket'
|
||||
register: _default_broadcast_websocket
|
||||
|
||||
- name: Set broadcast websocket secret
|
||||
set_fact:
|
||||
# yamllint disable-line rule:line-length
|
||||
_broadcast_websocket_secret: '{{ _custom_broadcast_websocket["resources"] | default([]) | length | ternary(_custom_broadcast_websocket, _default_broadcast_websocket) }}' # noqa 204
|
||||
|
||||
- block:
|
||||
- name: Create broadcast websocket secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'tower_broadcast_websocket_secret.yaml.j2') }}"
|
||||
|
||||
- name: Read broadcast websocket secret
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-broadcast-websocket'
|
||||
register: _generated_broadcast_websocket
|
||||
|
||||
when: not _broadcast_websocket_secret['resources'] | default([]) | length
|
||||
|
||||
- name: Set broadcast websocket secret
|
||||
set_fact:
|
||||
# yamllint disable-line rule:line-length
|
||||
broadcast_websocket_secret: '{{ _generated_broadcast_websocket["resources"] | default([]) | length | ternary(_generated_broadcast_websocket, _broadcast_websocket_secret) }}' # noqa 204
|
||||
|
||||
- name: Store broadcast websocket secret name
|
||||
set_fact:
|
||||
broadcast_websocket_secret_value: "{{ broadcast_websocket_secret['resources'][0]['data']['secret'] | b64decode }}"
|
||||
95
roles/installer/tasks/database_configuration.yml
Normal file
95
roles/installer/tasks/database_configuration.yml
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
- name: Check for specified PostgreSQL configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ tower_postgres_configuration_secret }}'
|
||||
register: _custom_pg_config_resources
|
||||
when: tower_postgres_configuration_secret | length
|
||||
|
||||
- name: Check for default PostgreSQL configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: _default_pg_config_resources
|
||||
|
||||
- name: Check for specified old PostgreSQL configuration secret
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ tower_old_postgres_configuration_secret }}'
|
||||
register: _custom_old_pg_config_resources
|
||||
when: tower_old_postgres_configuration_secret | length
|
||||
|
||||
- name: Check for default old PostgreSQL configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-old-postgres-configuration'
|
||||
register: _default_old_pg_config_resources
|
||||
|
||||
- name: Set old PostgreSQL configuration
|
||||
set_fact:
|
||||
# yamllint disable-line rule:line-length
|
||||
old_pg_config: '{{ _custom_old_pg_config_resources["resources"] | default([]) | length | ternary(_custom_old_pg_config_resources, _default_old_pg_config_resources) }}' # noqa 204
|
||||
|
||||
- name: Set proper database name when migrating from old deployment
|
||||
set_fact:
|
||||
database_name: "{{ old_pg_config['resources'][0]['data']['database'] | b64decode }}"
|
||||
database_username: "{{ old_pg_config['resources'][0]['data']['username'] | b64decode }}"
|
||||
when:
|
||||
- old_pg_config['resources'] is defined
|
||||
- old_pg_config['resources'] | length
|
||||
|
||||
- name: Set PostgreSQL configuration
|
||||
set_fact:
|
||||
_pg_config: '{{ _custom_pg_config_resources["resources"] | default([]) | length | ternary(_custom_pg_config_resources, _default_pg_config_resources) }}'
|
||||
|
||||
- block:
|
||||
- name: Create Database configuration
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'tower_postgres_secret.yaml.j2') }}"
|
||||
|
||||
- name: Read Database Configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: _generated_pg_config_resources
|
||||
when: not _pg_config['resources'] | default([]) | length
|
||||
|
||||
- name: Set PostgreSQL Configuration
|
||||
set_fact:
|
||||
pg_config: '{{ _generated_pg_config_resources["resources"] | default([]) | length | ternary(_generated_pg_config_resources, _pg_config) }}'
|
||||
|
||||
- name: Create Database if no database is specified
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'tower_postgres.yaml.j2') }}"
|
||||
when:
|
||||
- pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed'
|
||||
|
||||
- name: Store Database Configuration
|
||||
set_fact:
|
||||
awx_postgres_user: "{{ pg_config['resources'][0]['data']['username'] | b64decode }}"
|
||||
awx_postgres_pass: "{{ pg_config['resources'][0]['data']['password'] | b64decode }}"
|
||||
awx_postgres_database: "{{ pg_config['resources'][0]['data']['database'] | b64decode }}"
|
||||
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
|
||||
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
|
||||
|
||||
- name: Look up details for this deployment
|
||||
k8s_info:
|
||||
api_version: 'v1beta1' # TODO: How to parameterize this?
|
||||
kind: "AWX" # TODO: How to parameterize this?
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
register: this_awx
|
||||
|
||||
- name: Migrate data from old Openshift instance
|
||||
import_tasks: migrate_data.yml
|
||||
when:
|
||||
- old_pg_config['resources'] is defined
|
||||
- old_pg_config['resources'] | length
|
||||
- this_awx['resources'][0]['status']['towerMigratedFromSecret'] is not defined
|
||||
@@ -23,7 +23,6 @@
|
||||
User.objects.create_superuser('{{ tower_admin_user }}', '{{ tower_admin_email }}', '{{ tower_admin_password }}')\"
|
||||
| awx-manage shell"
|
||||
when: users_result.return_code > 0
|
||||
no_log: true
|
||||
|
||||
- name: Create preload data if necessary. # noqa 305
|
||||
community.kubernetes.k8s_exec:
|
||||
12
roles/installer/tasks/load_ldap_cacert_secret.yml
Normal file
12
roles/installer/tasks/load_ldap_cacert_secret.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Retrieve LDAP CA Certificate Secret
|
||||
community.kubernetes.k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ ldap_cacert_secret }}'
|
||||
register: ldap_cacert
|
||||
|
||||
- name: Load LDAP CA Certificate Secret content
|
||||
set_fact:
|
||||
ldap_cacert_ca_crt: '{{ ldap_cacert["resources"][0]["data"]["ldap-ca.crt"] | b64decode }}'
|
||||
when: '"ldap-ca.crt" in ldap_cacert["resources"][0]["data"]'
|
||||
17
roles/installer/tasks/load_route_tls_secret.yml
Normal file
17
roles/installer/tasks/load_route_tls_secret.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Retrieve Route TLS Secret
|
||||
community.kubernetes.k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ tower_route_tls_secret }}'
|
||||
register: route_tls
|
||||
|
||||
- name: Load Route TLS Secret content
|
||||
set_fact:
|
||||
tower_route_tls_key: '{{ route_tls["resources"][0]["data"]["tls.key"] | b64decode }}'
|
||||
tower_route_tls_crt: '{{ route_tls["resources"][0]["data"]["tls.crt"] | b64decode }}'
|
||||
|
||||
- name: Load Route TLS Secret content
|
||||
set_fact:
|
||||
tower_route_ca_crt: '{{ route_tls["resources"][0]["data"]["ca.crt"] | b64decode }}'
|
||||
when: '"ca.crt" in route_tls["resources"][0]["data"]'
|
||||
113
roles/installer/tasks/main.yml
Normal file
113
roles/installer/tasks/main.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
- name: Patching labels to AWX kind
|
||||
k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
|
||||
- name: Get current version
|
||||
set_fact:
|
||||
tower_image_version: "{{ tower_image.split(':')[1] }}"
|
||||
|
||||
- name: Include secret key configuration tasks
|
||||
include_tasks: secret_key_configuration.yml
|
||||
|
||||
- name: Load LDAP CAcert certificate
|
||||
include_tasks: load_ldap_cacert_secret.yml
|
||||
when:
|
||||
- ldap_cacert_secret != ''
|
||||
|
||||
- name: Include admin password configuration tasks
|
||||
include_tasks: admin_password_configuration.yml
|
||||
|
||||
- name: Include broadcast websocket configuration tasks
|
||||
include_tasks: broadcast_websocket_configuration.yml
|
||||
|
||||
- name: Include database configuration tasks
|
||||
include_tasks: database_configuration.yml
|
||||
|
||||
- name: Load Route TLS certificate
|
||||
include_tasks: load_route_tls_secret.yml
|
||||
when:
|
||||
- tower_ingress_type | lower == 'route'
|
||||
- tower_route_tls_secret != ''
|
||||
|
||||
- name: Ensure configured instance resources exist in the cluster.
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', item) | from_yaml_all | list }}"
|
||||
with_items:
|
||||
- tower_config.yaml.j2
|
||||
|
||||
- name: Apply Resources
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', item + '.yaml.j2') }}"
|
||||
register: tower_deployment_result
|
||||
loop:
|
||||
- 'tower_app_credentials'
|
||||
- 'tower_service_account'
|
||||
- 'tower_persistent'
|
||||
- 'tower_deployment'
|
||||
- 'tower_service'
|
||||
- 'tower_ingress'
|
||||
|
||||
- name: Get the resource pod information.
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: '{{ meta.namespace }}'
|
||||
label_selectors:
|
||||
- "app.kubernetes.io/name={{ meta.name }}"
|
||||
- "app.kubernetes.io/managed-by=awx-operator"
|
||||
- "app.kubernetes.io/component=awx"
|
||||
register: tower_pods
|
||||
until: "tower_pods['resources'][0]['status']['phase'] == 'Running'"
|
||||
delay: 5
|
||||
retries: 60
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Verify the resource pod name is populated.
|
||||
assert:
|
||||
that: tower_pod_name != ''
|
||||
fail_msg: "Could not find the tower pod's name."
|
||||
|
||||
- name: Check for pending migrations
|
||||
k8s_exec:
|
||||
namespace: "{{ meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l"
|
||||
changed_when: false
|
||||
register: database_check
|
||||
|
||||
- name: Migrate the database if the K8s resources were updated. # noqa 305
|
||||
k8s_exec:
|
||||
namespace: "{{ meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage migrate --noinput"
|
||||
register: migrate_result
|
||||
when:
|
||||
- database_check is defined
|
||||
- (database_check.stdout|trim) != '0'
|
||||
|
||||
- include_tasks: initialize.yml
|
||||
|
||||
- name: Update status variables
|
||||
include_tasks: update_status.yml
|
||||
74
roles/installer/tasks/migrate_data.yml
Normal file
74
roles/installer/tasks/migrate_data.yml
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
|
||||
- name: Store Database Configuration
|
||||
set_fact:
|
||||
tower_old_postgres_user: "{{ old_pg_config['resources'][0]['data']['username'] | b64decode }}"
|
||||
tower_old_postgres_pass: "{{ old_pg_config['resources'][0]['data']['password'] | b64decode }}"
|
||||
tower_old_postgres_database: "{{ old_pg_config['resources'][0]['data']['database'] | b64decode }}"
|
||||
tower_old_postgres_port: "{{ old_pg_config['resources'][0]['data']['port'] | b64decode }}"
|
||||
tower_old_postgres_host: "{{ old_pg_config['resources'][0]['data']['host'] | b64decode }}"
|
||||
|
||||
- name: Get the postgres pod information
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: '{{ meta.namespace }}'
|
||||
label_selectors:
|
||||
- "app.kubernetes.io/name={{ meta.name }}-postgres"
|
||||
register: postgres_pod
|
||||
until: "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
|
||||
delay: 5
|
||||
retries: 60
|
||||
|
||||
- name: Set the resource pod name as a variable.
|
||||
set_fact:
|
||||
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Check for presence of Deployment
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
kind: Deployment
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
register: tower_deployment
|
||||
|
||||
- name: Scale down Deployment for migration
|
||||
k8s_scale:
|
||||
api_version: v1
|
||||
kind: Deployment
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
replicas: 0
|
||||
when: tower_deployment['resources'] | length
|
||||
|
||||
- name: Set pg_dump command
|
||||
set_fact:
|
||||
pgdump: >-
|
||||
pg_dump --clean --create
|
||||
-h {{ tower_old_postgres_host }}
|
||||
-U {{ tower_old_postgres_user }}
|
||||
-d {{ tower_old_postgres_database }}
|
||||
-p {{ tower_old_postgres_port }}
|
||||
|
||||
- name: Set pg_restore command
|
||||
set_fact:
|
||||
psql_restore: >-
|
||||
psql -U {{ database_username }}
|
||||
-d template1
|
||||
-p {{ awx_postgres_port }}
|
||||
|
||||
- name: Stream backup from pg_dump to the new postgresql container
|
||||
community.kubernetes.k8s_exec:
|
||||
namespace: "{{ meta.namespace }}"
|
||||
pod: "{{ postgres_pod_name }}"
|
||||
command: |
|
||||
bash -c """
|
||||
set -e -o pipefail
|
||||
PGPASSWORD={{ tower_old_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ psql_restore }}
|
||||
echo 'Successful'
|
||||
"""
|
||||
register: data_migration
|
||||
failed_when: "'Successful' not in data_migration.stdout"
|
||||
|
||||
- name: Set flag signifying that this instance has been migrated
|
||||
set_fact:
|
||||
tower_migrated_from_secret: "{{ tower_old_postgres_configuration_secret }}"
|
||||
42
roles/installer/tasks/secret_key_configuration.yml
Normal file
42
roles/installer/tasks/secret_key_configuration.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
- name: Check for specified secret key configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ tower_secret_key_secret }}'
|
||||
register: _custom_secret_key
|
||||
when: tower_secret_key_secret | length
|
||||
|
||||
- name: Check for default secret key configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
register: _default_secret_key
|
||||
|
||||
- name: Set secret key secret
|
||||
set_fact:
|
||||
_secret_key_secret: '{{ _custom_secret_key["resources"] | default([]) | length | ternary(_custom_secret_key, _default_secret_key) }}'
|
||||
|
||||
- block:
|
||||
- name: Create secret key secret
|
||||
k8s:
|
||||
apply: true
|
||||
definition: "{{ lookup('template', 'tower_secret_key.yaml.j2') }}"
|
||||
|
||||
- name: Read secret key secret
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
register: _generated_secret_key
|
||||
|
||||
when: not _secret_key_secret['resources'] | default([]) | length
|
||||
|
||||
- name: Set secret key secret
|
||||
set_fact:
|
||||
secret_key_secret: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}'
|
||||
|
||||
- name: Store secret key secret name
|
||||
set_fact:
|
||||
secret_key_secret_name: "{{ secret_key_secret['resources'][0]['metadata']['name'] }}"
|
||||
80
roles/installer/tasks/update_status.yml
Normal file
80
roles/installer/tasks/update_status.yml
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
- name: Set apiVersion and kind variables
|
||||
set_fact:
|
||||
api_version: '{{ hostvars["localhost"]["inventory_file"].split("/")[4:6] | join("/") }}'
|
||||
kind: '{{ hostvars["localhost"]["inventory_file"].split("/")[6] }}'
|
||||
|
||||
- name: Update admin password status
|
||||
operator_sdk.util.k8s_status:
|
||||
api_version: '{{ api_version }}'
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
status:
|
||||
towerAdminPasswordSecret: "{{ admin_password_secret['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Update admin user status
|
||||
operator_sdk.util.k8s_status:
|
||||
api_version: '{{ api_version }}'
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
status:
|
||||
towerAdminUser: "{{ tower_admin_user }}"
|
||||
|
||||
- name: Retrieve instance version
|
||||
community.kubernetes.k8s_exec:
|
||||
namespace: "{{ meta.namespace }}"
|
||||
pod: "{{ tower_pod_name }}"
|
||||
container: "{{ meta.name }}-task"
|
||||
command: >-
|
||||
bash -c "awx-manage --version"
|
||||
register: instance_version
|
||||
changed_when: false
|
||||
|
||||
- name: Update version status
|
||||
operator_sdk.util.k8s_status:
|
||||
api_version: '{{ api_version }}'
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
status:
|
||||
towerVersion: "{{ instance_version.stdout | trim }}"
|
||||
|
||||
- name: Update image status
|
||||
operator_sdk.util.k8s_status:
|
||||
api_version: '{{ api_version }}'
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
status:
|
||||
towerImage: "{{ tower_image }}"
|
||||
|
||||
- block:
|
||||
- name: Retrieve route URL
|
||||
community.kubernetes.k8s_info:
|
||||
kind: Route
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}'
|
||||
register: route_url
|
||||
|
||||
- name: Update URL status
|
||||
operator_sdk.util.k8s_status:
|
||||
api_version: '{{ api_version }}'
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
status:
|
||||
towerURL: "https://{{ route_url['resources'][0]['status']['ingress'][0]['host'] }}"
|
||||
|
||||
when: tower_ingress_type | lower == 'route'
|
||||
|
||||
- name: Update towerMigratedFromSecret status
|
||||
operator_sdk.util.k8s_status:
|
||||
api_version: '{{ api_version }}'
|
||||
kind: "{{ kind }}"
|
||||
name: "{{ meta.name }}"
|
||||
namespace: "{{ meta.namespace }}"
|
||||
status:
|
||||
towerMigratedFromSecret: "{{ tower_migrated_from_secret }}"
|
||||
when: tower_migrated_from_secret is defined
|
||||
@@ -4,7 +4,7 @@ DATABASES = {
|
||||
'ENGINE': 'awx.main.db.profiled_pg',
|
||||
'NAME': "{{ awx_postgres_database }}",
|
||||
'USER': "{{ awx_postgres_user }}",
|
||||
'PASSWORD': "{{ awx_postgres_pass }}",
|
||||
'PASSWORD': "{{ awx_postgres_pass | quote }}",
|
||||
'HOST': '{{ awx_postgres_host }}',
|
||||
'PORT': "{{ awx_postgres_port }}",
|
||||
'OPTIONS': { 'sslmode': '{{ pg_sslmode|default("prefer") }}',
|
||||
@@ -13,4 +13,4 @@ DATABASES = {
|
||||
}
|
||||
}
|
||||
|
||||
BROADCAST_WEBSOCKET_SECRET = "{{ tower_broadcast_websocket_secret | b64encode }}"
|
||||
BROADCAST_WEBSOCKET_SECRET = "{{ broadcast_websocket_secret_value }}"
|
||||
5
roles/installer/templates/execution_environments.py.j2
Normal file
5
roles/installer/templates/execution_environments.py.j2
Normal file
@@ -0,0 +1,5 @@
|
||||
DEFAULT_EXECUTION_ENVIRONMENTS = [
|
||||
{% for item in tower_ee_images %}
|
||||
{'name': '{{ item.name }}' , 'image': '{{ item.image }}'}
|
||||
{% endfor %}
|
||||
]
|
||||
6
roles/installer/templates/ldap.py.j2
Normal file
6
roles/installer/templates/ldap.py.j2
Normal file
@@ -0,0 +1,6 @@
|
||||
AUTH_LDAP_GLOBAL_OPTIONS = {
|
||||
{% if ldap_cacert_ca_crt %}
|
||||
ldap.OPT_X_TLS_REQUIRE_CERT: True,
|
||||
ldap.OPT_X_TLS_CACERTFILE: "/etc/openldap/certs/ldap-ca.crt"
|
||||
{% endif %}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-admin-password'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
stringData:
|
||||
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
16
roles/installer/templates/tower_app_credentials.yaml.j2
Normal file
16
roles/installer/templates/tower_app_credentials.yaml.j2
Normal file
@@ -0,0 +1,16 @@
|
||||
# AWX Secret Configurations
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-app-credentials'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
data:
|
||||
credentials.py: "{{ lookup('template', 'credentials.py.j2') | b64encode }}"
|
||||
ldap.py: "{{ lookup('template', 'ldap.py.j2') | b64encode }}"
|
||||
execution_environments.py: "{{ lookup('template', 'execution_environments.py.j2') | b64encode }}"
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-broadcast-websocket'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
stringData:
|
||||
secret: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
@@ -3,17 +3,15 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: '{{ meta.name }}-awx-configmap'
|
||||
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: awx
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
data:
|
||||
environment: |
|
||||
DATABASE_USER=awx
|
||||
DATABASE_NAME=awx
|
||||
DATABASE_HOST='{{ meta.name }}-postgres.{{ meta.namespace }}.svc.cluster.local'
|
||||
DATABASE_PORT='5432'
|
||||
DATABASE_PASSWORD={{ tower_postgres_pass | quote }}
|
||||
AWX_SKIP_MIGRATIONS=true
|
||||
|
||||
settings: |
|
||||
@@ -28,7 +26,9 @@ data:
|
||||
STATIC_ROOT = '/var/lib/awx/public/static'
|
||||
PROJECTS_ROOT = '/var/lib/awx/projects'
|
||||
JOBOUTPUT_ROOT = '/var/lib/awx/job_status'
|
||||
|
||||
|
||||
IS_K8S = True
|
||||
|
||||
SECRET_KEY = get_secret()
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
@@ -64,6 +64,7 @@ data:
|
||||
'()': 'logging.StreamHandler',
|
||||
'level': 'DEBUG',
|
||||
'formatter': 'simple',
|
||||
'filters': ['guid'],
|
||||
}
|
||||
|
||||
LOGGING['loggers']['django.request']['handlers'] = ['console']
|
||||
@@ -83,22 +84,7 @@ data:
|
||||
LOGGING['handlers']['rbac_migrations'] = {'class': 'logging.NullHandler'}
|
||||
LOGGING['handlers']['system_tracking_migrations'] = {'class': 'logging.NullHandler'}
|
||||
LOGGING['handlers']['management_playbooks'] = {'class': 'logging.NullHandler'}
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ATOMIC_REQUESTS': True,
|
||||
'ENGINE': 'awx.main.db.profiled_pg',
|
||||
'NAME': 'awx',
|
||||
'USER': 'awx',
|
||||
'PASSWORD': '{{ tower_postgres_pass | quote }}',
|
||||
'HOST': '{{ meta.name }}-postgres.{{ meta.namespace }}.svc.cluster.local',
|
||||
'PORT': '5432',
|
||||
}
|
||||
}
|
||||
|
||||
if os.getenv("DATABASE_SSLMODE", False):
|
||||
DATABASES['default']['OPTIONS'] = {'sslmode': os.getenv("DATABASE_SSLMODE")}
|
||||
|
||||
|
||||
USE_X_FORWARDED_PORT = True
|
||||
BROADCAST_WEBSOCKET_PORT = 8052
|
||||
BROADCAST_WEBSOCKET_PROTOCOL = 'http'
|
||||
@@ -139,9 +125,27 @@ data:
|
||||
server 127.0.0.1:8051;
|
||||
}
|
||||
|
||||
|
||||
{% if tower_route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
server {
|
||||
listen 8052 default_server;
|
||||
|
||||
server_name _;
|
||||
|
||||
# Redirect all HTTP links to the matching HTTPS page
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
server {
|
||||
{% if tower_route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
listen 8053 ssl;
|
||||
|
||||
ssl_certificate /etc/nginx/pki/web.crt;
|
||||
ssl_certificate_key /etc/nginx/pki/web.key;
|
||||
{% else %}
|
||||
listen 8052 default_server;
|
||||
{% endif %}
|
||||
|
||||
# If you have a domain name, this is where to add it
|
||||
server_name _;
|
||||
keepalive_timeout 65;
|
||||
@@ -210,3 +214,33 @@ data:
|
||||
unixsocketperm 777
|
||||
port 0
|
||||
bind 127.0.0.1
|
||||
receptor_conf: |
|
||||
---
|
||||
- log-level: debug
|
||||
|
||||
- control-service:
|
||||
service: control
|
||||
filename: /var/run/receptor/receptor.sock
|
||||
permissions: 0660
|
||||
|
||||
- local-only:
|
||||
|
||||
- work-command:
|
||||
worktype: local
|
||||
command: ansible-runner
|
||||
params: worker
|
||||
allowruntimeparams: true
|
||||
|
||||
- work-kubernetes:
|
||||
worktype: kubernetes-runtime-auth
|
||||
authmethod: runtime
|
||||
allowruntimeauth: true
|
||||
allowruntimepod: true
|
||||
allowruntimeparams: true
|
||||
|
||||
- work-kubernetes:
|
||||
worktype: kubernetes-incluster-auth
|
||||
authmethod: incluster
|
||||
allowruntimeauth: true
|
||||
allowruntimepod: true
|
||||
allowruntimeparams: true
|
||||
@@ -1,14 +1,3 @@
|
||||
# AWX Secret Configurations
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secrets'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
data:
|
||||
credentials_py: "{{ lookup('template', 'credentials.py.j2') | b64encode }}"
|
||||
environment_sh: "{{ lookup('template', 'environment.sh.j2') | b64encode }}"
|
||||
|
||||
# AWX Deployment.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
@@ -17,17 +6,32 @@ metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: awx
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/version: '{{ tower_image_version }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
spec:
|
||||
replicas: {{ tower_replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: awx
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: awx
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/version: '{{ tower_image_version }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
spec:
|
||||
serviceAccountName: '{{ meta.name }}'
|
||||
{% if tower_image_pull_secret %}
|
||||
imagePullSecrets:
|
||||
- name: {{ tower_image_pull_secret }}
|
||||
{% endif %}
|
||||
containers:
|
||||
- image: '{{ tower_redis_image }}'
|
||||
name: redis
|
||||
@@ -39,6 +43,8 @@ spec:
|
||||
readOnly: true
|
||||
- name: {{ meta.name }}-redis-socket
|
||||
mountPath: "/var/run/redis"
|
||||
- name: "{{ meta.name }}-redis-data"
|
||||
mountPath: "/data"
|
||||
- image: '{{ tower_image }}'
|
||||
name: '{{ meta.name }}-web'
|
||||
{% if tower_web_command %}
|
||||
@@ -50,11 +56,25 @@ spec:
|
||||
imagePullPolicy: '{{ tower_image_pull_policy }}'
|
||||
ports:
|
||||
- containerPort: 8052
|
||||
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
- containerPort: 8053
|
||||
{% endif %}
|
||||
volumeMounts:
|
||||
- name: "{{ meta.name }}-application-credentials"
|
||||
mountPath: "/etc/tower/conf.d/"
|
||||
readOnly: true
|
||||
- name: {{ meta.name }}-secret-key
|
||||
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
- name: "{{ meta.name }}-nginx-certs"
|
||||
mountPath: "/etc/nginx/pki"
|
||||
readOnly: true
|
||||
{% endif %}
|
||||
{% if ldap_cacert_ca_crt %}
|
||||
- name: "{{ meta.name }}-ldap-cacert"
|
||||
mountPath: /etc/openldap/certs/ldap-ca.crt
|
||||
subPath: ldap-ca.crt
|
||||
readOnly: true
|
||||
{% endif %}
|
||||
- name: "{{ secret_key_secret_name }}"
|
||||
mountPath: /etc/tower/SECRET_KEY
|
||||
subPath: SECRET_KEY
|
||||
readOnly: true
|
||||
@@ -81,20 +101,19 @@ spec:
|
||||
{% if tower_web_extra_volume_mounts -%}
|
||||
{{ tower_web_extra_volume_mounts | indent(width=12, indentfirst=True) }}
|
||||
{% endif %}
|
||||
{% if (development_mode | bool) or (tower_task_extra_env | bool) %}
|
||||
env:
|
||||
{% endif %}
|
||||
- name: MY_POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{% if development_mode | bool %}
|
||||
- name: AWX_KUBE_DEVEL
|
||||
value: "1"
|
||||
{% endif %}
|
||||
{% if tower_task_extra_env %}
|
||||
{% if tower_web_extra_env -%}
|
||||
{{ tower_web_extra_env | indent(width=12, indentfirst=True) }}
|
||||
{% endif %}
|
||||
resources:
|
||||
requests:
|
||||
memory: '{{ tower_web_mem_request }}'
|
||||
cpu: '{{ tower_web_cpu_request }}'
|
||||
resources: {{ tower_web_resource_requirements }}
|
||||
- image: '{{ tower_image }}'
|
||||
name: '{{ meta.name }}-task'
|
||||
imagePullPolicy: '{{ tower_image_pull_policy }}'
|
||||
@@ -112,7 +131,7 @@ spec:
|
||||
- name: "{{ meta.name }}-application-credentials"
|
||||
mountPath: "/etc/tower/conf.d/"
|
||||
readOnly: true
|
||||
- name: {{ meta.name }}-secret-key
|
||||
- name: "{{ secret_key_secret_name }}"
|
||||
mountPath: /etc/tower/SECRET_KEY
|
||||
subPath: SECRET_KEY
|
||||
readOnly: true
|
||||
@@ -128,6 +147,10 @@ spec:
|
||||
mountPath: "/var/run/awx-rsyslog"
|
||||
- name: rsyslog-dir
|
||||
mountPath: "/var/lib/awx/rsyslog"
|
||||
- name: receptor-socket
|
||||
mountPath: "/var/run/receptor"
|
||||
- name: "{{ meta.name }}-projects"
|
||||
mountPath: "/var/lib/awx/projects"
|
||||
{% if development_mode | bool %}
|
||||
- name: awx-devel
|
||||
mountPath: "/awx_devel"
|
||||
@@ -137,7 +160,7 @@ spec:
|
||||
{% endif %}
|
||||
env:
|
||||
- name: SUPERVISOR_WEB_CONFIG_PATH
|
||||
value: "/supervisor.conf"
|
||||
value: "/etc/supervisord.conf"
|
||||
- name: AWX_SKIP_MIGRATIONS
|
||||
value: "1"
|
||||
- name: MY_POD_UID
|
||||
@@ -148,6 +171,10 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: MY_POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{% if development_mode | bool %}
|
||||
- name: AWX_KUBE_DEVEL
|
||||
value: "1"
|
||||
@@ -155,51 +182,117 @@ spec:
|
||||
{% if tower_task_extra_env -%}
|
||||
{{ tower_task_extra_env | indent(width=12, indentfirst=True) }}
|
||||
{% endif %}
|
||||
resources:
|
||||
requests:
|
||||
memory: '{{ tower_task_mem_request }}'
|
||||
cpu: '{{ tower_task_cpu_request }}'
|
||||
resources: {{ tower_task_resource_requirements }}
|
||||
- image: '{{ tower_ee_images[0].image }}'
|
||||
name: '{{ meta.name }}-ee'
|
||||
imagePullPolicy: '{{ tower_image_pull_policy }}'
|
||||
args: ['receptor', '--config', '/etc/receptor.conf']
|
||||
volumeMounts:
|
||||
- name: "{{ meta.name }}-receptor-config"
|
||||
mountPath: "/etc/receptor.conf"
|
||||
subPath: receptor.conf
|
||||
readOnly: true
|
||||
- name: receptor-socket
|
||||
mountPath: "/var/run/receptor"
|
||||
- name: "{{ meta.name }}-projects"
|
||||
mountPath: "/var/lib/awx/projects"
|
||||
{% if development_mode | bool %}
|
||||
env:
|
||||
- name: SDB_NOTIFY_HOST
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
{% endif %}
|
||||
{% if tower_node_selector %}
|
||||
nodeSelector:
|
||||
{{ tower_node_selector | indent(width=8) }}
|
||||
{% endif %}
|
||||
{% if tower_tolerations %}
|
||||
tolerations:
|
||||
{{ tower_tolerations | indent(width=8) }}
|
||||
{% endif %}
|
||||
volumes:
|
||||
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
- name: "{{ meta.name }}-nginx-certs"
|
||||
secret:
|
||||
secretName: "{{ tower_route_tls_secret }}"
|
||||
items:
|
||||
- key: tls.key
|
||||
path: 'web.key'
|
||||
- key: tls.crt
|
||||
path: 'web.crt'
|
||||
{% endif %}
|
||||
{% if ldap_cacert_ca_crt %}
|
||||
- name: "{{ meta.name }}-ldap-cacert"
|
||||
secret:
|
||||
secretName: "{{ ldap_cacert_secret }}"
|
||||
items:
|
||||
- key: ldap-ca.crt
|
||||
path: 'ldap-ca.crt'
|
||||
{% endif %}
|
||||
- name: "{{ meta.name }}-application-credentials"
|
||||
secret:
|
||||
secretName: "{{ meta.name }}-secrets"
|
||||
secretName: "{{ meta.name }}-app-credentials"
|
||||
items:
|
||||
- key: credentials_py
|
||||
- key: credentials.py
|
||||
path: 'credentials.py'
|
||||
- key: environment_sh
|
||||
path: 'environment.sh'
|
||||
- name: {{ meta.name }}-secret-key
|
||||
- key: ldap.py
|
||||
path: 'ldap.py'
|
||||
- key: execution_environments.py
|
||||
path: 'execution_environments.py'
|
||||
- name: "{{ secret_key_secret_name }}"
|
||||
secret:
|
||||
secretName: '{{ meta.name }}-secret-key'
|
||||
secretName: '{{ secret_key_secret_name }}'
|
||||
items:
|
||||
- key: secret_key
|
||||
path: SECRET_KEY
|
||||
- name: {{ meta.name }}-settings
|
||||
configMap:
|
||||
name: '{{ meta.name }}-awx-configmap'
|
||||
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
|
||||
items:
|
||||
- key: settings
|
||||
path: settings.py
|
||||
- name: {{ meta.name }}-nginx-conf
|
||||
configMap:
|
||||
name: '{{ meta.name }}-awx-configmap'
|
||||
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
|
||||
items:
|
||||
- key: nginx_conf
|
||||
path: nginx.conf
|
||||
- name: {{ meta.name }}-redis-config
|
||||
configMap:
|
||||
name: {{ meta.name }}-awx-configmap
|
||||
name: {{ meta.name }}-{{ deployment_type }}-configmap
|
||||
items:
|
||||
- key: redis_conf
|
||||
path: redis.conf
|
||||
- name: {{ meta.name }}-redis-socket
|
||||
emptyDir: {}
|
||||
- name: {{ meta.name }}-redis-data
|
||||
emptyDir: {}
|
||||
- name: supervisor-socket
|
||||
emptyDir: {}
|
||||
- name: rsyslog-socket
|
||||
emptyDir: {}
|
||||
- name: receptor-socket
|
||||
emptyDir: {}
|
||||
- name: rsyslog-dir
|
||||
emptyDir: {}
|
||||
- name: {{ meta.name }}-receptor-config
|
||||
configMap:
|
||||
name: '{{ meta.name }}-{{ deployment_type }}-configmap'
|
||||
items:
|
||||
- key: receptor_conf
|
||||
path: receptor.conf
|
||||
- name: "{{ meta.name }}-projects"
|
||||
{% if tower_projects_persistence|bool %}
|
||||
persistentVolumeClaim:
|
||||
{% if tower_projects_existing_claim %}
|
||||
claimName: {{ tower_projects_existing_claim }}
|
||||
{% else %}
|
||||
claimName: '{{ meta.name }}-projects-claim'
|
||||
{% endif %}
|
||||
{% else %}
|
||||
emptyDir: {}
|
||||
{% endif %}
|
||||
{% if development_mode | bool %}
|
||||
- name: awx-devel
|
||||
hostPath:
|
||||
@@ -208,73 +301,3 @@ spec:
|
||||
{% if tower_extra_volumes -%}
|
||||
{{ tower_extra_volumes | indent(width=8, indentfirst=True) }}
|
||||
{% endif %}
|
||||
|
||||
# AWX Service.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: '{{ meta.name }}-service'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: awx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8052
|
||||
name: http
|
||||
selector:
|
||||
app: awx
|
||||
{% if tower_ingress_type != "none" %}
|
||||
type: NodePort
|
||||
{% endif %}
|
||||
|
||||
# AWX Ingress.
|
||||
{% if 'ingress' == tower_ingress_type|lower %}
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: '{{ meta.name }}-ingress'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
{% if tower_ingress_annotations %}
|
||||
annotations:
|
||||
{{ tower_ingress_annotations | indent(width=4) }}
|
||||
{% endif %}
|
||||
spec:
|
||||
rules:
|
||||
- host: '{{ tower_hostname }}'
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: '{{ meta.name }}-service'
|
||||
servicePort: 80
|
||||
{% if tower_ingress_tls_secret %}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ tower_hostname }}
|
||||
secretName: {{ tower_ingress_tls_secret }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if 'route' == tower_ingress_type|lower %}
|
||||
---
|
||||
apiVersion: route.openshift.io/v1
|
||||
kind: Route
|
||||
metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
spec:
|
||||
port:
|
||||
targetPort: http
|
||||
tls:
|
||||
insecureEdgeTerminationPolicy: Redirect
|
||||
termination: edge
|
||||
to:
|
||||
kind: Service
|
||||
name: {{ meta.name }}-service
|
||||
weight: 100
|
||||
wildcardPolicy: None
|
||||
{% endif %}
|
||||
70
roles/installer/templates/tower_ingress.yaml.j2
Normal file
70
roles/installer/templates/tower_ingress.yaml.j2
Normal file
@@ -0,0 +1,70 @@
|
||||
{% if 'ingress' == tower_ingress_type|lower %}
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: '{{ meta.name }}-ingress'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
{% if tower_ingress_annotations %}
|
||||
annotations:
|
||||
{{ tower_ingress_annotations | indent(width=4) }}
|
||||
{% endif %}
|
||||
spec:
|
||||
rules:
|
||||
- host: '{{ tower_hostname }}'
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: '{{ meta.name }}-service'
|
||||
servicePort: 80
|
||||
{% if tower_ingress_tls_secret %}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ tower_hostname }}
|
||||
secretName: {{ tower_ingress_tls_secret }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if 'route' == tower_ingress_type|lower %}
|
||||
---
|
||||
apiVersion: route.openshift.io/v1
|
||||
kind: Route
|
||||
metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
spec:
|
||||
{% if tower_route_host != '' %}
|
||||
host: {{ tower_route_host }}
|
||||
{% endif %}
|
||||
port:
|
||||
targetPort: '{{ (tower_route_tls_termination_mechanism | lower == "passthrough") | ternary("https", "http") }}'
|
||||
tls:
|
||||
insecureEdgeTerminationPolicy: Redirect
|
||||
termination: {{ tower_route_tls_termination_mechanism | lower }}
|
||||
{% if tower_route_tls_termination_mechanism | lower == 'edge' and tower_route_tls_secret != '' %}
|
||||
key: |-
|
||||
{{ tower_route_tls_key | indent(width=6, indentfirst=True) }}
|
||||
certificate: |-
|
||||
{{ tower_route_tls_crt | indent(width=6, indentfirst=True) }}
|
||||
{% if tower_route_ca_crt is defined %}
|
||||
caCertificate: |-
|
||||
{{ tower_route_ca_crt | indent(width=6, indentfirst=True) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
to:
|
||||
kind: Service
|
||||
name: {{ meta.name }}-service
|
||||
weight: 100
|
||||
wildcardPolicy: None
|
||||
{% endif %}
|
||||
21
roles/installer/templates/tower_persistent.yaml.j2
Normal file
21
roles/installer/templates/tower_persistent.yaml.j2
Normal file
@@ -0,0 +1,21 @@
|
||||
{% if tower_projects_persistence|bool and tower_projects_existing_claim == '' %}
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: '{{ meta.name }}-projects-claim'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ tower_projects_storage_access_mode }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ tower_projects_storage_size }}
|
||||
{% if tower_projects_storage_class != '' %}
|
||||
storageClassName: {{ tower_projects_storage_class }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -6,11 +6,16 @@ metadata:
|
||||
name: '{{ meta.name }}-postgres'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: awx-postgres
|
||||
app.kubernetes.io/name: '{{ meta.name }}-postgres'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: database
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: awx-postgres
|
||||
app.kubernetes.io/name: '{{ meta.name }}-postgres'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: database
|
||||
serviceName: '{{ meta.name }}'
|
||||
replicas: 1
|
||||
updateStrategy:
|
||||
@@ -18,7 +23,10 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: awx-postgres
|
||||
app.kubernetes.io/name: '{{ meta.name }}-postgres'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: database
|
||||
spec:
|
||||
containers:
|
||||
- image: '{{ tower_postgres_image }}'
|
||||
@@ -41,6 +49,10 @@ spec:
|
||||
key: password
|
||||
- name: PGDATA
|
||||
value: '{{ tower_postgres_data_path }}'
|
||||
- name: POSTGRES_INITDB_ARGS
|
||||
value: '{{ postgres_initdb_args }}'
|
||||
- name: POSTGRES_HOST_AUTH_METHOD
|
||||
value: '{{ postgres_host_auth_method }}'
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
name: postgres
|
||||
@@ -57,9 +69,7 @@ spec:
|
||||
{% if tower_postgres_storage_class != '' %}
|
||||
storageClassName: '{{ tower_postgres_storage_class }}'
|
||||
{% endif %}
|
||||
resources:
|
||||
requests:
|
||||
storage: '{{ tower_postgres_storage_request }}'
|
||||
resources: {{ tower_postgres_resource_requirements }}
|
||||
|
||||
# Postgres Service.
|
||||
---
|
||||
@@ -69,11 +79,15 @@ metadata:
|
||||
name: '{{ meta.name }}-postgres'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: awx-postgres
|
||||
app.kubernetes.io/name: '{{ meta.name }}-postgres'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: database
|
||||
spec:
|
||||
ports:
|
||||
- port: 5432
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: awx-postgres
|
||||
|
||||
app.kubernetes.io/name: '{{ meta.name }}-postgres'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: database
|
||||
19
roles/installer/templates/tower_postgres_secret.yaml.j2
Normal file
19
roles/installer/templates/tower_postgres_secret.yaml.j2
Normal file
@@ -0,0 +1,19 @@
|
||||
# Postgres Secret.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
stringData:
|
||||
password: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
username: '{{ database_username }}'
|
||||
database: '{{ database_name }}'
|
||||
port: '5432'
|
||||
host: {{ meta.name }}-postgres
|
||||
type: 'managed'
|
||||
13
roles/installer/templates/tower_secret_key.yaml.j2
Normal file
13
roles/installer/templates/tower_secret_key.yaml.j2
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
stringData:
|
||||
secret_key: '{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}'
|
||||
49
roles/installer/templates/tower_service.yaml.j2
Normal file
49
roles/installer/templates/tower_service.yaml.j2
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: '{{ meta.name }}-service'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
{% if tower_ingress_type | lower == 'loadbalancer' %}
|
||||
annotations:
|
||||
{{ tower_loadbalancer_annotations | indent(width=4) }}
|
||||
{% endif %}
|
||||
spec:
|
||||
ports:
|
||||
{% if tower_ingress_type | lower != 'loadbalancer' and tower_loadbalancer_protocol | lower != 'https' %}
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8052
|
||||
name: http
|
||||
{% endif %}
|
||||
{% if tower_ingress_type | lower == 'route' and tower_route_tls_termination_mechanism | lower == 'passthrough' %}
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
targetPort: 8053
|
||||
name: https
|
||||
{% endif %}
|
||||
{% if tower_ingress_type | lower == 'loadbalancer' and tower_loadbalancer_protocol | lower == 'https' %}
|
||||
- port: {{ tower_loadbalancer_port }}
|
||||
protocol: TCP
|
||||
targetPort: 8052
|
||||
name: https
|
||||
{% elif tower_ingress_type | lower == 'loadbalancer' and tower_loadbalancer_protocol | lower != 'https' %}
|
||||
- port: {{ tower_loadbalancer_port }}
|
||||
protocol: TCP
|
||||
targetPort: 8052
|
||||
name: http
|
||||
{% endif %}
|
||||
selector:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
{% if tower_ingress_type | lower == "loadbalancer" %}
|
||||
type: LoadBalancer
|
||||
{% elif tower_ingress_type != "none" %}
|
||||
type: NodePort
|
||||
{% endif %}
|
||||
41
roles/installer/templates/tower_service_account.yaml.j2
Normal file
41
roles/installer/templates/tower_service_account.yaml.j2
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app.kubernetes.io/name: '{{ meta.name }}'
|
||||
app.kubernetes.io/part-of: '{{ meta.name }}'
|
||||
app.kubernetes.io/managed-by: awx-operator
|
||||
app.kubernetes.io/component: awx
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
rules:
|
||||
- apiGroups: [""] # "" indicates the core API group
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/log"]
|
||||
verbs: ["get"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/attach"]
|
||||
verbs: ["create"]
|
||||
|
||||
---
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: '{{ meta.name }}'
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: '{{ meta.name }}'
|
||||
5
roles/installer/vars/main.yml
Normal file
5
roles/installer/vars/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
postgres_initdb_args: '--auth-host=scram-sha-256'
|
||||
postgres_host_auth_method: 'scram-sha-256'
|
||||
ldap_cacert_ca_crt: ''
|
||||
tower_projects_existing_claim: ''
|
||||
117
scripts/build.sh
Executable file
117
scripts/build.sh
Executable file
@@ -0,0 +1,117 @@
|
||||
#!/bin/bash
|
||||
## This script will be build 3 images awx-{operator,bundle,catalog}
|
||||
## and push to the $REGISTRY specified.
|
||||
##
|
||||
## The goal is provide an quick way to build a test image.
|
||||
##
|
||||
## Example:
|
||||
##
|
||||
## git clone https://github.com/ansible/awx-operator.git
|
||||
## cd awx-operator
|
||||
## REGISTRY=registry.example.com/ansible TAG=mytag scripts/build.sh
|
||||
##
|
||||
## As a result, the $REGISTRY will be populated with 2 images
|
||||
## registry.example.com/ansible/awx-operator:mytag
|
||||
## registry.example.com/ansible/awx-operator-bundle:mytag
|
||||
## registry.example.com/ansible/awx-operator-catalog:mytag
|
||||
|
||||
OPERATOR_IMAGE=${OPERATOR_IMAGE:-awx-operator}
|
||||
BUNDLE_IMAGE=${BUNDLE_IMAGE:-awx-operator-bundle}
|
||||
CATALOG_IMAGE=${CATALOG_IMAGE:-awx-operator-catalog}
|
||||
|
||||
verify_podman_binary() {
|
||||
if hash podman 2>/dev/null; then
|
||||
POD_MANAGER="podman"
|
||||
else
|
||||
POD_MANAGER="docker"
|
||||
fi
|
||||
}
|
||||
|
||||
verify_operator_sdk_binary() {
|
||||
if hash operator-sdk 2>/dev/null; then
|
||||
OPERATOR_SDK="$(which operator-sdk)"
|
||||
else
|
||||
echo "operator-sdk binary not found."
|
||||
echo "Please visit https://sdk.operatorframework.io/docs/building-operators/ansible/installation"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_opm_binary() {
|
||||
if hash opm 2>/dev/null; then
|
||||
OPM_BINARY="$(which opm)"
|
||||
else
|
||||
echo "opm binary not found."
|
||||
echo "Please visit https://github.com/operator-framework/operator-registry/releases"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_local_deploy() {
|
||||
echo "operator_image: $REGISTRY/$OPERATOR_IMAGE" > ansible/group_vars/all
|
||||
echo "operator_version: $TAG" >> ansible/group_vars/all
|
||||
echo "pull_policy: Always" >> ansible/group_vars/all
|
||||
ansible-playbook ansible/chain-operator-files.yml
|
||||
}
|
||||
|
||||
|
||||
REGISTRY=${REGISTRY:-''}
|
||||
if [[ -z "$REGISTRY" ]]; then
|
||||
echo "Set your \$REGISTRY variable to your registry server."
|
||||
echo "export REGISTRY=quay.io/ansible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TAG=${TAG:-''}
|
||||
if [[ -z "$TAG" ]]; then
|
||||
echo "Set your \$TAG variable to your registry server."
|
||||
echo "export TAG=mytag"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build_operator_image() {
|
||||
echo "Building and pushing $OPERATOR_IMAGE image"
|
||||
$POD_MANAGER build . -f build/Dockerfile -t $REGISTRY/$OPERATOR_IMAGE:$TAG
|
||||
$POD_MANAGER push $REGISTRY/$OPERATOR_IMAGE:$TAG
|
||||
}
|
||||
|
||||
build_bundle_image() {
|
||||
echo "Building and pushing $BUNDLE_IMAGE image"
|
||||
$POD_MANAGER build . -f bundle.Dockerfile -t $REGISTRY/$BUNDLE_IMAGE:$TAG
|
||||
$POD_MANAGER push $REGISTRY/$BUNDLE_IMAGE:$TAG
|
||||
}
|
||||
|
||||
build_catalog_image() {
|
||||
echo "Building and pushing $CATALOG_IMAGE image"
|
||||
$OPM_BINARY index add --bundles $REGISTRY/$BUNDLE_IMAGE:$TAG --tag $REGISTRY/$CATALOG_IMAGE:$TAG
|
||||
$POD_MANAGER push $REGISTRY/$CATALOG_IMAGE:$TAG
|
||||
}
|
||||
|
||||
generate_catalogsource_yaml() {
|
||||
echo "Creating CatalogSource YAML"
|
||||
cat > catalogsource.yaml << EOF
|
||||
---
|
||||
apiVersion: operators.coreos.com/v1alpha1
|
||||
kind: CatalogSource
|
||||
metadata:
|
||||
name: awx-operator
|
||||
namespace: operators
|
||||
spec:
|
||||
displayName: 'Ansible AWX Operator'
|
||||
image: "$REGISTRY/$CATALOG_IMAGE:$TAG"
|
||||
publisher: 'Ansible AWX Operator'
|
||||
sourceType: grpc
|
||||
EOF
|
||||
|
||||
echo "Now run: 'kubectl apply -f catalogsource.yaml' to update the operator"
|
||||
echo "Happy testing!"
|
||||
}
|
||||
|
||||
verify_podman_binary
|
||||
verify_operator_sdk_binary
|
||||
verify_opm_binary
|
||||
prepare_local_deploy
|
||||
build_operator_image
|
||||
build_bundle_image
|
||||
build_catalog_image
|
||||
generate_catalogsource_yaml
|
||||
@@ -5,4 +5,4 @@
|
||||
playbook: /opt/ansible/main.yml
|
||||
finalizer:
|
||||
name: finalizer.awx.ansible.com
|
||||
role: awx_remove
|
||||
role: finalizer
|
||||
|
||||
Reference in New Issue
Block a user