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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dist
*.egg-info
pandoc-*-amd64.deb
pandoc-*-windows-x86_64.msi
pandoc-*-x86_64-macOS.pkg
README.rst

# Environments
Expand All @@ -16,4 +17,4 @@ venv/

# Other
kubectl.exe
/build
/build
12 changes: 6 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ def get_version(rel_path):
description='Python for Maximo Application Suite Dev/Ops',
long_description=long_description,
install_requires=[
'pyyaml', # MIT License
'openshift', # Apache Software License
'kubernetes', # Apache Software License
'kubeconfig', # BSD License
'jinja2', # BSD License
'jinja2-base64-filters' # MIT License
'pyyaml', # MIT License
'openshift', # Apache Software License
'kubernetes', # Apache Software License
'kubeconfig', # BSD License
'jinja2', # BSD License
'jinja2-base64-filters' # MIT License
],
extras_require={
'dev': [
Expand Down
16 changes: 16 additions & 0 deletions src/mas/devops/ocp.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ def connect(server: str, token: str, skipVerify: bool = False) -> bool:
return True


def getNamespace(dynClient: DynamicClient, namespace: str) -> dict:
"""
Get a namespace
"""
namespaceAPI = dynClient.resources.get(api_version="v1", kind="Namespace")

try:
ns = namespaceAPI.get(name=namespace)
logger.debug(f"Namespace {namespace} exists")
return ns
except NotFoundError:
logger.debug(f"Namespace {namespace} does not exist")

return {}


def createNamespace(dynClient: DynamicClient, namespace: str) -> bool:
"""
Create a namespace if it does not exist
Expand Down
46 changes: 46 additions & 0 deletions src/mas/devops/sls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# *****************************************************************************
# Copyright (c) 2025 IBM Corporation and other Contributors.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# *****************************************************************************

import logging
from openshift.dynamic import DynamicClient
from openshift.dynamic.exceptions import NotFoundError, ResourceNotFoundError, UnauthorizedError

logger = logging.getLogger(__name__)


def listSLSInstances(dynClient: DynamicClient) -> list:
"""
Get a list of SLS instances on the cluster
"""
try:
slsAPI = dynClient.resources.get(api_version="sls.ibm.com/v1", kind="LicenseService")
return slsAPI.get().to_dict()['items']
except NotFoundError:
logger.info("There are no SLS instances installed on this cluster")
return []
except ResourceNotFoundError:
logger.info("LicenseService CRD not found on cluster")
return []
except UnauthorizedError:
logger.error("Error: Unable to verify SLS instances due to failed authorization: {e}")
return []


def findSLSByNamespace(namespace: str, instances: list = None, dynClient: DynamicClient = None):
if not instances and not dynClient:
return False

if not instances and dynClient:
instances = listSLSInstances(dynClient)

for instance in instances:
if namespace in instance['metadata']['namespace']:
return True
return False
16 changes: 11 additions & 5 deletions src/mas/devops/tekton.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def preparePipelinesNamespace(dynClient: DynamicClient, instanceId: str = None,
sleep(15)


def prepareInstallSecrets(dynClient: DynamicClient, instanceId: str, slsLicenseFile: str, additionalConfigs: dict = None, certs: str = None, podTemplates: str = None) -> None:
def prepareInstallSecrets(dynClient: DynamicClient, instanceId: str, slsLicenseFile: str = None, additionalConfigs: dict = None, certs: str = None, podTemplates: str = None) -> None:
namespace = f"mas-{instanceId}-pipelines"
secretsAPI = dynClient.resources.get(api_version="v1", kind="Secret")

Expand Down Expand Up @@ -178,10 +178,16 @@ def prepareInstallSecrets(dynClient: DynamicClient, instanceId: str, slsLicenseF
except NotFoundError:
pass

# TODO: Convert this to using secretsAPI.create()
result = kubectl.run(subcmd_args=['-n', namespace, 'create', 'secret', 'generic', 'pipeline-sls-entitlement', '--from-file', slsLicenseFile])
for line in result.split("\n"):
logger.debug(line)
if slsLicenseFile is None:
slsLicenseFile = {
"apiVersion": "v1",
"kind": "Secret",
"type": "Opaque",
"metadata": {
"name": "pipeline-sls-entitlement"
}
}
secretsAPI.create(body=slsLicenseFile, namespace=namespace)

# 3. Secret/pipeline-certificates
# -------------------------------------------------------------------------
Expand Down
7 changes: 7 additions & 0 deletions src/mas/devops/templates/pipelinerun-install.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,10 @@ spec:
# -------------------------------------------------------------------------
- name: sls_channel
value: '3.x'
{%- if sls_entitlement_file is defined and sls_entitlement_file != "" %}
- name: sls_entitlement_file
value: "{{ sls_entitlement_file }}"
{%- endif %}
{%- if sls_namespace is defined and sls_namespace != "" %}
- name: sls_namespace
value: "{{ sls_namespace }}"
Expand All @@ -298,6 +300,11 @@ spec:
- name: sls_mongodb_cfg_file
value: "{{ sls_mongodb_cfg_file }}"
{%- endif %}
{%- if sls_action is defined and sls_action != "" %}
- name: sls_action
value: "{{ sls_action }}"
{%- endif %}


# Dependencies - UDS/DRO (Required)
# -------------------------------------------------------------------------
Expand Down