diff --git a/instance-applications/113-ibm-aiservice/Chart.yaml b/instance-applications/113-ibm-aiservice/Chart.yaml index 88e778886..0d40934f0 100644 --- a/instance-applications/113-ibm-aiservice/Chart.yaml +++ b/instance-applications/113-ibm-aiservice/Chart.yaml @@ -8,4 +8,9 @@ dependencies: - name: junitreporter version: 1.0.0 repository: "file://../../sub-charts/junitreporter/" - condition: junitreporter.devops_mongo_uri != "" \ No newline at end of file + condition: junitreporter.devops_mongo_uri != "" +- name: aiservice + version: 1.0.0 + repository: "file://../../sub-charts/aiservice/" + condition: aiservice.ibm-entitlement != "" + \ No newline at end of file diff --git a/instance-applications/113-ibm-aiservice/templates/04-aiservice-operator-subscription.yaml b/instance-applications/113-ibm-aiservice/templates/04-aiservice-operator-subscription.yaml index 77568b36d..e8cf427b7 100644 --- a/instance-applications/113-ibm-aiservice/templates/04-aiservice-operator-subscription.yaml +++ b/instance-applications/113-ibm-aiservice/templates/04-aiservice-operator-subscription.yaml @@ -1,16 +1,4 @@ {{- if .Values.cluster_admin_role }} ---- -apiVersion: v1 -kind: Secret -metadata: - name: ibm-entitlement - namespace: "{{ .Values.aiservice_namespace }}" - annotations: - argocd.argoproj.io/sync-wave: "146" -type: kubernetes.io/dockerconfigjson -data: - .dockerconfigjson: "{{ .Values.artifactory_token}}" - --- apiVersion: operators.coreos.com/v1 kind: OperatorGroup diff --git a/instance-applications/113-ibm-aiservice/templates/05-aiservice-subchart.yaml b/instance-applications/113-ibm-aiservice/templates/05-aiservice-subchart.yaml new file mode 100644 index 000000000..79ce6cb35 --- /dev/null +++ b/instance-applications/113-ibm-aiservice/templates/05-aiservice-subchart.yaml @@ -0,0 +1,122 @@ +{{- if .Values.application_admin_role }} +{{- $_job_name_prefix := "aiservice-subchart" }} +{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} +{{- $_job_config_values := omit .Values "junitreporter" }} +{{- $_job_version := "v1" }} +{{- $_job_hash := print ($_job_config_values | toYaml) $_cli_image_digest $_job_version | adler32sum }} +{{- $_job_name := join "-" (list $_job_name_prefix $_job_hash ) }} +{{- $_job_cleanup_group := cat $_job_name_prefix | sha1sum }} + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: aiservice-subchart-job + namespace: {{ .Values.aiservice_namespace }} + annotations: + argocd.argoproj.io/hook: PreSync +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: aiservice-subchart-job + namespace: "{{ .Values.aiservice_namespace }}" + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation +rules: + - apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "list", "patch", "delete"] + - apiGroups: [""] + resources: ["secrets", "configmaps", "serviceaccounts"] + verbs: ["get", "list", "patch", "delete"] + - apiGroups: ["operators.coreos.com"] + resources: ["subscriptions", "clusterserviceversions"] + verbs: ["get", "list"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: aiservice-subchart-job + namespace: "{{ .Values.aiservice_namespace }}" + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation +subjects: + - kind: ServiceAccount + name: postsync-aiservice-migration + namespace: "{{ .Values.aiservice_namespace }}" +roleRef: + kind: Role + name: postsync-aiservice-migration + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: aiservice-subchart-job + namespace: "{{ .Values.aiservice_namespace }}" + annotations: + argocd.argoproj.io/hook: PreSync +spec: + podSelector: + matchLabels: + app: sync-job + egress: + - {} + policyTypes: + - Egress +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ $_job_name }} + namespace: {{ .Values.aiservice_namespace }} + annotations: + argocd.argoproj.io/hook: PreSync + labels: + mas.ibm.com/job-cleanup-group: {{ $_job_cleanup_group }} +{{- if .Values.custom_labels }} +{{ .Values.custom_labels | toYaml | indent 4 }} +{{- end }} +spec: + template: + metadata: + labels: + app: sync-job +{{- if .Values.custom_labels }} +{{ .Values.custom_labels | toYaml | indent 8 }} +{{- end }} + spec: + serviceAccountName: aiservice-subchart-job + restartPolicy: OnFailure + containers: + - name: aiservice-subchart + image: quay.io/ibmmas/cli@{{ $_cli_image_digest }} + imagePullPolicy: IfNotPresent + env: + - name: SOURCE_NAMESPACE + value: "{{ .Values.aiservice_namespace }}" + - name: TARGET_NAMESPACE + value: "{{ .Values.tenantNamespace }}" + - name: ARTIFACTORY_TOKEN + value: "{{ .Values.artifactory_token }}" + - name: RELEASE_NAME + value: "{{ .Release.Name }}" + + command: + - /bin/sh + - -c + - | + set -e + + helm dependency update + echo $(pwd) + echo $(ls) + echo "Installing to $RELEASE_NAME token $ARTIFACTORY_TOKEN" + helm upgrade ibm-aiservice ./charts/aiservice --set .Values.aiservice.app_artifactory_token=$ARTIFACTORY_TOKEN + + echo "All secrets copied successfully" +{{- end }} diff --git a/instance-applications/113-ibm-aiservice/values.yaml b/instance-applications/113-ibm-aiservice/values.yaml index d90c02449..cecd2f25b 100644 --- a/instance-applications/113-ibm-aiservice/values.yaml +++ b/instance-applications/113-ibm-aiservice/values.yaml @@ -79,4 +79,8 @@ in_saas_env: "false" is_gitops_fvt_env: "false" #TENANT -mas_aiservice_tenant_name: "aiservice-{{ mas_aiservice_tenant_name }}" \ No newline at end of file +mas_aiservice_tenant_name: "aiservice-{{ mas_aiservice_tenant_name }}" + +#AIService Values +aiservice: + app_artifactory_token: diff --git a/instance-applications/115-ibm-aiservice-tenant/Chart.yaml b/instance-applications/115-ibm-aiservice-tenant/Chart.yaml index 186b9bb20..7e88c79db 100644 --- a/instance-applications/115-ibm-aiservice-tenant/Chart.yaml +++ b/instance-applications/115-ibm-aiservice-tenant/Chart.yaml @@ -8,4 +8,7 @@ dependencies: - name: junitreporter version: 1.0.0 repository: "file://../../sub-charts/junitreporter/" - condition: junitreporter.devops_mongo_uri != "" \ No newline at end of file + condition: junitreporter.devops_mongo_uri != "" +- name: aiservice + version: 1.0.0 + repository: "file://../../sub-charts/aiservice/" \ No newline at end of file diff --git a/instance-applications/115-ibm-aiservice-tenant/templates/06-aiservice-km-s3-secret.yaml b/instance-applications/115-ibm-aiservice-tenant/templates/06-aiservice-km-s3-secret.yaml deleted file mode 100644 index f15d43d5e..000000000 --- a/instance-applications/115-ibm-aiservice-tenant/templates/06-aiservice-km-s3-secret.yaml +++ /dev/null @@ -1,174 +0,0 @@ -{{- if .Values.application_admin_role }} -{{- $_job_name_prefix := "presync-copy-ai-secrets" }} -{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} -{{- $_job_config_values := omit .Values "junitreporter" }} -{{- $_job_version := "v5" }} -{{- $_job_hash := print ($_job_config_values | toYaml) $_cli_image_digest $_job_version | adler32sum }} -{{- $_job_name := join "-" (list $_job_name_prefix $_job_hash ) }} -{{- $_job_cleanup_group := cat $_job_name_prefix | sha1sum }} - ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: copy-secret-job-{{ .Values.tenantNamespace }} - namespace: {{ .Values.aiservice_namespace }} - annotations: - argocd.argoproj.io/sync-wave: "305" - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: secret-reader-{{ .Values.tenantNamespace }} - namespace: {{ .Values.aiservice_namespace }} - annotations: - argocd.argoproj.io/sync-wave: "305" - labels: - app.kubernetes.io/name: secret-reader - app.kubernetes.io/component: rbac - app.kubernetes.io/instance: {{ .Values.tenantNamespace }} - app.kubernetes.io/part-of: aiservice -rules: - - apiGroups: [""] - resources: ["secrets", "pods"] - verbs: ["get", "list"] - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: secret-reader-binding-{{ .Values.tenantNamespace }} - namespace: {{ .Values.aiservice_namespace }} - annotations: - argocd.argoproj.io/sync-wave: "306" -subjects: - - kind: ServiceAccount - name: copy-secret-job-{{ .Values.tenantNamespace }} - namespace: {{ .Values.aiservice_namespace }} -roleRef: - kind: Role - name: secret-reader-{{ .Values.tenantNamespace }} - apiGroup: rbac.authorization.k8s.io - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: secret-writer-{{ .Values.tenantNamespace }} - namespace: {{ .Values.tenantNamespace }} - annotations: - argocd.argoproj.io/sync-wave: "306" -rules: - - apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "create", "update", "patch"] - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: secret-writer-binding-{{ .Values.tenantNamespace }} - namespace: {{ .Values.tenantNamespace }} - annotations: - argocd.argoproj.io/sync-wave: "306" -subjects: - - kind: ServiceAccount - name: copy-secret-job-{{ .Values.tenantNamespace }} - namespace: {{ .Values.aiservice_namespace }} -roleRef: - kind: Role - name: secret-writer-{{ .Values.tenantNamespace }} - apiGroup: rbac.authorization.k8s.io ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-copy-secret-job-{{ .Values.tenantNamespace }} - namespace: "{{ .Values.aiservice_namespace }}" - annotations: - argocd.argoproj.io/sync-wave: "306" -spec: - podSelector: - matchLabels: - app: sync-job - egress: - - {} - policyTypes: - - Egress ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ $_job_name }} - namespace: {{ .Values.aiservice_namespace }} - annotations: - argocd.argoproj.io/sync-wave: "307" - labels: - mas.ibm.com/job-cleanup-group: {{ $_job_cleanup_group }} -{{- if .Values.custom_labels }} -{{ .Values.custom_labels | toYaml | indent 4 }} -{{- end }} -spec: - template: - metadata: - labels: - app: sync-job -{{- if .Values.custom_labels }} -{{ .Values.custom_labels | toYaml | indent 8 }} -{{- end }} - spec: - serviceAccountName: copy-secret-job-{{ .Values.tenantNamespace }} - restartPolicy: OnFailure - containers: - - name: copy-secrets - image: quay.io/ibmmas/cli@{{ $_cli_image_digest }} - imagePullPolicy: IfNotPresent - env: - - name: SOURCE_NAMESPACE - value: "{{ .Values.aiservice_namespace }}" - - name: TARGET_NAMESPACE - value: "{{ .Values.tenantNamespace }}" - - name: SECRETS_TO_COPY - value: "ibm-entitlement km-s3-secret" - command: - - /bin/sh - - -c - - | - set -e - echo "Starting secret copy from $SOURCE_NAMESPACE to $TARGET_NAMESPACE" - for SECRET_NAME in $SECRETS_TO_COPY; do - echo "--------------------------------------------------------" - echo "Copying secret: $SECRET_NAME" - echo "--------------------------------------------------------" - - if ! kubectl get secret $SECRET_NAME -n $SOURCE_NAMESPACE -o json > /tmp/${SECRET_NAME}.json; then - echo "Failed to get secret $SECRET_NAME from $SOURCE_NAMESPACE" - exit 1 - fi - - # Clean metadata fields to avoid resourceVersion conflicts - jq 'del(.metadata.resourceVersion, .metadata.uid, .metadata.creationTimestamp, .metadata.selfLink, .metadata.managedFields)' /tmp/${SECRET_NAME}.json \ - | sed "s/\"namespace\": \"$SOURCE_NAMESPACE\"/\"namespace\": \"$TARGET_NAMESPACE\"/" > /tmp/${SECRET_NAME}_clean.json - - # Delete the app label as this secret is not tracked by ArgoCD (it's not in Git) - jq 'del(.metadata.labels["app.kubernetes.io/instance"])' /tmp/${SECRET_NAME}_clean.json > /tmp/${SECRET_NAME}_clean2.json - - # These secrets are not defined in Git so exclude them from ArgoCD's reconcilliation. - jq '.metadata.annotations = (.metadata.annotations // {}) + {"argocd.argoproj.io/sync-options": "IgnoreExtraneous,Prune=false"}' \ - /tmp/${SECRET_NAME}_clean2.json > /tmp/${SECRET_NAME}_annotated.json - - if ! kubectl apply -f /tmp/${SECRET_NAME}_annotated.json; then - echo "Failed to apply $SECRET_NAME to $TARGET_NAMESPACE" - exit 1 - fi - - if ! kubectl get secret $SECRET_NAME -n $TARGET_NAMESPACE > /dev/null; then - echo "Secret $SECRET_NAME not found in $TARGET_NAMESPACE after apply" - exit 1 - fi - - echo "Successfully copied $SECRET_NAME to $TARGET_NAMESPACE" - done - echo "All secrets copied successfully" -{{- end }} diff --git a/sub-charts/aiservice/Chart.yaml b/sub-charts/aiservice/Chart.yaml new file mode 100644 index 000000000..e9ecfa21b --- /dev/null +++ b/sub-charts/aiservice/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: aiservice +description: | + Contains common shared resources for AIService. +type: application +version: 1.0.0 diff --git a/sub-charts/aiservice/README.md b/sub-charts/aiservice/README.md new file mode 100644 index 000000000..e37d59f83 --- /dev/null +++ b/sub-charts/aiservice/README.md @@ -0,0 +1,3 @@ +AIService +=============================================================================== +Updates common AIService resources when they are changed. \ No newline at end of file diff --git a/sub-charts/aiservice/templates/00-presync-aiservice-ibm-entitlement.yaml b/sub-charts/aiservice/templates/00-presync-aiservice-ibm-entitlement.yaml new file mode 100644 index 000000000..967379cd6 --- /dev/null +++ b/sub-charts/aiservice/templates/00-presync-aiservice-ibm-entitlement.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: ibm-entitlement + namespace: {{ .Values.aiservice_namespace }} + annotations: + argocd.argoproj.io/sync-wave: "146" + token: {{ .Values.app_artifactory_token }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{.Values.app_artifactory_token }} diff --git a/instance-applications/113-ibm-aiservice/templates/05-aiservice-km-s3-secret.yaml b/sub-charts/aiservice/templates/01-presync-aiservice-km-s3-secret.yaml similarity index 92% rename from instance-applications/113-ibm-aiservice/templates/05-aiservice-km-s3-secret.yaml rename to sub-charts/aiservice/templates/01-presync-aiservice-km-s3-secret.yaml index 711175ad1..42b414944 100644 --- a/instance-applications/113-ibm-aiservice/templates/05-aiservice-km-s3-secret.yaml +++ b/sub-charts/aiservice/templates/01-presync-aiservice-km-s3-secret.yaml @@ -1,11 +1,10 @@ -{{- if .Values.application_admin_role }} --- apiVersion: v1 kind: Secret type: Opaque metadata: name: km-s3-secret - namespace: "{{ .Values.aiservice_namespace }}" + namespace: {{ .Values.aiservice_namespace }} annotations: argocd.argoproj.io/sync-wave: "147" serving.kserve.io/s3-endpoint: "{{ .Values.aiservice_s3_host }}:{{ .Values.aiservice_s3_port }}" @@ -24,5 +23,3 @@ data: S3_PORT: {{ .Values.aiservice_s3_port | default "" | toString | b64enc | quote }} S3_REGION: {{ .Values.aiservice_s3_region | default "" | toString | b64enc | quote }} S3_SSL: {{ .Values.aiservice_s3_ssl | default true | toString | b64enc | quote }} - -{{- end }} diff --git a/sub-charts/aiservice/values.yaml b/sub-charts/aiservice/values.yaml new file mode 100644 index 000000000..7d8536397 --- /dev/null +++ b/sub-charts/aiservice/values.yaml @@ -0,0 +1,5 @@ +--- +ibm-entitlement: +km-s3-secret: + +app_artifactory_token: