Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/mas/devops/mas.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,26 @@ def verifyMasInstance(dynClient: DynamicClient, instanceId: str) -> bool:
return False


def verifyAiServiceInstance(dynClient: DynamicClient, instanceId: str) -> bool:
"""
Validate that the chosen AI Service instance exists
"""
try:
aiserviceAPI = dynClient.resources.get(api_version="aiservice.ibm.com/v1", kind="AIServiceApp")
aiserviceAPI.get(name=instanceId, namespace=f"aiservice-{instanceId}")
return True
except NotFoundError:
print("NOT FOUND")
return False
except ResourceNotFoundError:
# The AIServiceApp CRD has not even been installed in the cluster
print("RESOURCE NOT FOUND")
return False
except UnauthorizedError as e:
logger.error(f"Error: Unable to verify AI Service instance due to failed authorization: {e}")
return False


def verifyAppInstance(dynClient: DynamicClient, instanceId: str, applicationId: str) -> bool:
"""
Validate that the chosen app instance exists
Expand Down Expand Up @@ -260,6 +280,17 @@ def getAppsSubscriptionChannel(dynClient: DynamicClient, instanceId: str) -> lis
return []


def getAiserviceChannel(dynClient: DynamicClient, instanceId: str) -> str:
"""
Get the AI Service channel from the subscription
"""
aiserviceSubscription = getSubscription(dynClient, f"aiservice-{instanceId}", "ibm-aiservice")
if aiserviceSubscription is None:
return None
else:
return aiserviceSubscription.spec.channel


def updateIBMEntitlementKey(dynClient: DynamicClient, namespace: str, icrUsername: str, icrPassword: str, artifactoryUsername: str = None, artifactoryPassword: str = None, secretName: str = "ibm-entitlement") -> ResourceInstance:
if secretName is None:
secretName = "ibm-entitlement"
Expand Down
32 changes: 32 additions & 0 deletions src/mas/devops/tekton.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,3 +462,35 @@ def launchAiServiceInstallPipeline(dynClient: DynamicClient, params: dict) -> st

pipelineURL = f"{getConsoleURL(dynClient)}/k8s/ns/aiservice-{instanceId}-pipelines/tekton.dev~v1beta1~PipelineRun/{instanceId}-install-{timestamp}"
return pipelineURL


def launchAiServiceUpgradePipeline(dynClient: DynamicClient,
aiserviceInstanceId: str,
skipPreCheck: bool = False,
aiserviceChannel: str = "",
params: dict = {}) -> str:
"""
Create a PipelineRun to upgrade the chosen AI Service instance
"""
pipelineRunsAPI = dynClient.resources.get(api_version="tekton.dev/v1beta1", kind="PipelineRun")
namespace = f"aiservice-{aiserviceInstanceId}-pipelines"
timestamp = datetime.now().strftime("%y%m%d-%H%M")
# Create the PipelineRun
templateDir = path.join(path.abspath(path.dirname(__file__)), "templates")
env = Environment(
loader=FileSystemLoader(searchpath=templateDir)
)
template = env.get_template("pipelinerun-aiservice-upgrade.yml.j2")
renderedTemplate = template.render(
timestamp=timestamp,
aiservice_instance_id=aiserviceInstanceId,
skip_pre_check=skipPreCheck,
aiservice_channel=aiserviceChannel,
**params
)
logger.debug(renderedTemplate)
pipelineRun = yaml.safe_load(renderedTemplate)
pipelineRunsAPI.apply(body=pipelineRun, namespace=namespace)

pipelineURL = f"{getConsoleURL(dynClient)}/k8s/ns/aiservice-{aiserviceInstanceId}-pipelines/tekton.dev~v1beta1~PipelineRun/{aiserviceInstanceId}-upgrade-{timestamp}"
return pipelineURL
56 changes: 56 additions & 0 deletions src/mas/devops/templates/pipelinerun-aiservice-upgrade.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: "{{ aiservice_instance_id }}-upgrade-{{ timestamp }}"
labels:
tekton.dev/pipeline: aiservice-upgrade
spec:
pipelineRef:
name: aiservice-upgrade

serviceAccountName: "{{ service_account_name | default('pipeline', True) }}"
timeouts:
pipeline: "0"

params:
# Target AI Service Instance
# -------------------------------------------------------------------------
- name: aiservice_instance_id
value: "{{ aiservice_instance_id }}"
- name: aiservice_channel
value: "{{ aiservice_channel }}"

# IBM Entitlement Key
# -------------------------------------------------------------------------
- name: ibm_entitlement_key
value: "{{ ibm_entitlement_key }}"

{%- if skip_pre_check is defined and skip_pre_check != "" %}
# Skip pre-check
# -------------------------------------------------------------------------
- name: skip_pre_check
value: "{{ skip_pre_check }}"
{%- endif %}
{%- if artifactory_username is defined and artifactory_username != "" %}

# Enable development catalogs
# -------------------------------------------------------------------------
- name: artifactory_username
value: "{{ artifactory_username }}"
- name: artifactory_token
value: "{{ artifactory_token }}"
{%- endif %}

workspaces:
# The generated configuration files
# -------------------------------------------------------------------------
- name: shared-configs
persistentVolumeClaim:
claimName: config-pvc

# PodTemplates configurations
# -------------------------------------------------------------------------
- name: shared-pod-templates
secret:
secretName: pipeline-pod-templates