Compare commits

..

10 Commits

Author SHA1 Message Date
dependabot[bot]
1b0fa26709 Bump wntrblm/nox from 2024.04.15 to 2024.10.09 in the dependencies group
Bumps the dependencies group with 1 update: [wntrblm/nox](https://github.com/wntrblm/nox).


Updates `wntrblm/nox` from 2024.04.15 to 2024.10.09
- [Release notes](https://github.com/wntrblm/nox/releases)
- [Changelog](https://github.com/wntrblm/nox/blob/main/CHANGELOG.md)
- [Commits](https://github.com/wntrblm/nox/compare/2024.04.15...2024.10.09)

---
updated-dependencies:
- dependency-name: wntrblm/nox
  dependency-type: direct:production
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 11:21:48 +00:00
aknochow
5d0f91ec13 adding conditional to checksum template and removing default for public_base_url to fix undefined variable 2024-12-02 11:54:13 -05:00
Christian Adams
6ab32a42cf Add up.sh and down.sh development scripts for consistency with other ansible operators (#1991) 2024-11-26 11:25:24 -05:00
Chris Meyers
9718424483 Point at awx devel collection
* awx.awx collection on galaxy is ooooold at this point. Releases are
  paused, so point at awx collection in devel to get that new bleeding
  edge hotness.
2024-11-07 12:53:53 -05:00
aknochow
d5683adaf8 adding redirect page (#1982) 2024-10-29 17:47:41 -04:00
Christian Adams
1bc342258a Only set upgradedFrom status if previous_version is explicitly set (#1980) 2024-10-23 13:51:18 -04:00
Hao Liu
79ab6f0b5e Fix disable reverse sync on mgmt command (#1977) 2024-10-18 15:02:28 +00:00
Christian Adams
3822e32755 Add upgradedFrom status for check-version changes (#1975) 2024-10-17 19:28:43 +00:00
Christian Adams
c30d4c174d Compare gating version against existing deployment versions (#1972)
* Compare gating version against existing deployment versions and set upgradeFrom status
* Add quotes to default version

Co-authored-by: Dimitri Savineau <savineau.dimitri@gmail.com>
2024-10-16 17:43:26 -04:00
Christian Adams
8a5ec6e19c Fix Label PR check by using python venv for requests library (#1973) 2024-10-16 13:00:50 -04:00
24 changed files with 481 additions and 15 deletions

View File

@@ -13,8 +13,6 @@ jobs:
name: Label PR - Community
steps:
- uses: actions/checkout@v4
with:
ref: test-python-module-fix
- uses: actions/setup-python@v5

View File

@@ -18,7 +18,7 @@ jobs:
- name: Check out repo
uses: actions/checkout@v4
- name: Setup nox
uses: wntrblm/nox@2024.04.15
uses: wntrblm/nox@2024.10.09
with:
python-versions: "${{ matrix.python-versions }}"
- name: "Run nox -s ${{ matrix.session }}"

View File

@@ -10,6 +10,7 @@ Have questions about this document or anything not covered here? Please file a n
- [Table of contents](#table-of-contents)
- [Things to know prior to submitting code](#things-to-know-prior-to-submitting-code)
- [Submmiting your work](#submmiting-your-work)
- [Development](#development)
- [Testing](#testing)
- [Testing in Kind](#testing-in-kind)
- [Testing in Minikube](#testing-in-minikube)
@@ -42,7 +43,8 @@ Have questions about this document or anything not covered here? Please file a n
**Note**: If you have multiple commits, make sure to `squash` your commits into a single commit which will facilitate our release process.
## Development
The development environment consists of running an [`up.sh`](./up.sh) and a [`down.sh`](./down.sh) script, which applies or deletes yaml on the Openshift or K8s cluster you are connected to. See the [development.md](docs/development.md) for information on how to deploy and test changes from your branch.
## Testing

View File

@@ -20,6 +20,8 @@ Please visit [our contributing guidelines](https://github.com/ansible/awx-operat
For docs changes, create PRs on the appropriate files in the `/docs` folder.
The development environment consists of running an [`up.sh`](https://github.com/ansible/awx-operator/blob/devel/up.sh) and a [`down.sh`](https://github.com/ansible/awx-operator/blob/devel/down.sh) script, which applies or deletes yaml on the Openshift or K8s cluster you are connected to. See the [development.md](https://github.com/ansible/awx-operator/blob/devel/docs/development.md) for information on how to deploy and test changes from your branch.
## Author
This operator was originally built in 2019 by [Jeff Geerling](https://www.jeffgeerling.com) and is now maintained by the Ansible Team

View File

@@ -2009,6 +2009,9 @@ spec:
description: Enable metrics utility shipping to Red Hat Hybrid Cloud Console
type: boolean
default: false
public_base_url:
description: Public base URL
type: string
type: object
status:
properties:
@@ -2042,6 +2045,9 @@ spec:
image:
description: URL of the image used for the deployed instance
type: string
upgradedFrom:
description: Last gated version
type: string
conditions:
description: The resulting conditions when a Service Telemetry is instantiated
items:

View File

@@ -173,6 +173,12 @@ spec:
path: db_management_pod_node_selector
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- displayName: Public Base URL
path: public_base_url
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
statusDescriptors:
- description: Persistent volume claim name used during backup
displayName: Backup Claim

View File

@@ -0,0 +1,24 @@
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
spec:
service_type: clusterip
ingress_type: route
no_log: false
# Secrets
admin_password_secret: custom-admin-password
postgres_configuration_secret: custom-pg-configuration
secret_key_secret: custom-secret-key
# Resource Requirements
postgres_storage_requirements:
requests:
storage: 10Gi
# Extra Settings
extra_settings:
- setting: MAX_PAGE_SIZE
value: "500"

View File

@@ -0,0 +1,13 @@
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
spec:
service_type: nodeport
ingress_type: ingress
# Secrets
admin_password_secret: custom-admin-password
postgres_configuration_secret: custom-pg-configuration
secret_key_secret: custom-secret-key

View File

@@ -0,0 +1,13 @@
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
spec:
service_type: clusterip
ingress_type: Route
# Secrets
admin_password_secret: custom-admin-password
postgres_configuration_secret: custom-pg-configuration
secret_key_secret: custom-secret-key

View File

@@ -0,0 +1,7 @@
---
apiVersion: v1
kind: Secret
metadata:
name: custom-admin-password
stringData:
password: 'password'

View File

@@ -0,0 +1,7 @@
---
apiVersion: v1
kind: Secret
metadata:
name: custom-secret-key
stringData:
secret_key: 'awxsecret'

View File

@@ -0,0 +1,12 @@
---
apiVersion: v1
kind: Secret
metadata:
name: external-pg-secret
stringData:
database: 'awx'
host: 'awx-postgres'
password: 'test'
port: '5432'
type: 'managed'
username: 'awx'

58
docs/development.md Normal file
View File

@@ -0,0 +1,58 @@
# Development Guide
There are development scripts and yaml exaples in the [`dev/`](../dev) directory that, along with the up.sh and down.sh scripts in the root of the repo, can be used to build, deploy and test changes made to the awx-operator.
## Build and Deploy
If you clone the repo, and make sure you are logged in at the CLI with oc and your cluster, you can run:
```
export QUAY_USER=username
export NAMESPACE=awx
export TAG=test
./up.sh
```
You can add those variables to your .bashrc file so that you can just run `./up.sh` in the future.
> Note: the first time you run this, it will create quay.io repos on your fork. You will need to either make those public, or create a global pull secret on your Openshift cluster.
To get the URL, if on **Openshift**, run:
```
$ oc get route
```
On **k8s with ingress**, run:
```
$ kubectl get ing
```
On **k8s with nodeport**, run:
```
$ kubectl get svc
```
The URL is then `http://<Node-IP>:<NodePort>`
> Note: NodePort will only work if you expose that port on your underlying k8s node, or are accessing it from localhost.
By default, the usename and password will be admin and password if using the `up.sh` script because it pre-creates a custom admin password k8s secret and specifies it on the AWX custom resource spec. Without that, a password would have been generated and stored in a k8s secret named <deployment-name>-admin-password.
## Clean up
Same thing for cleanup, just run ./down.sh and it will clean up your namespace on that cluster
```
./down.sh
```
## Running CI tests locally
More tests coming soon...

36
down.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
# AWX Operator down.sh
# Purpose:
# Cleanup and delete the namespace you deployed in
# -- Usage
# NAMESPACE=awx ./down.sh
# -- Variables
TAG=${TAG:-dev}
AWX_CR=${AWX_CR:-awx}
CLEAN_DB=${CLEAN_DB:-false}
# -- Check for required variables
# Set the following environment variables
# export NAMESPACE=awx
if [ -z "$NAMESPACE" ]; then
echo "Error: NAMESPACE env variable is not set. Run the following with your namespace:"
echo " export NAMESPACE=developer"
exit 1
fi
# -- Delete Backups
kubectl delete awxbackup --all
# -- Delete Restores
kubectl delete awxrestore --all
# Deploy Operator
make undeploy NAMESPACE=$NAMESPACE
# Remove PVCs
kubectl delete pvc postgres-15-$AWX_CR-postgres-15-0

View File

@@ -4,4 +4,6 @@ collections:
- name: kubernetes.core
- name: operator_sdk.util
- name: community.docker
- name: awx.awx
- name: https://github.com/ansible/awx.git#/awx_collection/
type: git
version: devel

View File

@@ -0,0 +1,35 @@
---
- name: Check for presence of Deployment
kubernetes.core.k8s_info:
api_version: apps/v1
kind: Deployment
namespace: "{{ ansible_operator_meta.namespace }}"
label_selectors:
- 'app.kubernetes.io/part-of={{ ansible_operator_meta.name }}'
- 'app.kubernetes.io/managed-by={{ deployment_type }}-operator'
- 'app.kubernetes.io/component={{ deployment_type }}'
register: _deployments
- name: Set previous_version if deployment exists
when: _deployments.resources | length > 0
block:
- name: Check for existing deployment
kubernetes.core.k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
namespace: "{{ ansible_operator_meta.namespace }}"
name: "{{ ansible_operator_meta.name }}"
register: existing_cr
- name: Set previous_version version based on AWX CR version status
ansible.builtin.set_fact:
previous_version: "{{ existing_cr.resources[0].status.version }}"
when: existing_cr['resources'] | length
- name: If previous_version is less than or equal to gating_version, set upgraded_from to previous_version
ansible.builtin.set_fact:
upgraded_from: "{{ previous_version }}"
when:
- previous_version is defined
- previous_version is version_compare(gating_version, '<')

View File

@@ -18,13 +18,11 @@
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ awx_web_pod_name }}"
container: "{{ ansible_operator_meta.name }}-web"
command: awx-manage createsuperuser --username={{ admin_user | quote }} --email={{ admin_email | quote }} --noinput
command: bash -c "ANSIBLE_REVERSE_RESOURCE_SYNC=false awx-manage createsuperuser --username={{ admin_user | quote }} --email={{ admin_email | quote }} --noinput"
register: result
changed_when: "'That username is already taken' not in result.stderr"
failed_when: "'That username is already taken' not in result.stderr and 'Superuser created successfully' not in result.stdout"
no_log: "{{ no_log }}"
environment:
ANSIBLE_REVERSE_RESOURCE_SYNC: "false"
when: users_result.return_code > 0
- name: Update Django super user password
@@ -116,9 +114,7 @@
pod: "{{ awx_web_pod_name }}"
container: "{{ ansible_operator_meta.name }}-web"
command: >-
bash -c "awx-manage create_preload_data"
bash -c "ANSIBLE_REVERSE_RESOURCE_SYNC=false awx-manage create_preload_data"
register: cdo
changed_when: "'added' in cdo.stdout"
environment:
ANSIBLE_REVERSE_RESOURCE_SYNC: "false"
when: create_preload_data | bool

View File

@@ -44,6 +44,12 @@
- name: Include secret key configuration tasks
include_tasks: secret_key_configuration.yml
- name: Apply Redirect Page Configmap
k8s:
apply: true
definition: "{{ lookup('template', 'configmaps/redirect-page.configmap.html.j2') }}"
when: public_base_url is defined
- name: Load LDAP CAcert certificate (Deprecated)
include_tasks: load_ldap_cacert_secret.yml
when:

View File

@@ -23,6 +23,10 @@
namespace: "{{ ansible_operator_meta.namespace }}"
register: awx_web_deployment
- name: Check for existing deployment for previous version
include_tasks: check_existing.yml
when: gating_version | length
- name: Start installation if auto_upgrade is true
include_tasks: install.yml
when:

View File

@@ -55,6 +55,16 @@
changed_when: false
when: awx_web_pod_name != ''
- name: Update upgradedFrom status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
status:
upgradedFrom: "{{ upgraded_from }}"
when: upgraded_from is defined
- name: Update version status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'

View File

@@ -0,0 +1,76 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ ansible_operator_meta.name }}-redirect-page
namespace: {{ ansible_operator_meta.namespace }}
data:
redirect-page.html: |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="15; url={{ public_base_url }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redirecting to Ansible Automation Platform</title>
<!-- Favicon links -->
<link rel="icon" type="image/x-icon" href="static/media/favicon.ico">
<!-- Link to DRF's CSS -->
<link rel="stylesheet" type="text/css" href="static/rest_framework/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="static/rest_framework/css/bootstrap-theme.min.css">
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding-top: 0px;
/* background-color: rgb(34, 34, 34); */
}
.banner {
background-color: #151414;
color: rgb(255, 255, 255);
padding: 20px;
margin-bottom: 20px;
min-height: 70px; /* Ensure the banner is tall enough to fit the logo */
text-align: left;
}
.logo {
width: 150px;
margin-bottom: 20px;
}
a {
color: #007BFF;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.doc-note {
font-size: 0.7em; /* Makes the text smaller */
color: #555; /* Optional: Change text color to a lighter shade */
background-color: #f9f9f9; /* Optional: Light background color */
padding: 10px; /* Optional: Add some padding */
margin: 10px 0; /* Optional: Add some margin */
}
</style>
</head>
<body>
<!-- Banner Section with Brand Logo -->
<div class="banner">
<img src="/static/media/aap-logo.svg" alt="Brand Logo">
</div>
<h2>Redirecting to Ansible Automation Platform...</h2>
<p>If you are not redirected automatically, <a href="{{ public_base_url }}">click here</a> to go to AAP.</p>
<p class="doc-note">
The API endpoints for this platform service will temporarily remain available at the URL for this service.
Please use the Ansible Automation Platform API endpoints corresponding to this component in the future.
These can be found at <a href="{{ public_base_url }}/api/{{ deployment_type }}" target="_blank">{{ public_base_url }}/api/{{ deployment_type }}</a>.
</p>
<!-- Include any additional scripts if needed -->
<script src="static/rest_framework/js/jquery-3.5.1.min.js"></script>
<script src="static/rest_framework/js/bootstrap.min.js"></script>
</body>
</html>

View File

@@ -28,12 +28,15 @@ spec:
annotations:
kubectl.kubernetes.io/default-container: '{{ ansible_operator_meta.name }}-web'
{% for template in [
"configmaps/config",
"secrets/app_credentials",
"storage/persistent",
"configmaps/config.yaml",
"secrets/app_credentials.yaml",
"storage/persistent.yaml",
] %}
checksum-{{ template | replace('/', '-') }}: "{{ lookup('template', template + '.yaml.j2') | sha1 }}"
checksum-{{ template | replace('/', '-') }}: "{{ lookup('template', template + '.j2') | sha1 }}"
{% endfor %}
{% if public_base_url is defined %}
checksum-configmaps-redirect-page.configmap.html: "{{ lookup('template', 'configmaps/redirect-page.configmap.html.j2') | sha1 }}"
{% endif %}
{% for secret in [
"bundle_cacert",
"route_tls",
@@ -197,6 +200,11 @@ spec:
timeoutSeconds: {{ web_readiness_timeout }}
{% endif %}
volumeMounts:
{% if public_base_url is defined %}
- name: redirect-page
mountPath: '/var/lib/awx/venv/awx/lib/python3.11/site-packages/awx/ui/build/index.html'
subPath: redirect-page.html
{% endif %}
{% if bundle_ca_crt %}
- name: "ca-trust-extracted"
mountPath: "/etc/pki/ca-trust/extracted"
@@ -375,6 +383,14 @@ spec:
{{ security_context_settings | to_nice_yaml | indent(8) }}
{% endif %}
volumes:
{% if public_base_url is defined %}
- name: redirect-page
configMap:
name: '{{ ansible_operator_meta.name }}-redirect-page'
items:
- key: redirect-page.html
path: redirect-page.html
{% endif %}
- name: "{{ ansible_operator_meta.name }}-receptor-ca"
secret:
secretName: "{{ ansible_operator_meta.name }}-receptor-ca"

View File

@@ -21,3 +21,6 @@ _metrics_utility_pvc_claim: "{{ metrics_utility_pvc_claim | default(deployment_t
_metrics_utility_pvc_claim_size: "{{ metrics_utility_pvc_claim_size | default('5Gi') }}"
_metrics_utility_cronjob_gather_schedule: "{{ metrics_utility_cronjob_gather_schedule | default('@hourly') }}"
_metrics_utility_cronjob_report_schedule: "{{ metrics_utility_cronjob_report_schedule | default('@monthly') }}"
# version check
gating_version: ''

134
up.sh Executable file
View File

@@ -0,0 +1,134 @@
#!/bin/bash
# AWX Operator up.sh
# Purpose:
# Build operator image from your local checkout, push to quay.io/youruser/awx-operator:dev, and deploy operator
# -- Usage
# NAMESPACE=awx TAG=dev QUAY_USER=developer ./up.sh
# -- User Variables
NAMESPACE=${NAMESPACE:-awx}
QUAY_USER=${QUAY_USER:-developer}
TAG=${TAG:-$(git rev-parse --short HEAD)}
DEV_TAG=${DEV_TAG:-dev}
DEV_TAG_PUSH=${DEV_TAG_PUSH:-true}
# -- Check for required variables
# Set the following environment variables
# export NAMESPACE=awx
# export QUAY_USER=developer
if [ -z "$QUAY_USER" ]; then
echo "Error: QUAY_USER env variable is not set."
echo " export QUAY_USER=developer"
exit 1
fi
if [ -z "$NAMESPACE" ]; then
echo "Error: NAMESPACE env variable is not set. Run the following with your namespace:"
echo " export NAMESPACE=developer"
exit 1
fi
# -- Container Build Engine (podman or docker)
ENGINE=${ENGINE:-podman}
# -- Variables
IMG=quay.io/$QUAY_USER/awx-operator
KUBE_APPLY="kubectl apply -n $NAMESPACE -f"
# -- Wait for existing project to be deleted
# Function to check if the namespace is in terminating state
is_namespace_terminating() {
kubectl get namespace $NAMESPACE 2>/dev/null | grep -q 'Terminating'
return $?
}
# Check if the namespace exists and is in terminating state
if kubectl get namespace $NAMESPACE 2>/dev/null; then
echo "Namespace $NAMESPACE exists."
if is_namespace_terminating; then
echo "Namespace $NAMESPACE is in terminating state. Waiting for it to be fully terminated..."
while is_namespace_terminating; do
sleep 5
done
echo "Namespace $NAMESPACE has been terminated."
fi
fi
# -- Create namespace
kubectl create namespace $NAMESPACE
# -- Prepare
# Set imagePullPolicy to Always
files=(
config/manager/manager.yaml
)
for file in "${files[@]}"; do
if grep -qF 'imagePullPolicy: IfNotPresent' ${file}; then
sed -i -e "s|imagePullPolicy: IfNotPresent|imagePullPolicy: Always|g" ${file};
fi
done
# Delete old operator deployment
kubectl delete deployment awx-operator-controller-manager
# Create secrets
$KUBE_APPLY dev/secrets/custom-secret-key.yml
$KUBE_APPLY dev/secrets/admin-password-secret.yml
# (Optional) Create external-pg-secret
# $KUBE_APPLY dev/secrets/external-pg-secret.yml
# -- Login to Quay.io
$ENGINE login quay.io
if [ $ENGINE = 'podman' ]; then
if [ -f "$XDG_RUNTIME_DIR/containers/auth.json" ] ; then
REGISTRY_AUTH_CONFIG=$XDG_RUNTIME_DIR/containers/auth.json
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
elif [ -f $HOME/.config/containers/auth.json ] ; then
REGISTRY_AUTH_CONFIG=$HOME/.config/containers/auth.json
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
elif [ -f "/home/$USER/.docker/config.json" ] ; then
REGISTRY_AUTH_CONFIG=/home/$USER/.docker/config.json
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
else
echo "No Podman configuration files were found."
fi
fi
if [ $ENGINE = 'docker' ]; then
if [ -f "/home/$USER/.docker/config.json" ] ; then
REGISTRY_AUTH_CONFIG=/home/$USER/.docker/config.json
echo "Found registry auth config: $REGISTRY_AUTH_CONFIG"
else
echo "No Docker configuration files were found."
fi
fi
# -- Build & Push Operator Image
echo "Preparing to build $IMG:$TAG ($IMG:$DEV_TAG) with $ENGINE..."
sleep 3
make docker-build docker-push IMG=$IMG:$TAG
# Tag and Push DEV_TAG Image when DEV_TAG_PUSH is 'True'
if $DEV_TAG_PUSH ; then
$ENGINE tag $IMG:$TAG $IMG:$DEV_TAG
make docker-push IMG=$IMG:$DEV_TAG
fi
# -- Deploy Operator
make deploy IMG=$IMG:$TAG NAMESPACE=$NAMESPACE
# -- Create CR
# uncomment the CR you want to use
$KUBE_APPLY dev/awx-cr/awx-openshift-cr.yml
# $KUBE_APPLY dev/awx-cr/awx-cr-settings.yml
# $KUBE_APPLY dev/awx-cr/awx-k8s-ingress.yml