Add OPA and Openshift AI
This commit is contained in:
49
roles/rhoai_maas/tasks/database.yml
Normal file
49
roles/rhoai_maas/tasks/database.yml
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
# Build maas-db-config (DB_CONNECTION_URL) from the CloudNativePG basic-auth secret.
|
||||
# RHOAI 3.5+ reads it from the infrastructure namespace; it must exist before the
|
||||
# DSC enables modelsAsAService.
|
||||
|
||||
- name: Read MaaS database credentials
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: v1
|
||||
kind: Secret
|
||||
namespace: "{{ rhoai_maas_db_secret_namespace }}"
|
||||
name: "{{ rhoai_maas_db_secret_name }}"
|
||||
register: __rhoai_maas_db_secret
|
||||
no_log: true
|
||||
|
||||
- name: Verify MaaS database credentials exist
|
||||
ansible.builtin.assert:
|
||||
that: __rhoai_maas_db_secret.resources | length > 0
|
||||
fail_msg: >-
|
||||
Secret {{ rhoai_maas_db_secret_namespace }}/{{ rhoai_maas_db_secret_name }} not found.
|
||||
Run the cloudnativepg_operator role first (playbooks/deploy_rhoai_maas.yml does this).
|
||||
|
||||
- name: Create MaaS infrastructure namespace
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ rhoai_maas_infra_namespace }}"
|
||||
|
||||
- name: Create maas-db-config secret
|
||||
vars:
|
||||
__db: "{{ __rhoai_maas_db_secret.resources[0].data }}"
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: maas-db-config
|
||||
namespace: "{{ rhoai_maas_infra_namespace }}"
|
||||
type: Opaque
|
||||
stringData:
|
||||
DB_CONNECTION_URL: >-
|
||||
postgresql://{{ __db.username | b64decode | urlencode | replace('/', '%2F') }}:{{
|
||||
__db.password | b64decode | urlencode | replace('/', '%2F') }}@{{
|
||||
__db.host | b64decode }}:{{ __db.port | b64decode }}/{{ __db.database | b64decode
|
||||
}}?sslmode={{ rhoai_maas_db_sslmode }}
|
||||
no_log: true
|
||||
41
roles/rhoai_maas/tasks/main.yml
Normal file
41
roles/rhoai_maas/tasks/main.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# Install Red Hat OpenShift AI 3.5 with Models-as-a-Service and register
|
||||
# in-cluster OpenAI-compatible servers (llama-coder) as MaaS ExternalModels.
|
||||
#
|
||||
# Follows "Govern LLM access with Models-as-a-Service" (RHOAI Self-Managed 3.5)
|
||||
# and its companion guide https://github.com/jharmison-redhat/rhoai-maas-guide.
|
||||
#
|
||||
# Order matters:
|
||||
# - GatewayClass before Kuadrant, or Kuadrant reports MissingDependency
|
||||
# (Istio is provisioned by the GatewayClass).
|
||||
# - maas-db-config before the DSC enables modelsAsAService.
|
||||
#
|
||||
# All tasks are idempotent (kubernetes.core.k8s state: present / patched).
|
||||
|
||||
- name: Install operators
|
||||
ansible.builtin.include_tasks: operator.yml
|
||||
loop: "{{ rhoai_maas_operators }}"
|
||||
loop_control:
|
||||
loop_var: __rhoai_maas_operator
|
||||
label: "{{ __rhoai_maas_operator.name }}"
|
||||
|
||||
- name: Configure platform (monitoring, gateway, Kuadrant)
|
||||
ansible.builtin.include_tasks: platform.yml
|
||||
|
||||
- name: Configure MaaS database secret
|
||||
ansible.builtin.include_tasks: database.yml
|
||||
|
||||
- name: Configure DataScienceCluster
|
||||
ansible.builtin.include_tasks: rhoai.yml
|
||||
|
||||
- name: Register models and access policies
|
||||
ansible.builtin.include_tasks: models.yml
|
||||
|
||||
- name: Display MaaS deployment summary
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "Models-as-a-Service ready!"
|
||||
- " Endpoint : https://{{ __rhoai_maas_hostname }}/v1"
|
||||
- " Models : {{ rhoai_maas_external_models | map(attribute='name') | join(', ') }}"
|
||||
- " API keys : RHOAI dashboard, or POST https://{{ __rhoai_maas_hostname }}/maas-api/v1/api-keys with an OpenShift token"
|
||||
- " Test : curl -H \"Authorization: Bearer $MAAS_API_KEY\" https://{{ __rhoai_maas_hostname }}/v1/models"
|
||||
165
roles/rhoai_maas/tasks/models.yml
Normal file
165
roles/rhoai_maas/tasks/models.yml
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
# ------------------------------------------------------------------
|
||||
# ExternalProvider + ExternalModel + MaaSModelRef per model
|
||||
# ------------------------------------------------------------------
|
||||
- name: Allow model namespaces to attach to the Gateway
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ item }}"
|
||||
definition:
|
||||
metadata:
|
||||
labels:
|
||||
maas.opendatahub.io/gateway-access: "true"
|
||||
opendatahub.io/dashboard: "true"
|
||||
loop: "{{ rhoai_maas_external_models | map(attribute='namespace') | unique }}"
|
||||
|
||||
- name: Mark provider API key secrets as MaaS-managed
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
api_version: v1
|
||||
kind: Secret
|
||||
namespace: "{{ item.namespace }}"
|
||||
name: "{{ item.api_key_secret }}"
|
||||
definition:
|
||||
metadata:
|
||||
labels:
|
||||
inference.llm-d.ai/ipp-managed: "true"
|
||||
loop: "{{ rhoai_maas_external_models }}"
|
||||
loop_control:
|
||||
label: "{{ item.namespace }}/{{ item.api_key_secret }}"
|
||||
|
||||
- name: Create ExternalProviders
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: inference.opendatahub.io/v1alpha1
|
||||
kind: ExternalProvider
|
||||
metadata:
|
||||
name: "{{ item.provider_name }}"
|
||||
namespace: "{{ item.namespace }}"
|
||||
spec:
|
||||
provider: "{{ item.provider_type }}"
|
||||
endpoint: "{{ item.endpoint }}"
|
||||
auth:
|
||||
type: apikey
|
||||
secretRef:
|
||||
name: "{{ item.api_key_secret }}"
|
||||
loop: "{{ rhoai_maas_external_models }}"
|
||||
loop_control:
|
||||
label: "{{ item.namespace }}/{{ item.provider_name }}"
|
||||
|
||||
- name: Wait for ExternalProviders to be ready
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: inference.opendatahub.io/v1alpha1
|
||||
kind: ExternalProvider
|
||||
namespace: "{{ item.namespace }}"
|
||||
name: "{{ item.provider_name }}"
|
||||
register: __rhoai_maas_provider
|
||||
until: (__rhoai_maas_provider.resources[0].status.phase | default('')) == 'Ready'
|
||||
retries: 30
|
||||
delay: 10
|
||||
loop: "{{ rhoai_maas_external_models }}"
|
||||
loop_control:
|
||||
label: "{{ item.namespace }}/{{ item.provider_name }}"
|
||||
|
||||
- name: Create ExternalModels
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: inference.opendatahub.io/v1alpha1
|
||||
kind: ExternalModel
|
||||
metadata:
|
||||
name: "{{ item.name }}"
|
||||
namespace: "{{ item.namespace }}"
|
||||
annotations:
|
||||
maas.opendatahub.io/tls: "{{ item.tls | default(true) | string | lower }}"
|
||||
maas.opendatahub.io/port: "{{ item.port | default(443) | string }}"
|
||||
spec:
|
||||
externalProviderRefs:
|
||||
- ref:
|
||||
name: "{{ item.provider_name }}"
|
||||
targetModel: "{{ item.target_model }}"
|
||||
apiFormat: "{{ item.api_format | default('openai-chat') }}"
|
||||
path: "{{ item.path | default('/v1/chat/completions') }}"
|
||||
weight: 100
|
||||
loop: "{{ rhoai_maas_external_models }}"
|
||||
loop_control:
|
||||
label: "{{ item.namespace }}/{{ item.name }}"
|
||||
|
||||
- name: Publish models to MaaS
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: maas.opendatahub.io/v1alpha1
|
||||
kind: MaaSModelRef
|
||||
metadata:
|
||||
name: "{{ item.name }}"
|
||||
namespace: "{{ item.namespace }}"
|
||||
annotations:
|
||||
openshift.io/display-name: "{{ item.display_name | default(item.name) }}"
|
||||
openshift.io/description: "{{ item.description | default('') }}"
|
||||
spec:
|
||||
modelRef:
|
||||
kind: ExternalModel
|
||||
name: "{{ item.name }}"
|
||||
loop: "{{ rhoai_maas_external_models }}"
|
||||
loop_control:
|
||||
label: "{{ item.namespace }}/{{ item.name }}"
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Access policies and quota (models-as-a-service namespace)
|
||||
# ------------------------------------------------------------------
|
||||
- name: Wait for the models-as-a-service namespace
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ __rhoai_maas_namespace }}"
|
||||
register: __rhoai_maas_ns
|
||||
until: __rhoai_maas_ns.resources | length > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Create MaaSAuthPolicies
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: maas.opendatahub.io/v1alpha1
|
||||
kind: MaaSAuthPolicy
|
||||
metadata:
|
||||
name: "{{ item.name }}"
|
||||
namespace: "{{ __rhoai_maas_namespace }}"
|
||||
annotations:
|
||||
openshift.io/display-name: "{{ item.display_name | default(item.name) }}"
|
||||
openshift.io/description: "{{ item.description | default('') }}"
|
||||
spec:
|
||||
modelRefs: "{{ item.model_refs }}"
|
||||
subjects:
|
||||
groups: "{{ item.groups | default([]) | map('community.general.dict_kv', 'name') | list }}"
|
||||
users: "{{ item.users | default([]) }}"
|
||||
loop: "{{ rhoai_maas_auth_policies }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Create MaaSSubscriptions
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: maas.opendatahub.io/v1alpha1
|
||||
kind: MaaSSubscription
|
||||
metadata:
|
||||
name: "{{ item.name }}"
|
||||
namespace: "{{ __rhoai_maas_namespace }}"
|
||||
annotations:
|
||||
openshift.io/display-name: "{{ item.display_name | default(item.name) }}"
|
||||
openshift.io/description: "{{ item.description | default('') }}"
|
||||
spec:
|
||||
owner:
|
||||
groups: "{{ item.groups | default([]) | map('community.general.dict_kv', 'name') | list }}"
|
||||
users: "{{ item.users | default([]) }}"
|
||||
modelRefs: "{{ item.model_refs }}"
|
||||
priority: "{{ item.priority | default(10) | int }}"
|
||||
loop: "{{ rhoai_maas_subscriptions }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
69
roles/rhoai_maas/tasks/operator.yml
Normal file
69
roles/rhoai_maas/tasks/operator.yml
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
# Install one OLM operator (Automatic approval) and wait for its CSV.
|
||||
# Expects __rhoai_maas_operator: {name, namespace, channel,
|
||||
# operator_group_target_namespaces?, namespace_labels?}
|
||||
|
||||
- name: Create operator namespace {{ __rhoai_maas_operator.namespace }}
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ __rhoai_maas_operator.namespace }}"
|
||||
labels: "{{ __rhoai_maas_operator.namespace_labels | default({}) }}"
|
||||
|
||||
# openshift-operators already has the global-operators OperatorGroup
|
||||
- name: Create OperatorGroup for {{ __rhoai_maas_operator.name }}
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: operators.coreos.com/v1
|
||||
kind: OperatorGroup
|
||||
metadata:
|
||||
name: "{{ __rhoai_maas_operator.name }}"
|
||||
namespace: "{{ __rhoai_maas_operator.namespace }}"
|
||||
spec: >-
|
||||
{{ {'targetNamespaces': __rhoai_maas_operator.operator_group_target_namespaces}
|
||||
if __rhoai_maas_operator.operator_group_target_namespaces is defined else {} }}
|
||||
when: __rhoai_maas_operator.namespace != 'openshift-operators'
|
||||
|
||||
- name: Subscribe to {{ __rhoai_maas_operator.name }}
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: operators.coreos.com/v1alpha1
|
||||
kind: Subscription
|
||||
metadata:
|
||||
name: "{{ __rhoai_maas_operator.name }}"
|
||||
namespace: "{{ __rhoai_maas_operator.namespace }}"
|
||||
spec:
|
||||
channel: "{{ __rhoai_maas_operator.channel }}"
|
||||
installPlanApproval: Automatic
|
||||
name: "{{ __rhoai_maas_operator.name }}"
|
||||
source: "{{ __rhoai_maas_operator.source | default('redhat-operators') }}"
|
||||
sourceNamespace: openshift-marketplace
|
||||
|
||||
- name: Wait for Subscription to report an installed CSV - {{ __rhoai_maas_operator.name }}
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: operators.coreos.com/v1alpha1
|
||||
kind: Subscription
|
||||
namespace: "{{ __rhoai_maas_operator.namespace }}"
|
||||
name: "{{ __rhoai_maas_operator.name }}"
|
||||
register: __rhoai_maas_sub
|
||||
until: (__rhoai_maas_sub.resources[0].status.installedCSV | default('')) | length > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Wait for CSV to succeed - {{ __rhoai_maas_operator.name }}
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: operators.coreos.com/v1alpha1
|
||||
kind: ClusterServiceVersion
|
||||
namespace: "{{ __rhoai_maas_operator.namespace }}"
|
||||
name: "{{ __rhoai_maas_sub.resources[0].status.installedCSV }}"
|
||||
register: __rhoai_maas_csv
|
||||
until: >-
|
||||
__rhoai_maas_csv.resources | length > 0 and
|
||||
__rhoai_maas_csv.resources[0].status.phase | default('') == 'Succeeded'
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
361
roles/rhoai_maas/tasks/platform.yml
Normal file
361
roles/rhoai_maas/tasks/platform.yml
Normal file
@@ -0,0 +1,361 @@
|
||||
---
|
||||
# ------------------------------------------------------------------
|
||||
# User Workload Monitoring (MaaS reports Degraded without it)
|
||||
# ------------------------------------------------------------------
|
||||
- name: Read cluster monitoring config
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: v1
|
||||
kind: ConfigMap
|
||||
namespace: openshift-monitoring
|
||||
name: cluster-monitoring-config
|
||||
register: __rhoai_maas_cmo
|
||||
|
||||
- name: Resolve cluster monitoring config
|
||||
ansible.builtin.set_fact:
|
||||
__rhoai_maas_cmo_config: >-
|
||||
{{ ((__rhoai_maas_cmo.resources[0].data['config.yaml'] | default('{}')) if __rhoai_maas_cmo.resources else '{}')
|
||||
| from_yaml | default({}, true) }}
|
||||
|
||||
- name: Enable User Workload Monitoring
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cluster-monitoring-config
|
||||
namespace: openshift-monitoring
|
||||
data:
|
||||
config.yaml: "{{ __rhoai_maas_cmo_config | combine({'enableUserWorkload': true}) | to_nice_yaml }}"
|
||||
when: not (__rhoai_maas_cmo_config.enableUserWorkload | default(false) | bool)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Gateway API: GatewayClass, Gateway, passthrough Route
|
||||
# ------------------------------------------------------------------
|
||||
- name: Read cluster ingress domain
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: config.openshift.io/v1
|
||||
kind: Ingress
|
||||
name: cluster
|
||||
register: __rhoai_maas_ingress
|
||||
when: rhoai_maas_hostname | length == 0
|
||||
|
||||
- name: Resolve MaaS hostname
|
||||
ansible.builtin.set_fact:
|
||||
__rhoai_maas_hostname: >-
|
||||
{{ rhoai_maas_hostname if rhoai_maas_hostname | length > 0
|
||||
else 'maas.' ~ __rhoai_maas_ingress.resources[0].spec.domain }}
|
||||
|
||||
- name: Create MaaS gateway certificate
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: "{{ __rhoai_maas_gateway_name }}-cert"
|
||||
namespace: "{{ __rhoai_maas_gateway_namespace }}"
|
||||
spec:
|
||||
secretName: "{{ rhoai_maas_gateway_cert_secret }}"
|
||||
issuerRef:
|
||||
name: "{{ rhoai_maas_gateway_cert_issuer }}"
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- "{{ __rhoai_maas_hostname }}"
|
||||
duration: 2160h
|
||||
renewBefore: 720h
|
||||
when: rhoai_maas_gateway_cert_issuer | length > 0
|
||||
|
||||
- name: Wait for MaaS gateway certificate to be issued
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
namespace: "{{ __rhoai_maas_gateway_namespace }}"
|
||||
name: "{{ __rhoai_maas_gateway_name }}-cert"
|
||||
register: __rhoai_maas_gw_cert
|
||||
until: >-
|
||||
(__rhoai_maas_gw_cert.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Ready') | selectattr('status', 'equalto', 'True') | list | length) > 0
|
||||
retries: 30
|
||||
delay: 10
|
||||
when: rhoai_maas_gateway_cert_issuer | length > 0
|
||||
|
||||
# Creating the GatewayClass makes the ingress operator install Service Mesh 3 (Istio)
|
||||
- name: Create openshift-default GatewayClass
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: openshift-default
|
||||
spec:
|
||||
controllerName: openshift.io/gateway-controller/v1
|
||||
|
||||
- name: Wait for GatewayClass to be accepted
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: gateway.networking.k8s.io/v1
|
||||
kind: GatewayClass
|
||||
name: openshift-default
|
||||
register: __rhoai_maas_gwc
|
||||
until: >-
|
||||
__rhoai_maas_gwc.resources | length > 0 and
|
||||
(__rhoai_maas_gwc.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Accepted') | selectattr('status', 'equalto', 'True') | list | length) > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Create Gateway deployment options
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: maas-gateway-options
|
||||
namespace: "{{ __rhoai_maas_gateway_namespace }}"
|
||||
data:
|
||||
deployment: |
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: istio-proxy
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: 2Gi
|
||||
|
||||
- name: Create MaaS Gateway
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: "{{ __rhoai_maas_gateway_name }}"
|
||||
namespace: "{{ __rhoai_maas_gateway_namespace }}"
|
||||
annotations:
|
||||
opendatahub.io/managed: "false"
|
||||
security.opendatahub.io/authorino-tls-bootstrap: "true"
|
||||
networking.istio.io/service-type: "{{ rhoai_maas_gateway_service_type }}"
|
||||
spec:
|
||||
gatewayClassName: openshift-default
|
||||
infrastructure:
|
||||
parametersRef:
|
||||
group: ""
|
||||
kind: ConfigMap
|
||||
name: maas-gateway-options
|
||||
listeners:
|
||||
- name: http
|
||||
hostname: "{{ __rhoai_maas_hostname }}"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
maas.opendatahub.io/gateway-access: "true"
|
||||
- name: https
|
||||
hostname: "{{ __rhoai_maas_hostname }}"
|
||||
port: 443
|
||||
protocol: HTTPS
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
maas.opendatahub.io/gateway-access: "true"
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
name: "{{ rhoai_maas_gateway_cert_secret }}"
|
||||
|
||||
- name: Wait for MaaS Gateway to be programmed
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: gateway.networking.k8s.io/v1
|
||||
kind: Gateway
|
||||
namespace: "{{ __rhoai_maas_gateway_namespace }}"
|
||||
name: "{{ __rhoai_maas_gateway_name }}"
|
||||
register: __rhoai_maas_gw
|
||||
until: >-
|
||||
(__rhoai_maas_gw.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Programmed') | selectattr('status', 'equalto', 'True') | list | length) > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Expose MaaS Gateway through the default router
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: route.openshift.io/v1
|
||||
kind: Route
|
||||
metadata:
|
||||
name: "{{ __rhoai_maas_gateway_name }}-https"
|
||||
namespace: "{{ __rhoai_maas_gateway_namespace }}"
|
||||
spec:
|
||||
host: "{{ __rhoai_maas_hostname }}"
|
||||
port:
|
||||
targetPort: https
|
||||
tls:
|
||||
termination: passthrough
|
||||
insecureEdgeTerminationPolicy: Redirect
|
||||
to:
|
||||
kind: Service
|
||||
name: "{{ __rhoai_maas_gateway_service }}"
|
||||
weight: 100
|
||||
when: rhoai_maas_gateway_create_route | bool
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Kuadrant (Authorino + Limitador) and Authorino TLS
|
||||
# ------------------------------------------------------------------
|
||||
- name: Create kuadrant-system namespace
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kuadrant-system
|
||||
|
||||
- name: Create Kuadrant instance
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: kuadrant.io/v1beta1
|
||||
kind: Kuadrant
|
||||
metadata:
|
||||
name: kuadrant
|
||||
namespace: kuadrant-system
|
||||
spec:
|
||||
observability:
|
||||
enable: true
|
||||
|
||||
# The Kuadrant operator only detects the Gateway API provider (Istio) at startup.
|
||||
# RHCL is installed before the GatewayClass provisions Istio, so on a fresh
|
||||
# install Kuadrant reports MissingDependency until the operator pod restarts.
|
||||
- name: Read Kuadrant status
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: kuadrant.io/v1beta1
|
||||
kind: Kuadrant
|
||||
namespace: kuadrant-system
|
||||
name: kuadrant
|
||||
register: __rhoai_maas_kuadrant
|
||||
until: >-
|
||||
(__rhoai_maas_kuadrant.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Ready') | list | length) > 0
|
||||
retries: 12
|
||||
delay: 5
|
||||
failed_when: false
|
||||
|
||||
- name: Restart the Kuadrant operator to detect Istio
|
||||
kubernetes.core.k8s:
|
||||
state: absent
|
||||
api_version: v1
|
||||
kind: Pod
|
||||
namespace: openshift-operators
|
||||
label_selectors:
|
||||
- app=kuadrant
|
||||
- control-plane=controller-manager
|
||||
when: >-
|
||||
(__rhoai_maas_kuadrant.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Ready') | map(attribute='reason') | first | default(''))
|
||||
== 'MissingDependency'
|
||||
|
||||
- name: Wait for Kuadrant to be ready
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: kuadrant.io/v1beta1
|
||||
kind: Kuadrant
|
||||
namespace: kuadrant-system
|
||||
name: kuadrant
|
||||
register: __rhoai_maas_kuadrant
|
||||
until: >-
|
||||
(__rhoai_maas_kuadrant.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Ready') | selectattr('status', 'equalto', 'True') | list | length) > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Wait for Authorino service
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: v1
|
||||
kind: Service
|
||||
namespace: kuadrant-system
|
||||
name: authorino-authorino-authorization
|
||||
register: __rhoai_maas_authorino_svc
|
||||
until: __rhoai_maas_authorino_svc.resources | length > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Request a service-ca serving certificate for Authorino
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
api_version: v1
|
||||
kind: Service
|
||||
namespace: kuadrant-system
|
||||
name: authorino-authorino-authorization
|
||||
definition:
|
||||
metadata:
|
||||
annotations:
|
||||
service.beta.openshift.io/serving-cert-secret-name: authorino-server-cert
|
||||
|
||||
- name: Wait for Authorino serving certificate
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: v1
|
||||
kind: Secret
|
||||
namespace: kuadrant-system
|
||||
name: authorino-server-cert
|
||||
register: __rhoai_maas_authorino_cert
|
||||
until: __rhoai_maas_authorino_cert.resources | length > 0
|
||||
retries: 30
|
||||
delay: 10
|
||||
no_log: true
|
||||
|
||||
- name: Enable Authorino TLS listener
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
api_version: operator.authorino.kuadrant.io/v1beta1
|
||||
kind: Authorino
|
||||
namespace: kuadrant-system
|
||||
name: authorino
|
||||
merge_type: merge
|
||||
definition:
|
||||
spec:
|
||||
listener:
|
||||
tls:
|
||||
enabled: true
|
||||
certSecretRef:
|
||||
name: authorino-server-cert
|
||||
|
||||
- name: Read Authorino deployment
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: apps/v1
|
||||
kind: Deployment
|
||||
namespace: kuadrant-system
|
||||
name: authorino
|
||||
register: __rhoai_maas_authorino_deploy
|
||||
|
||||
- name: Trust the service CA in Authorino
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
api_version: apps/v1
|
||||
kind: Deployment
|
||||
namespace: kuadrant-system
|
||||
name: authorino
|
||||
merge_type: strategic-merge
|
||||
definition:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: "{{ __rhoai_maas_authorino_deploy.resources[0].spec.template.spec.containers[0].name }}"
|
||||
env:
|
||||
- name: SSL_CERT_FILE
|
||||
value: /etc/ssl/certs/openshift-service-ca/service-ca-bundle.crt
|
||||
- name: REQUESTS_CA_BUNDLE
|
||||
value: /etc/ssl/certs/openshift-service-ca/service-ca-bundle.crt
|
||||
143
roles/rhoai_maas/tasks/rhoai.yml
Normal file
143
roles/rhoai_maas/tasks/rhoai.yml
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
- name: Wait for RHOAI CRDs
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
name: "{{ item }}"
|
||||
register: __rhoai_maas_crd
|
||||
until: >-
|
||||
__rhoai_maas_crd.resources | length > 0 and
|
||||
(__rhoai_maas_crd.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Established') | selectattr('status', 'equalto', 'True') | list | length) > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
loop:
|
||||
- dscinitializations.dscinitialization.opendatahub.io
|
||||
- datascienceclusters.datasciencecluster.opendatahub.io
|
||||
|
||||
- name: Configure DSCInitialization
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: dscinitialization.opendatahub.io/v2
|
||||
kind: DSCInitialization
|
||||
metadata:
|
||||
name: default-dsci
|
||||
spec:
|
||||
applicationsNamespace: "{{ __rhoai_maas_apps_namespace }}"
|
||||
monitoring:
|
||||
managementState: Managed
|
||||
trustedCABundle:
|
||||
managementState: Managed
|
||||
customCABundle: ""
|
||||
register: __rhoai_maas_dsci_result
|
||||
# The operator webhook may not be serving yet right after the CSV succeeds
|
||||
until: __rhoai_maas_dsci_result is not failed
|
||||
retries: 30
|
||||
delay: 10
|
||||
|
||||
- name: Resolve DataScienceCluster components
|
||||
ansible.builtin.set_fact:
|
||||
__rhoai_maas_dsc_components: >-
|
||||
{{ dict(rhoai_maas_dsc_managed_components | product([{'managementState': 'Managed'}]))
|
||||
| combine(dict(rhoai_maas_dsc_removed_components | product([{'managementState': 'Removed'}])))
|
||||
| combine(__rhoai_maas_dsc_component_overrides, recursive=True) }}
|
||||
|
||||
- name: Configure DataScienceCluster
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: datasciencecluster.opendatahub.io/v2
|
||||
kind: DataScienceCluster
|
||||
metadata:
|
||||
name: "{{ rhoai_maas_dsc_name }}"
|
||||
spec:
|
||||
components: "{{ __rhoai_maas_dsc_components }}"
|
||||
register: __rhoai_maas_dsc_result
|
||||
until: __rhoai_maas_dsc_result is not failed
|
||||
retries: 30
|
||||
delay: 10
|
||||
|
||||
# The API server silently prunes unknown fields, so a misspelled component
|
||||
# setting applies cleanly but leaves MaaS Removed and its CRDs never appear.
|
||||
- name: Verify MaaS is enabled in the DataScienceCluster
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
(__rhoai_maas_dsc_result.result.spec.components.aigateway.modelsAsAService.managementState
|
||||
| default('')) == 'Managed'
|
||||
fail_msg: >-
|
||||
DataScienceCluster {{ rhoai_maas_dsc_name }} does not have
|
||||
aigateway.modelsAsAService Managed after apply (field pruned or overridden):
|
||||
{{ __rhoai_maas_dsc_result.result.spec.components.aigateway | default({}) }}
|
||||
|
||||
- name: Wait for MaaS CRDs
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
name: "{{ item }}"
|
||||
register: __rhoai_maas_crd
|
||||
until: >-
|
||||
__rhoai_maas_crd.resources | length > 0 and
|
||||
(__rhoai_maas_crd.resources[0].status.conditions | default([])
|
||||
| selectattr('type', 'equalto', 'Established') | selectattr('status', 'equalto', 'True') | list | length) > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
loop:
|
||||
- maasmodelrefs.maas.opendatahub.io
|
||||
- maasauthpolicies.maas.opendatahub.io
|
||||
- maassubscriptions.maas.opendatahub.io
|
||||
- externalproviders.inference.opendatahub.io
|
||||
- externalmodels.inference.opendatahub.io
|
||||
- odhdashboardconfigs.opendatahub.io
|
||||
|
||||
# The operator normally labels this itself; keep it as a safety net
|
||||
- name: Allow the MaaS infrastructure namespace to attach to the Gateway
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ rhoai_maas_infra_namespace }}"
|
||||
definition:
|
||||
metadata:
|
||||
labels:
|
||||
maas.opendatahub.io/gateway-access: "true"
|
||||
|
||||
- name: Wait for maas-api to be available
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: apps/v1
|
||||
kind: Deployment
|
||||
namespace: "{{ rhoai_maas_infra_namespace }}"
|
||||
name: maas-api
|
||||
register: __rhoai_maas_api
|
||||
until: >-
|
||||
__rhoai_maas_api.resources | length > 0 and
|
||||
(__rhoai_maas_api.resources[0].status.availableReplicas | default(0)) >= 1
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Wait for the dashboard config
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: opendatahub.io/v1alpha
|
||||
kind: OdhDashboardConfig
|
||||
namespace: "{{ __rhoai_maas_apps_namespace }}"
|
||||
name: odh-dashboard-config
|
||||
register: __rhoai_maas_dashboard
|
||||
until: __rhoai_maas_dashboard.resources | length > 0
|
||||
retries: "{{ __rhoai_maas_wait_retries }}"
|
||||
delay: 10
|
||||
|
||||
- name: Enable MaaS and external models in the dashboard
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
api_version: opendatahub.io/v1alpha
|
||||
kind: OdhDashboardConfig
|
||||
namespace: "{{ __rhoai_maas_apps_namespace }}"
|
||||
name: odh-dashboard-config
|
||||
merge_type: merge
|
||||
definition:
|
||||
spec:
|
||||
dashboardConfig:
|
||||
modelAsService: true
|
||||
externalModels: true
|
||||
genAiStudio: true
|
||||
Reference in New Issue
Block a user