فهرست منبع

Merge pull request #370 from ptrinesh/devel

Issue #369 AWX 19.1.0 deployment and configuration code changes
Lucas A. Wilson 3 سال پیش
والد
کامیت
a6a098f9c4

+ 37 - 0
control_plane/roles/webui_awx/files/awx.yml

@@ -0,0 +1,37 @@
+---
+apiVersion: awx.ansible.com/v1beta1
+kind: AWX
+metadata:
+  name: awx
+  namespace: awx
+spec:
+  deployment_type: awx
+
+  #tower_hostname:
+  #tower_secret_key_secret:
+
+  #tower_extra_volumes:
+
+  #tower_admin_user: admin
+  #tower_admin_email:
+  #tower_admin_password_secret:
+
+  tower_ingress_type: Ingress
+  #tower_ingress_type:
+  #tower_loadbalancer_protocol:
+  #tower_loadbalancer_port:
+
+  #tower_image_pull_secret:
+
+  tower_postgres_storage_class: nfs-client
+
+  tower_projects_persistence: true
+  tower_projects_use_existing_claim: "_Yes_"
+  tower_projects_existing_claim: awx-pv-claim
+  tower_projects_storage_class: manual
+  tower_projects_storage_size: 10Gi
+  tower_projects_storage_access_mode: RWO
+
+  tower_ee_images:
+    - name: custom-awx-ee
+      image: localhost/custom-awx-ee

+ 18 - 0
control_plane/roles/webui_awx/files/awx_ee.yml

@@ -0,0 +1,18 @@
+FROM quay.io/ansible/awx-ee:0.2.0
+
+USER root
+
+# add Ansible galaxy dependencies
+ADD requirements.yml /tmp/requirements.yml
+
+# install omsdk
+RUN pip install omsdk --upgrade
+
+# install Ansible Galaxy collections
+RUN ansible-galaxy collection install -r /tmp/requirements.yml --collections-path /usr/share/ansible/collections
+
+# add certificates
+RUN update-ca-trust force-enable
+RUN chmod -R 0777 /usr/share/ansible/collections
+
+USER 1000

+ 531 - 0
control_plane/roles/webui_awx/files/awx_operator.yml

@@ -0,0 +1,531 @@
+# 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
+  namespace: awx
+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
+                  default: awx
+                kind:
+                  description: Kind of the deployment type
+                  type: string
+                  default: AWX
+                api_version:
+                  description: apiVersion of the deployment type
+                  type: string
+                  default: awx.ansible.com/v1beta1
+                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
+                    - NodePort
+                    - nodeport
+                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_image_version:
+                  description: Application container image version 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_ee_extra_volume_mounts:
+                  description: Specify volume mounts to be added to Execution container
+                  type: string
+                tower_task_extra_volume_mounts:
+                  description: Specify volume mounts to be added to Task container
+                  type: string
+                tower_web_extra_volume_mounts:
+                  description: Specify volume mounts to be added to the Web container
+                  type: string
+                tower_redis_image:
+                  description: Registry path to the redis container to use
+                  type: string
+                tower_redis_image_version:
+                  description: Redis container image version to use
+                  type: string
+                tower_postgres_image:
+                  description: Registry path to the PostgreSQL container to use
+                  type: string
+                tower_postgres_image_version:
+                  description: PostgreSQL container image version to use
+                  type: string
+                tower_postgres_selector:
+                  description: nodeSelector for the Postgres pods
+                  type: string
+                tower_postgres_tolerations:
+                  description: node tolerations for the Postgres pods
+                  type: string
+                tower_postgres_storage_requirements:
+                  description: Storage requirements for the PostgreSQL container
+                  properties:
+                    requests:
+                      properties:
+                        storage:
+                          type: string
+                      type: object
+                    limits:
+                      properties:
+                        storage:
+                          type: string
+                      type: object
+                  type: object
+                tower_postgres_resource_requirements:
+                  description: Resource requirements for the PostgreSQL container
+                  properties:
+                    requests:
+                      properties:
+                        cpu:
+                          type: string
+                        memory:
+                          type: string
+                      type: object
+                    limits:
+                      properties:
+                        cpu:
+                          type: string
+                        memory:
+                          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
+                extra_settings:
+                  description: Extra settings to specify for the API
+                  items:
+                    properties:
+                      setting:
+                        type: string
+                      value:
+                        type: string
+                    type: object
+                  type: array
+              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
+metadata:
+  creationTimestamp: null
+  name: awx-operator
+  namespace: awx
+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
+      - statefulsets/scale
+    verbs:
+      - patch
+  - apiGroups:
+      - ""
+    resources:
+      - pods/exec
+    verbs:
+      - create
+      - get
+  - apiGroups:
+      - apps
+    resources:
+      - replicasets
+    verbs:
+      - get
+  - apiGroups:
+      - awx.ansible.com
+    resources:
+      - '*'
+    verbs:
+      - '*'
+
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: awx-operator
+  namespace: awx
+subjects:
+  - kind: ServiceAccount
+    name: awx-operator
+    namespace: awx
+roleRef:
+  kind: ClusterRole
+  name: awx-operator
+  apiGroup: rbac.authorization.k8s.io
+
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: awx-operator
+  namespace: awx
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: awx-operator
+  namespace: awx
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      name: awx-operator
+  template:
+    metadata:
+      labels:
+        name: awx-operator
+    spec:
+      serviceAccountName: awx-operator
+      containers:
+        - name: awx-operator
+          image: "quay.io/ansible/awx-operator:0.9.0"
+          imagePullPolicy: "Always"
+          volumeMounts:
+            - mountPath: /tmp/ansible-operator/runner
+              name: runner
+          env:
+            # Watch all namespaces (cluster-scoped).
+            - name: WATCH_NAMESPACE
+              value: ""
+            - name: POD_NAME
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.name
+            - name: OPERATOR_NAME
+              value: awx-operator
+            - name: ANSIBLE_GATHERING
+              value: explicit
+          livenessProbe:
+            httpGet:
+              path: /healthz
+              port: 6789
+            initialDelaySeconds: 15
+            periodSeconds: 20
+      volumes:
+        - name: runner
+          emptyDir: {}

+ 15 - 0
control_plane/roles/webui_awx/files/awx_postgres_pv.yml

@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+  name: awx-postgres-pv
+  namespace: awx
+  labels:
+    type: local
+spec:
+  storageClassName: nfs-client
+  capacity:
+    storage: 10Gi
+  accessModes:
+    - ReadWriteOnce
+  hostPath:
+    path: "/var/nfs_awx"

+ 29 - 0
control_plane/roles/webui_awx/files/awx_projects_pv.yml

@@ -0,0 +1,29 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+  name: awx-projects-pv
+  namespace: awx
+  labels:
+    type: local
+spec:
+  storageClassName: manual
+  capacity:
+    storage: 10Gi
+  accessModes:
+    - ReadWriteOnce
+  hostPath:
+    path: "/etc"
+
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: awx-pv-claim
+  namespace: awx
+spec:
+  storageClassName: manual
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 3Gi

+ 5 - 0
control_plane/roles/webui_awx/files/requirements.yml

@@ -0,0 +1,5 @@
+---
+collections:
+  - community.general
+  - dellemc.openmanage
+  - dellemc.os10

+ 118 - 270
control_plane/roles/webui_awx/tasks/awx_configuration.yml

@@ -1,4 +1,4 @@
-# Copyright 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
+# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -13,272 +13,120 @@
 # limitations under the License.
 ---
 
-# Get Current AWX configuration
-- name: Waiting for 30 seconds for UI components to be accessible
-  wait_for:
-    timeout: 30
-
-- name: Organization list
-  block:
-    - name: Get organization list
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        organizations list -f human
-      register: organizations_list
-      changed_when: no
-      no_log: True
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ organizations_list.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-- name: Project list
-  block:
-    - name: Get project list
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        projects list -f human
-      register: projects_list
-      changed_when: no
-      no_log: True
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ projects_list.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-- name: Inventory list
-  block:
-    - name: Get inventory list
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        inventory list -f human
-      register: inventory_list
-      changed_when: no
-      no_log: True
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ inventory_list.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-- name: Credential list
-  block:
-    - name: Get credentials list
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        credentials list -f human
-      register: credentials_list
-      changed_when: no
-      no_log: True
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ credentials_list.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-- name: Template List
-  block:
-    - name: Get template list
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        job_templates list -f human
-      register: job_templates_list
-      changed_when: no
-      no_log: True
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ job_templates_list.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-- name: Group names
-  block:
-    - name: If omnia-inventory exists, fetch group names in the inventory
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        groups list --inventory "{{ omnia_inventory_name }}" -f human
-      register: groups_list
-      when: omnia_inventory_name in inventory_list.stdout
-      no_log: True
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ groups_list.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-- name: Schedules list
-  block:
-    - name: Get schedules list
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        schedules list -f human
-      register: schedules_list
-      changed_when: no
-      no_log: True
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ schedules_list.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-# Delete Default Configurations
-- name: Delete default configurations
-  block:
-    - name: Delete default organization
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        organizations delete "{{ default_org }}"
-      when: default_org in organizations_list.stdout
-      register: register_error
-      no_log: True
-
-    - name: Delete default job template
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        job_templates delete "{{ default_template }}"
-      when: default_template in job_templates_list.stdout
-      register: register_error
-      no_log: True
-
-    - name: Delete default project
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        projects delete "{{ default_projects }}"
-      when: default_projects in projects_list.stdout
-      register: register_error
-      no_log: True
-
-    - name: Delete default credential
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        credentials delete "{{ default_credentials }}"
-      when: default_credentials in credentials_list.stdout
-      register: register_error
-      no_log: True
-
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ register_error.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
-
-# Create required configuration if not present
-- name: Create required configurations
-  block:
-    - name: Create organisation
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        organizations create --name "{{ organization_name }}"
-      when: organization_name not in organizations_list.stdout
-      register: register_error
-      no_log: True
-
-    - name: Create new project
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        projects create --name "{{ project_name }}" --organization "{{ organization_name }}"
-        --local_path "{{ role_path.split('/')[-4] }}"
-      when: project_name not in projects_list.stdout
-      register: register_error
-      no_log: True
-
-    - name: Create new omnia inventory
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        inventory create --name "{{ omnia_inventory_name }}" --organization "{{ organization_name }}"
-      when: omnia_inventory_name not in inventory_list.stdout
-      register: register_error
-      no_log: True
-
-    - name: Create groups in omnia inventory
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        groups create --name "{{ item }}" --inventory "{{ omnia_inventory_name }}"
-      when: omnia_inventory_name not in inventory_list.stdout or item not in groups_list.stdout
-      register: register_error
-      no_log: True
-      loop: "{{ group_names }}"
-
-    - name: Create credentials for omnia
-      command: >-
-        awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-        credentials create --name "{{ credential_name }}" --organization "{{ organization_name }}"
-        --credential_type "{{ credential_type }}"
-        --inputs '{"username": "{{ cobbler_username }}", "password": "{{ cobbler_password }}"}'
-      when: credential_name not in credentials_list.stdout
-      register: register_error
-      no_log: True
-
-    - name: DeployOmnia Template
-      block:
-        - name: Create template to deploy omnia
-          command: >-
-            awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-            job_templates create
-            --name "{{ omnia_template_name }}"
-            --job_type run
-            --inventory "{{ omnia_inventory_name }}"
-            --project "{{ project_name }}"
-            --playbook "{{ omnia_playbook }}"
-            --verbosity "{{ playbooks_verbosity }}"
-            --ask_skip_tags_on_launch true
-          register: register_error
-          no_log: True
-
-        - name: Associate credential
-          command: >-
-            awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-            job_templates associate "{{ omnia_template_name }}"
-            --credential ""{{ credential_name }}""
-          register: register_error
-          no_log: True
-
-      when: omnia_template_name not in job_templates_list.stdout
-
-    - name: DynamicInventory template
-      block:
-        - name: Create template to fetch dynamic inventory
-          command: >-
-            awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-            job_templates create
-            --name "{{ inventory_template_name }}"
-            --job_type run
-            --inventory "{{ omnia_inventory_name }}"
-            --project "{{ project_name }}"
-            --playbook "{{ inventory_playbook }}"
-            --verbosity "{{ playbooks_verbosity }}"
-            --use_fact_cache true
-          register: register_error
-          no_log: True
-
-        - name: Associate credential
-          command: >-
-            awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-            job_templates associate "{{ inventory_template_name }}"
-            --credential ""{{ credential_name }}""
-          register: register_error
-          no_log: True
-
-      when: inventory_template_name not in job_templates_list.stdout
-
-    - name: Schedule dynamic inventory template
-      block:
-        - name: Get unified job template list
-          command: >-
-            awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-            unified_job_templates list --name "{{ inventory_template_name }}" -f human
-          no_log: True
-          register: unified_job_template_list
-
-        - name: Get job ID
-          set_fact:
-            job_id: "{{ unified_job_template_list.stdout | regex_search('[0-9]+') }}"
-
-        - name: Schedule dynamic inventory job
-          command: >-
-            awx --conf.host "{{ awx_ip }}" --conf.username "{{ awx_user }}" --conf.password "{{ admin_password }}"
-            schedules create --name "{{ schedule_name }}"
-            --unified_job_template="{{ job_id }}" --rrule="{{ schedule_rule }}"
-          register: register_error
-          no_log: True
-
-      when: schedule_name not in schedules_list.stdout
-
-  rescue:
-    - name: Message
-      fail:
-        msg: "{{ register_error.stdout | regex_replace(awx_user) | regex_replace(admin_password) }}"
+# Deleting the defaults
+- name: Delete machine credential
+  awx.awx.tower_credential:
+    name: "{{ default_credential }}"
+    credential_type: "{{ default_credential_type }}"
+    state: absent
+    tower_config_file: "~/.tower_cli.cfg"
+
+- name: Delete job template
+  awx.awx.tower_job_template:
+    name: "{{ default_template }}"
+    state: absent
+    tower_config_file: "~/.tower_cli.cfg"
+    
+- name: Delete project
+  awx.awx.tower_project:
+    name: "{{ default_project }}"
+    state: absent
+    tower_config_file: "~/.tower_cli.cfg"
+
+- name: Delete organization
+  awx.awx.tower_organization:
+    name: "{{ default_org }}"
+    state: absent
+    tower_config_file: "~/.tower_cli.cfg"
+
+# Configuration begins
+- name: Create organization
+  awx.awx.tower_organization:
+    name: "{{ awx_organization }}"
+    description: "Name of organization using this product"
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+
+- name: Create awx inventories
+  awx.awx.tower_inventory:
+    name: "{{ item.name }}"
+    description: "{{ item.description }}"
+    organization: "{{ awx_organization }}"
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+  loop: "{{ inventory_names }}"
+  when: item.flag
+
+- name: Add groups to node_inventory
+  awx.awx.tower_group:
+    name: "{{ item.name }}"
+    description: "{{ item.description }}"
+    inventory: "node_inventory"
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+  loop: "{{ group_names }}"
+
+- name: Add project
+  awx.awx.tower_project:
+    name: "{{ project_name }}"
+    description: "{{ project_description }}"
+    organization: "{{ awx_organization }}"
+    scm_type: manual
+    local_path: "{{ role_path.split('/')[-4] }}"
+    default_environment: "custom-awx-ee"
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+
+- name: Add awx credentials
+  awx.awx.tower_credential:
+    name: "{{ item.name }}"
+    organization: "{{ awx_organization }}"
+    credential_type: "{{ item.type }}"
+    inputs:
+      username: "{{ item.username }}"
+      password: "{{ item.password }}"
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+  loop: "{{ credential_details }}"
+  changed_when: true
+  when: item.flag
+
+- name: Create awx job templates
+  awx.awx.tower_job_template:
+    name: "{{ item.name }}"
+    job_type: "run"
+    organization: "{{ awx_organization }}"
+    inventory: "{{ item.inventory }}"
+    project: "{{ project_name }}"
+    playbook: "{{ item.playbook }}"
+    credentials:
+      - "{{ item.credential }}"
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+  loop: "{{ job_template_details }}"
+  when: item.flag
+
+- name: Create deploy_omnia_template
+  awx.awx.tower_job_template:
+    name: "{{ item.name }}"
+    job_type: "run"
+    organization: "{{ awx_organization }}"
+    inventory: "{{ item.inventory }}"
+    project: "{{ project_name }}"
+    playbook: "{{ item.playbook }}"
+    credentials:
+      - "{{ item.credential }}"
+    ask_skip_tags_on_launch: true
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+  loop: "{{ deploy_omnia_details }}"
+
+- name: Build a schedule for idrac job template
+  awx.awx.tower_schedule:
+    name: "{{ item.name }}"
+    unified_job_template: "{{ item.template }}"
+    rrule: "{{ schedule_rule }}"
+    state: present
+    tower_config_file: "~/.tower_cli.cfg"
+  register: result
+  loop: "{{ scheduled_templates}}"

+ 71 - 0
control_plane/roles/webui_awx/tasks/configure_settings.yml

@@ -0,0 +1,71 @@
+# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
+#
+# 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.
+---
+
+# Get Current AWX configuration
+
+- name: Get awx-service Cluster-IP
+  command: "kubectl get svc awx-service -n {{ awx_namespace }} -o jsonpath='{.spec.clusterIP}'"
+  register: awx_cluster_ip
+  changed_when: false
+
+- name: Get AWX admin password
+  shell: "kubectl get secret awx-admin-password -n {{ awx_namespace }} -o jsonpath='{.data.password}' | base64 --decode"
+  register: awx_admin_password
+  changed_when: false
+
+- name: Check if config file exists
+  stat:
+    path: "~/.tower_cli.cfg"
+  register: config_file_status
+
+- name: Create config file
+  copy:
+    dest:  "~/.tower_cli.cfg"
+    content: |
+      [general]
+      host: http://{{ awx_cluster_ip.stdout }}
+      username: admin
+      password: {{ awx_admin_password.stdout }}
+      verify_ssl: false
+      use_token: false
+    owner: root
+    mode: "{{ file_perm }}"
+
+- name: Stop and disable firewalld
+  service:
+    name: firewalld
+    state: stopped
+    enabled: no
+
+- name: Waiting for the AWX UI to be up
+  uri:
+    url: "http://{{ awx_cluster_ip.stdout }}"
+    status_code: "{{ return_status }}"
+  register: display
+  until: display.status == 200
+  retries: 20
+  delay: 15
+  changed_when: false
+
+- name: Waiting for the AWX UI to be in running state
+  uri:
+    url: "http://{{ awx_cluster_ip.stdout }}"
+    status_code: "{{ return_status }}"
+    return_content: true
+  register: display
+  until: awx_ui_msg not in display.content
+  retries: 20
+  delay: 15
+  changed_when: false

+ 77 - 45
control_plane/roles/webui_awx/tasks/install_awx.yml

@@ -1,4 +1,4 @@
-# Copyright 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
+# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -15,50 +15,82 @@
 
 # Tasks for installing AWX
 
-- name: Change inventory file
+- name: Get all namespaces
+  command: kubectl get ns
+  changed_when: false
+  register: namespaces
+
+- name: Create namespace
+  command: "kubectl create namespace {{ awx_namespace }}"
+  changed_when: true
+  when: "'awx' not in namespaces.stdout"
+
+- name: Get K8s pods
+  command: "kubectl get pods -n {{ awx_namespace }}"
+  changed_when: false
+  register: k8s_pods
+
+- name: Deploy awx-operator
+  command: "kubectl apply -f {{ awx_operator_yml_file_path }}"
+  changed_when: true
+  when: '"awx-operator" not in k8s_pods.stdout'
+
+- name: Get K8s persistent volumes
+  command: "kubectl get pv -n {{ awx_namespace }}"
+  changed_when: false
+  register: k8s_pvs
+
+- name: Configure host volume as playbooks directory path
   replace:
-    path: "{{ awx_inventory_path }}"
-    regexp: "{{ item.regexp }}"
-    replace: "{{ item.replace }}"
-  loop:
-    - { name: Project data directory, regexp: "{{ project_data_dir_old }}" , replace: "{{ project_data_dir_new }}" }
-    - { name: Alternate DNS Servers, regexp: "{{ awx_alternate_dns_servers_old }}", replace: "{{ awx_alternate_dns_servers_new }}" }
-    - { name: Credentials, regexp: "{{ admin_password_old }}", replace: "{{ admin_password_new }}"}
-  loop_control:
-    label: "{{ item.name }}"
-  tags: install
-
-- name: Ensure port is 8081
-  lineinfile:
-    path: "{{ awx_inventory_path }}"
-    regexp: "{{ port_old }}"
-    line: "{{ port_new }}"
+    path: "{{ awx_pv_yml_file_path }}"
+    regexp: 'path: "/etc"'
+    replace: 'path: "{{ playbook_dir | dirname | dirname }}"'
+  when: "'awx-projects-pv' not in k8s_pvs.stdout"
+
+- name: Create persistent volume and volumeclaim for projects
+  command: "kubectl apply -f {{ awx_pv_yml_file_path }}"
+  changed_when: true
+  when: "'awx-projects-pv' not in k8s_pvs.stdout"
+
+- name: Create persistent volume for postgres
+  command: "kubectl apply -f {{ awx_postgres_pv_file_path }}"
+  changed_when: true
+  when: "'awx-postgres-pv' not in k8s_pvs.stdout"
+
+- name: Get the docker images
+  command: buildah images
+  changed_when: false
+  register: docker_images
+
+- name: Build the custom-awx-ee image from the docker file
+  command: "buildah bud -t custom-awx-ee {{ awx_ee_docker_file }}"
+  changed_when: false
+  when: "'custom-awx-ee' not in docker_images.stdout"
+
+- name: Waiting for awx-operator deployment to be up and running
+  shell: "kubectl wait --for=condition=available deployment/awx-operator -n {{ awx_namespace }} --timeout=600s"
+  changed_when: false
+
+- name: Deploy awx
+  command: "kubectl apply -f {{ awx_yml_file_path }}"
+  changed_when: true
+  when: not k8s_pods.stdout | regex_search('awx-([A-Za-z0-9]{10})-([A-Za-z0-9]{5})')
+
+- name: Install awxkit using pip3
+  pip:
+    name: awxkit
     state: present
 
-- name: Create pgdocker directory
-  file:
-    path: "{{ pgdocker_dir_path }}"
-    state: directory
-    mode: 0775
-  tags: install
-
-- name: Install AWX
-  block:
-    - name: Run AWX install.yml file
-      command: ansible-playbook -i inventory install.yml --extra-vars "admin_password={{ admin_password }}"
-      args:
-        chdir: "{{ awx_installer_path }}"
-      register: awx_installation
-      no_log: True
-
-  rescue:
-    - name: Check AWX status on machine
-      include_tasks: check_awx_status.yml
-
-    - name: Fail if container are not running
-      fail:
-        msg: "AWX installation failed with error msg:
-        {{ awx_installation.stdout | regex_replace(admin_password) }}."
-      when: not awx_status
-
-  tags: install
+- name: Install awx collection
+  command: "ansible-galaxy collection install awx.awx:{{ awx_version }}"
+  changed_when: true
+  register: installation_status
+
+- name: Wait for awx pods to get created
+  wait_for:
+    timeout: "{{ awx_wait_time }}"
+  when: not k8s_pods.stdout | regex_search('awx-([A-Za-z0-9]{10})-([A-Za-z0-9]{5})')
+
+- name: Waiting for awx deployment to be up and running
+  shell: "kubectl wait --for=condition=available deployment/awx -n {{ awx_namespace }} --timeout=1200s"
+  changed_when: false

+ 6 - 42
control_plane/roles/webui_awx/tasks/main.yml

@@ -1,4 +1,4 @@
-# Copyright 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
+# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,63 +14,27 @@
 ---
 
 # Tasks for Deploying AWX on the system
-- name: Check AWX status on machine
-  include_tasks: check_awx_status.yml
-  tags: install
-
-- name: Include control_plane_common variables
-  include_vars: ../../control_plane_common/vars/main.yml
-  tags: install
 
 - name: Internet validation
   include_tasks: ../../control_plane_common/tasks/internet_validation.yml
-  when: not awx_status
-  tags: install
-
-- name: Clone AWX repo
-  include_tasks: clone_awx.yml
-  when: not awx_status
-  tags: install
-
-- name: Modify firewall config
-  include_tasks: firewall_settings.yml
-  when: not awx_status
   tags: install
 
 - name: Install AWX
   include_tasks: install_awx.yml
-  when: not awx_status
-  tags: install
-
-- name: Status message
-  block:
-    - debug:
-        msg: "{{ message_skipped }}"
-        verbosity: 2
-      when: awx_status
-    - debug:
-        msg: "{{ message_installed }}"
-        verbosity: 2
-      when: not awx_status
   tags: install
 
 - name: Internet validation
   include_tasks: ../../control_plane_common/tasks/internet_validation.yml
   tags: install
 
-- name: Install AWX-CLI
-  include_tasks: install_awx_cli.yml
+- name: Configure settings
+  include_tasks: configure_settings.yml
   tags: install
 
-- name: Check if AWX-UI is accessible
-  include_tasks: ui_accessibility.yml
+- name: Internet validation
+  include_tasks: ../../control_plane_common/tasks/internet_validation.yml
   tags: install
 
 - name: Configure AWX
-  block:
-    - include_tasks: awx_configuration.yml
-  rescue:
-    - name: Display msg
-      debug:
-        msg: "{{ conf_fail_msg }}"
+  include_tasks: awx_configuration.yml
   tags: install

+ 50 - 46
control_plane/roles/webui_awx/vars/main.yml

@@ -1,4 +1,4 @@
-# Copyright 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
+# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,58 +12,62 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ---
-
 # vars file for webui_awx
 
-# Usage: clone_awx.yml
-awx_git_repo: "https://github.com/ansible/awx.git"
-docker_volume: "/var/lib/docker/volumes/{{ docker_volume_name }}"
-awx_repo_path: "{{ docker_volume }}/awx/"
-awx_installer_path: "{{ awx_repo_path }}/installer/"
-
 # Usage: install_awx.yml
-awx_inventory_path: "{{ awx_repo_path }}/installer/inventory"
-pgdocker_dir_path: /var/lib/pgdocker
-project_data_dir_old: "#project_data_dir=/var/lib/awx/projects"
-project_data_dir_new: "project_data_dir= {{ role_path + '/../../../..' }} "
-awx_alternate_dns_servers_old: '#awx_alternate_dns_servers="10.1.2.3,10.2.3.4"'
-awx_alternate_dns_servers_new: 'awx_alternate_dns_servers="8.8.8.8,8.8.4.4"'
-admin_password_old: "admin_password=password"
-admin_password_new: "#admin_password=password"
-port_old: "host_port=80"
-port_new: "host_port=8081"
+awx_namespace: awx
+awx_pv_yml_file_path: "{{ role_path }}/files/awx_projects_pv.yml"
+awx_postgres_pv_file_path: "{{ role_path }}/files/awx_postgres_pv.yml"
+awx_pvc_yml_file_path: "{{ role_path }}/files/awx_projects_pvclaim.yml"
+awx_operator_yml_file_path: "{{ role_path }}/files/awx_operator.yml"
+awx_ee_docker_file: "{{ role_path }}/files/awx_ee.yml"
+awx_yml_file_path: "{{ role_path }}/files/awx.yml"
+postgres_storage_class: nfs-client
+projects_existing_claim: awx-pv-claim
+awx_version: 19.1.0
+file_perm: 644
+awx_wait_time: 90
 
-# Usage: main.yml
-message_skipped: "Installation Skipped: AWX instance is already running on your system"
-message_installed: "Installation Successful"
-awx_ip: http://localhost:8081
+# Usage: configure_settings.yml
+awx_ui_msg: "AWX Upgrading"
 return_status: 200
-awx_ui_msg: "Password Dialog"
-conf_fail_msg: "AWX configuration failed at the last executed task."
-
-# Usage: install_awx_cli.yml
-awx_cli_repo: "https://releases.ansible.com/ansible-tower/cli/ansible-tower-cli-centos7.repo"
-awx_cli_repo_path: "/etc/yum.repos.d/ansible-tower-cli-centos7.repo"
 
 # Usage: awx_configuration.yml
-awx_user: admin         #Don't change it. It is set as admin while installing AWX
 default_org: Default
 default_template: 'Demo Job Template'
-default_projects: 'Demo Project'
-default_credentials: 'Demo Credential'
-organization_name: DellEMC
-project_name: omnia
-omnia_inventory_name: omnia_inventory
+default_project: 'Demo Project'
+default_credential: 'Demo Credential'
+default_credential_type: Machine
+organization_name: 'DellEMC'
+project_name: 'omnia'
+project_description: "Directory which contains configuration playbooks"
+inventory_names:
+  - { name: idrac_inventory, description: "Inventory to store IPs of idrac servers", flag: true }
+  - { name: ethernet_inventory, description: "Inventory to store IPs of ethernet switches", flag: "{{ ethernet_switch_support }}" }
+  - { name: infiniband_inventory, description: "Inventory to store IPs of infiniband switches", flag: "{{ ib_switch_support }}" }
+  - { name: powervault_me4_inventory, description: "Inventory to store IPs of ME4 servers", flag: "{{ powervault_support }}" }
+  - { name: node_inventory, description: "Inventory to store host IPs of servers", flag: true }
 group_names:
-  - manager
-  - compute
-credential_name: omnia_credential
-credential_type: Machine
-cobbler_username: root
-omnia_template_name: DeployOmnia
-omnia_playbook: omnia.yml
-inventory_template_name: DynamicInventory
-inventory_playbook: control_plane/collect_node_info.yml
-playbooks_verbosity: 0
-schedule_name: DynamicInventorySchedule
-schedule_rule: "DTSTART:20201201T000000Z RRULE:FREQ=MINUTELY;INTERVAL=10"
+  - { name: manager, description: "Group to store IP of head node" }
+  - { name: compute, description: "Group to store IPs of compute nodes" }
+  - { name: login, description: "Group to store IP of login node" }
+  - { name: nfs, description: "Group to store IP of NFS node" }
+credential_details:
+  - { name: idrac_credential, type: Network, username: "{{ idrac_username }}", password: "{{ idrac_password }}", flag: true }
+  - { name: ethernet_credential, type: Machine, username: "{{ ethernet_switch_username }}", password: "{{ ethernet_switch_password }}", flag: "{{ ethernet_switch_support }}" }
+  - { name: infiniband_credential, type: Network, username: "{{ ib_username }}", password: "{{ ib_password }}", flag: "{{ ib_switch_support }}" }
+  - { name: powervault_me4_credential, type: Network, username: "{{ powervault_me4_username }}", password: "{{ powervault_me4_password }}", flag: "{{ powervault_support }}" }
+  - { name: node_credential, type: Machine, username: root, password: "{{ provision_password }}", flag: true }
+job_template_details:
+  - { name: idrac_template, inventory: idrac_inventory, playbook: control_plane/idrac.yml, credential: idrac_credential, flag: true }
+  - { name: ethernet_template, inventory: ethernet_inventory, playbook: control_plane/ethernet.yml, credential: ethernet_credential, flag: "{{ ethernet_switch_support }}" }
+  - { name: infiniband_template, inventory: infiniband_inventory, playbook: control_plane/infiniband.yml, credential: infiniband_credential, flag: "{{ ib_switch_support }}" }
+  - { name: powervault_me4_template, inventory: powervault_me4_inventory, playbook: control_plane/powervault_me4.yml, credential: powervault_me4_credential, flag: "{{ powervault_support }}" }
+  - { name: node_inventory_job, inventory: node_inventory, playbook: control_plane/collect_node_info.yml, credential: node_credential, flag: true }
+  - { name: device_inventory_job, inventory: node_inventory, playbook: control_plane/collect_device_info.yml, credential: node_credential, flag: true }
+deploy_omnia_details:
+  - { name: deploy_omnia_template, inventory: node_inventory, playbook: omnia.yml, credential: node_credential }
+schedule_rule: "DTSTART:20210608T120000Z RRULE:FREQ=MINUTELY;INTERVAL=10"
+scheduled_templates:
+  - { name: NodeInventorySchedule, template: node_inventory_job }
+  - { name: DeviceInventorySchedule, template: device_inventory_job }