Compare commits

...

7 Commits

Author SHA1 Message Date
Hao Liu
630a5ee1f3 Fix bug where uppercase Route fails (#1731) 2024-02-26 17:17:37 +00:00
Matt Miller
3d78e90ab1 Update Dockerfile operator-framework/ansible-operator to v1.34.0 (#1714)
Update Dockerfile base image

* Vulnerability scans against this image when deployed shows: CVE-2023-4911
* https://quay.io/repository/operator-framework/ansible-operator/manifest/sha256:f08f675976f42dc3a8ebbb8482acea153a8f57232e2ee48940e3d40ca40d24d9?tab=vulnerabilities
* It appears if 5f3d9ed96f/Dockerfile (L1C14-L1C49) is updated to `v1.34.0` this vulnerability is mitigated.
2024-02-21 14:50:08 -05:00
kurokobo
3981e6ba5e fix: correct indentation for annotations for awxmeshingress (#1723)
fix: correct indentation for annotations
2024-02-21 19:46:34 +00:00
kurokobo
ac682a9c05 docs: improve documentation for awxmeshingress (#1724)
* add descriptions and examples for awxmeshingress
* convert list to table
* add note for image
* correct minor wording issues
* apply suggested changes from code review for docs/user-guide/advanced-configuration/mesh-ingress.md

Co-authored-by: Seth Foster <fosterseth@users.noreply.github.com>
2024-02-21 14:36:50 -05:00
kurokobo
7bdf48ffc0 docs: add description for --force-conflicts option to upgrade crds (#1717) 2024-02-21 14:31:32 -05:00
Seth Foster
fc11db4ece Fix syntax error in mesh ingress docs (#1720)
Signed-off-by: Seth Foster <fosterbseth@gmail.com>
2024-02-16 17:16:28 +00:00
TVo
148309325e Separate out the custom receptor CA section to its own section. (#1707) 2024-02-16 10:06:05 -07:00
8 changed files with 213 additions and 111 deletions

View File

@@ -36,6 +36,29 @@ When upgrading to releases with CRD changes use the following command to update
kubectl apply --server-side -k github.com/ansible/awx-operator/config/crd?ref=<VERSION>
```
If running above command results in an error like below:
```text
Apply failed with 1 conflict: conflict with "helm" using apiextensions.k8s.io/v1: .spec.versions
Please review the fields above--they currently have other managers. Here
are the ways you can resolve this warning:
* If you intend to manage all of these fields, please re-run the apply
command with the `--force-conflicts` flag.
* If you do not intend to manage all of the fields, please edit your
manifest to remove references to the fields that should keep their
current managers.
* You may co-own fields by updating your manifest to match the existing
value; in this case, you'll become the manager if the other manager(s)
stop managing the field (remove it from their configuration).
See https://kubernetes.io/docs/reference/using-api/server-side-apply/#conflicts
```
Use `--force-conflicts` flag to resolve the conflict.
```bash
kubectl apply --server-side --force-conflicts -k github.com/ansible/awx-operator/config/crd?ref=<VERSION>
```
## Configuration
The goal of adding helm configurations is to abstract out and simplify the creation of multi-resource configs. The `AWX.spec` field maps directly to the spec configs of the `AWX` resource that the operator provides, which are detailed in the [main README](https://github.com/ansible/awx-operator/blob/devel/README.md). Other sub-config can be added with the goal of simplifying more involved setups that require additional resources to be specified.

View File

@@ -1,4 +1,4 @@
FROM quay.io/operator-framework/ansible-operator:v1.32.0
FROM quay.io/operator-framework/ansible-operator:v1.34.0
USER root
RUN dnf update --security --bugfix -y && \

View File

@@ -1,26 +1,4 @@
### Adding Execution Nodes
Starting with AWX Operator v0.30.0 and AWX v21.7.0, standalone execution nodes can be added to your deployments.
See [AWX execution nodes docs](https://github.com/ansible/awx/blob/devel/docs/execution_nodes.md) for information about this feature.
See [Managing Capacity With Instances](https://ansible.readthedocs.io/projects/awx/en/latest/administration/instances.html) chapter of the AWX Administration Guide for information about this feature.
#### Custom Receptor CA
The control nodes on the K8S cluster will communicate with execution nodes via mutual TLS TCP connections, running via Receptor.
Execution nodes will verify incoming connections by ensuring the x509 certificate was issued by a trusted Certificate Authority (CA).
A user may wish to provide their own CA for this validation. If no CA is provided, AWX Operator will automatically generate one using OpenSSL.
Given custom `ca.crt` and `ca.key` stored locally, run the following,
```bash
kubectl create secret tls awx-demo-receptor-ca \
--cert=/path/to/ca.crt --key=/path/to/ca.key
```
The secret should be named `{AWX Custom Resource name}-receptor-ca`. In the above the AWX CR name is "awx-demo". Please replace "awx-demo" with your AWX Custom Resource name.
If this secret is created after AWX is deployed, run the following to restart the deployment,
```bash
kubectl rollout restart deployment awx-demo
```
**Important Note**, changing the receptor CA will break connections to any existing execution nodes. These nodes will enter an `unavailable` state, and jobs will not be able to run on them. Users will need to download and re-run the install bundle for each execution node. This will replace the TLS certificate files with those signed by the new CA. The execution nodes should then appear in a `ready` state after a few minutes.

View File

@@ -0,0 +1,24 @@
### Custom Receptor CA
The control nodes on the K8S cluster will communicate with execution nodes via mutual TLS TCP connections, running via Receptor.
Execution nodes will verify incoming connections by ensuring the x509 certificate was issued by a trusted Certificate Authority (CA).
A user may wish to provide their own CA for this validation. If no CA is provided, AWX Operator will automatically generate one using OpenSSL.
Given custom `ca.crt` and `ca.key` stored locally, run the following,
```bash
kubectl create secret tls awx-demo-receptor-ca \
--cert=/path/to/ca.crt --key=/path/to/ca.key
```
The secret should be named `{AWX Custom Resource name}-receptor-ca`. In the above the AWX CR name is "awx-demo". Please replace "awx-demo" with your AWX Custom Resource name.
If this secret is created after AWX is deployed, run the following to restart the deployment,
```bash
kubectl rollout restart deployment awx-demo
```
**Important Note**, changing the receptor CA will break connections to any existing execution nodes. These nodes will enter an `unavailable` state, and jobs will not be able to run on them. Users will need to download and re-run the install bundle for each execution node. This will replace the TLS certificate files with those signed by the new CA. The execution nodes should then appear in a `ready` state after a few minutes.

View File

@@ -11,9 +11,14 @@ For more information about remote execution and hop nodes and how to create them
## Deploy and configure AWXMeshIngress
### On Red Hat OpenShift with operator managed Route
!!! note
The mesh ingress uses the `control_plane_ee_image` and `image_pull_policy` fields of the AWX instance to determine image and policy to be adopted.
Defaulted to `quay.io/ansible/awx-ee:latest` and `Always`.
Currently there are no dedicated parameters to specify the image and policy.
To deploy an mesh ingress on OpenShift create the AWXMeshIngress resource.
### On Red Hat OpenShift with Operator managed Route
To deploy a mesh ingress on OpenShift, create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
Example:
@@ -27,21 +32,136 @@ spec:
deployment_name: <awx instance name>
```
### User managed Ingress
### On Kubernetes with Operator managed Ingress (NGINX)
UNDER CONSTRUCTION (contribution welcome)
To deploy a mesh ingress on Kubernetes cluster which has [NGINX Ingress Controller](https://www.nginx.com/products/nginx-ingress-controller/), create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
### Operator managed Ingress
Note that AWXMeshIngress requires [SSL Passthrough](https://kubernetes.github.io/ingress-nginx/user-guide/tls/#ssl-passthrough) enabled which is disabled by default. Ensure it is enabled on your NGINX Ingress Controller.
UNDER CONSTRUCTION (contribution welcome)
By specifying `ingress_controller` as `nginx`, AWX Operator will generate Ingress resource that has `nginx.ingress.kubernetes.io/ssl-passthrough` annotation set to `"true"`.
### Deploy and configure AWXMeshIngress via IngressRouteTCP
Example:
UNDER CONSTRUCTION (contribution welcome)
```yaml
---
apiVersion: awx.ansible.com/v1alpha1
kind: AWXMeshIngress
metadata:
name: <mesh ingress name>
spec:
deployment_name: <awx instance name>
ingress_type: Ingress
ingress_controller: nginx
ingress_class_name: nginx
external_hostname: <fqdn for mesh ingress>
```
### On Kubernetes with Operator managed Ingress (Traefik)
To deploy a mesh ingress on Kubernetes cluster which has [Traefik Kubernetes Ingress provider](https://doc.traefik.io/traefik/providers/kubernetes-ingress/), create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
Note that by deploying following AWXMeshIngress, AWX Operator will generate IngressRouteTCP resource that has `websecure` as an `entryPoints`. If this does not satisfy your requirement, refer to [User managed Ingress section](#on-kubernetes-with-user-managed-ingress) and create an IngressRouteTCP resource manually.
Example:
```yaml
---
apiVersion: awx.ansible.com/v1alpha1
kind: AWXMeshIngress
metadata:
name: <mesh ingress name>
spec:
deployment_name: <awx instance name>
ingress_type: IngressRouteTCP
ingress_controller: traefik
ingress_class_name: traefik
ingress_api_version: traefik.io/v1alpha1
external_hostname: <fqdn for mesh ingress>
```
### On Kubernetes with User managed Ingress
To deploy a mesh ingress on Kubernetes cluster, create the AWXMeshIngress resource on the namespace where your AWX instance is running on.
Alternatively, if you wish to create your own Ingress resource, you can deploy a mesh ingress with `ingress_type` set to `none` and then manually create an Ingress resource with any configuration.
In this case, the `external_hostname` is still required as it is used to generate the certificate that will be used by Receptor.
Example:
```yaml
---
apiVersion: awx.ansible.com/v1alpha1
kind: AWXMeshIngress
metadata:
name: <mesh ingress name>
spec:
deployment_name: <awx instance name>
ingress_type: none # This line can be omitted since this is the default value
external_hostname: <fqdn for mesh ingress>
```
The requirements for user managed Ingress resource are as follows:
- Supports WebSocket
- SSL/TLS Passthrough enabled
- Accessible over port `443`
- Having the same hostname as `external_hostname` in the AWXMeshIngress resource
- Routing the traffic to port `27199` of the Service of the same name as the AWXMeshIngress resource
These are example Ingress resources for NGINX and Traefik.
```yaml
# Ingress for NGINX Ingress Controller
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: <mesh ingress name>
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: <fqdn for mesh ingress>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: <mesh ingress name>
port:
number: 27199
```
```yaml
# Ingress for Traefik Kubernetes Ingress provider
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: <mesh ingress name>
spec:
entryPoints:
- websecure
routes:
- match: HostSNI(`<fqdn for mesh ingress>`)
services:
- name: <mesh ingress name>
port: 27199
tls:
passthrough: true
```
## Validating setup of Mesh Ingress
After AWXMeshIngress has been successfully created a new Instance with the same name will show up in AWX Instance UI
After AWXMeshIngress has been successfully created, a new Instance with the same name will be registered to AWX and will be visible on the Instance UI page
![mesh ingress instance on AWX UI](mesh-ingress-instance-on-awx-ui.png)
@@ -57,92 +177,48 @@ In this example, the mesh ingress has two listener addresses:
When selecting peer for new instance the mesh ingress instance should now be present as a option.
![peering to mesh ingress on awx ui](peering-to-mesh-ingress-on-awx-ui.png)
For more information about how to create external remote execution and hop node and configuring the mesh. See AWX Documentation on [Add a instance](https://ansible.readthedocs.io/projects/awx/en/latest/administration/instances.html#add-an-instance).
For more information about how to create external remote execution and hop nodes and configuring the mesh, see AWX Documentation on [Add a instance](https://ansible.readthedocs.io/projects/awx/en/latest/administration/instances.html#add-an-instance).
## AWXMeshIngress
## Custom Resource Definitions
### AWXMeshIngress
AWXMeshIngress controls the deployment and configuration of mesh ingress on AWX
- **apiVersion**: awx.ansible.com/v1alpha1
| Name | Description |
| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`apiVersion`** | awx.ansible.com/v1alpha1 |
| **`kind`** | AWXMeshIngress |
| **`metadata`** ([ObjectMeta](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/object-meta/#ObjectMeta)) | Standard object's metadata. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata) |
| **`spec`** ([AWXMeshIngressSpec](#awxmeshingressspec)) | Spec is the desired state of the AWXMeshIngress. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) |
| **`status`** ([AWXMeshIngressStatus](#awxmeshingressstatus)) | Status is the current state of the AWXMeshIngress. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) |
- **kind**: AWXMeshIngress
#### AWXMeshIngressSpec
- **metadata**: ([ObjectMeta](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/object-meta/#ObjectMeta))
AWXMeshIngressSpec is the description of the configuration for AWXMeshIngress.
Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
| Name | Description | Default |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| **`deployment_name`** (string), required | Name of the AWX deployment to create the Mesh Ingress for. | `awx` |
| **`ingress_type`** (string) | Ingress type for ingress managed by the operator. Options: `none`, `Ingress`, `IngressRouteTCP`, `Route` | `Route` (on OpenShift), `none` (on Kubernetes) |
| **`external_hostname`** (string) | External hostname is an optional field used for specifying the external hostname defined in an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/). This parameter is automatically generated on OpenShift | N/A |
| **`external_ipaddress`** (string) | External IP Address is an optional field used for specifying the external IP address defined in an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) | N/A |
| **`ingress_api_version`** (string) | API Version for ingress managed by the operator. This parameter is ignored when `ingress_type` is `Route` | `networking.k8s.io/v1` |
| **`ingress_annotations`** (string) | Additional annotation on the ingress managed by the operator. This parameter is ignored when `ingress_type` is `Route` | `""` |
| **`ingress_controller`** (string) | Special configuration for specific Ingress Controllers. This parameter is ignored when `ingress_type` is `Route` | `""` |
| **`ingress_class_name`** (string) | The name of ingress class to use instead of the cluster default. see [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec). This parameter is ignored when `ingress_type` is `Route` | `""` |
- **spec**: ([AWXMeshIngressSpec](#awxmeshingressspec))
spec is the desired state of the AWXMeshIngress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
- **status**: ([AWXMeshIngressStatus](#awxmeshingressstatus))
status is the current state of the AWXMeshIngress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
### AWXMeshIngressSpec
AWXMeshIngress is the description of the configuration for AWXMeshIngress.
- **deployment_name** (string), required
Name of the AWX deployment to create the Mesh Ingress for.
- **external_hostname** (string)
External hostname is an optional field used for specifying the external hostname defined in an user managed [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- **external_ipaddress** (string)
External IP Address is an optional field used for specifying the external IP address defined in an user managed [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- **ingress_type** (string)
Ingress type for ingress managed by the operator
Options:
- none (default)
- Ingress
- IngressRouteTCP
- Route (default when deploy on OpenShift)
- **ingress_api_version** (string)
API Version for ingress managed by the operator
This parameter is ignored when ingress_type=Route
- **ingress_annotations** (string)
Annotation on the ingress managed by the operator
- **ingress_class_name** (string)
The name of ingress class to use instead of the cluster default. see [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec)
This parameter is ignored when `ingress_type=Route`
- **ingress_controller** (string)
Special configuration for specific Ingress Controllers
This parameter is ignored when ingress_type=Route
### AWXMeshIngressStatus
#### AWXMeshIngressStatus
AWXMeshIngressStatus describe the current state of the AWXMeshIngress.
## AWXMeshIngressList
### AWXMeshIngressList
AWXMeshIngressList is a collection of AWXMeshIngress.
- **items** ([][AWXMeshIngress](#awxmeshingress))
items is the list of Ingress.
- **apiVersion** (string)
APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
- **kind** (string)
Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
- **metadata** ([ListMeta](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/list-meta/#ListMeta))
Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
| Name | Description |
| ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`items`** ([AWXMeshIngress](#awxmeshingress)) | items is the list of Ingress. |
| **`apiVersion`** (string) | APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources) |
| **`kind`** (string) | Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds) |
| **`metadata`** ([ListMeta](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/list-meta/#ListMeta)) | Standard object's metadata. [More info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata) |

View File

@@ -67,6 +67,7 @@ nav:
- user-guide/advanced-configuration/scaling-the-web-and-task-pods-independently.md
- user-guide/advanced-configuration/assigning-awx-pods-to-specific-nodes.md
- user-guide/advanced-configuration/trusting-a-custom-certificate-authority.md
- user-guide/advanced-configuration/custom-receptor-certs.md
- user-guide/advanced-configuration/enabling-ldap-integration-at-awx-bootstrap.md
- user-guide/advanced-configuration/persisting-projects-directory.md
- user-guide/advanced-configuration/custom-volume-and-volume-mount-options.md

View File

@@ -61,7 +61,7 @@
- name: Default ingress_type to Route if OpenShift
set_fact:
ingress_type: route
when: is_openshift | bool and ingress_type == 'none'
when: is_openshift | bool and ingress_type | lower == 'none'
- name: Apply Ingress resource
k8s:
@@ -77,7 +77,7 @@
- name: Set external_hostname
set_fact:
external_hostname: "{{ ingress.result.status.ingress[0].host }}"
when: ingress_type == 'route'
when: ingress_type | lower == 'route'
- name: Create other resources
k8s:

View File

@@ -12,7 +12,7 @@ metadata:
{{ ingress_annotations | indent(width=4) }}
{% endif %}
{% if ingress_controller|lower == "nginx" %}
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
{% endif %}
spec:
{% if ingress_class_name %}