diff --git a/ci-templates/build.yml b/ci-templates/build.yml
index 79ab2b823b21de625797217f814222b4f1d3f3d6..64c988eb82981ad180d3e766ad49740d80bfe0e5 100644
--- a/ci-templates/build.yml
+++ b/ci-templates/build.yml
@@ -26,7 +26,7 @@
.angular_build:
extends: .default
stage: build
- image: trion/ng-cli:13.3.7
+ image: trion/ng-cli:14.2.9
script:
- |
if [ ! -f "./src/assets/config/theming.scss" ]; then
@@ -36,7 +36,7 @@
cp ./src/assets/config/config.prod.default.json ./src/assets/config/config.prod.json
fi
- npm install
- - ng build --configuration production --deleteOutputPath=false
+ - ng build --configuration production
artifacts:
paths:
- dist/
diff --git a/ci-templates/build_unprotected.yml b/ci-templates/build_unprotected.yml
index bf2678b8b766c2301b1ba1e7905cd2f46f02f3f9..55e0fdf74af304d2f1458ec01a1e509bcb94d1ba 100644
--- a/ci-templates/build_unprotected.yml
+++ b/ci-templates/build_unprotected.yml
@@ -20,7 +20,7 @@
.angular_build:
extends: .default
stage: build
- image: trion/ng-cli:13.3.7
+ image: trion/ng-cli:14.2.9
script:
- |
if [ ! -f "./src/assets/config/theming.scss" ]; then
@@ -30,7 +30,7 @@
cp ./src/assets/config/config.prod.default.json ./src/assets/config/config.prod.json
fi
- npm install
- - ng build --configuration production --deleteOutputPath=false
+ - ng build --configuration production
artifacts:
paths:
- dist/
diff --git a/compose/deploy.sh b/compose/deploy.sh
index d8ac5383db45435b482eb5355c904f8a5565059c..ba0cd282151b68e921f09d6633b074a0bf756051 100644
--- a/compose/deploy.sh
+++ b/compose/deploy.sh
@@ -43,6 +43,8 @@ updaterepo org.etsi.osl.osom
updaterepo org.etsi.osl.oas
updaterepo org.etsi.osl.tmf.api
updaterepo org.etsi.osl.cridge
+updaterepo org.etsi.osl.metrico
+updaterepo org.etsi.osl.mcp.server
updaterepo org.etsi.osl.tmf.web
updaterepo org.etsi.osl.portal.web
@@ -61,5 +63,5 @@ fi
echo "Installing npm packages..."
-docker run -u 0 --rm -v "$PWD":/app trion/ng-cli:13.3.7 npm install
-docker run -u 0 --rm -v "$PWD":/app trion/ng-cli:13.3.7 ng build --configuration production --deleteOutputPath=false
+docker run -u $(id -u) --rm -v "$PWD":/app trion/ng-cli:14.2.9 npm install
+docker run -u $(id -u) --rm -v "$PWD":/app trion/ng-cli:14.2.9 ng build --configuration production
diff --git a/compose/docker-compose.yaml.configure b/compose/docker-compose.yaml.configure
index ce1ebc0e978326442686c2a93bd11a61b33605ed..5026f35d2509cd4ca9da16e6a5b647aa5177d58d 100644
--- a/compose/docker-compose.yaml.configure
+++ b/compose/docker-compose.yaml.configure
@@ -1,4 +1,3 @@
-version: '3.4'
services:
artemis:
@@ -10,6 +9,11 @@ services:
- 8161:8161
- 61616:61616
- 61613:61613
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "3"
volumes:
- /var/log/activemq:/var/log/activemq
networks:
@@ -23,6 +27,11 @@ services:
ports:
- 80:80
- 443:443
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "500m"
+ max-file: "3"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/certificates:/etc/nginx/certificates
@@ -44,6 +53,11 @@ services:
MYSQL_ROOT_HOST: "%"
ports:
- "13306:3306"
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "200m"
+ max-file: "2"
volumes:
- ~/mysql/data:/var/lib/mysql
- ./mysql-init:/docker-entrypoint-initdb.d
@@ -51,32 +65,37 @@ services:
- back
keycloak:
- container_name: keycloak
- image: quay.io/keycloak/keycloak:16.1.1
- restart: always
- profiles: ["dev", "prod"]
- environment:
- DB_VENDOR: MYSQL
- DB_ADDR: amysql
- DB_DATABASE: keycloak
- DB_USER: keycloak
- DB_PASSWORD: password
- KEYCLOAK_USER: admin
- KEYCLOAK_PASSWORD: Pa55w0rd
- JDBC_PARAMS: "useSSL=false"
- JAVA_OPTS: "-server -Xms512m -Xmx2048m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -XX:+UseAdaptiveSizePolicy -XX:MaxMetaspaceSize=1024m -Djava.net.preferIPv4Stack=true -Djboss.as.management.blocking.timeout=3600"
- KEYCLOAK_IMPORT: /tmp/realm-export.json
- PROXY_ADDRESS_FORWARDING: "true"
- volumes:
- - ./keycloak-init:/tmp
- ports:
- - 8080:8080
- - 8443:8443
- depends_on:
- - mysql-portal
- networks:
- - front
- - back
+ container_name: keycloak
+ image: quay.io/keycloak/keycloak:16.1.1
+ restart: always
+ profiles: ["dev", "prod"]
+ environment:
+ DB_VENDOR: MYSQL
+ DB_ADDR: amysql
+ DB_DATABASE: keycloak
+ DB_USER: keycloak
+ DB_PASSWORD: password
+ KEYCLOAK_USER: admin
+ KEYCLOAK_PASSWORD: Pa55w0rd
+ JDBC_PARAMS: "useSSL=false"
+ JAVA_OPTS: "-server -Xms512m -Xmx2048m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -XX:+UseAdaptiveSizePolicy -XX:MaxMetaspaceSize=1024m -Djava.net.preferIPv4Stack=true -Djboss.as.management.blocking.timeout=3600"
+ KEYCLOAK_IMPORT: /tmp/realm-export.json
+ PROXY_ADDRESS_FORWARDING: "true"
+ volumes:
+ - ./keycloak-init:/tmp
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "200m"
+ max-file: "5"
+ ports:
+ - 8080:8080
+ - 8443:8443
+ depends_on:
+ - mysql-portal
+ networks:
+ - front
+ - back
osportalapi:
@@ -114,7 +133,7 @@ services:
logging:
driver: "json-file"
options:
- max-size: "1g"
+ max-size: "750m"
max-file: "3"
volumes:
- ./repo:/root
@@ -145,7 +164,7 @@ services:
logging:
driver: "json-file"
options:
- max-size: "1g"
+ max-size: "800m"
max-file: "3"
ports:
- 13011:13011
@@ -170,6 +189,11 @@ services:
"bugzillakey":"",
"main_operations_product":""
}'
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "200m"
+ max-file: "3"
ports:
- 13010:13010
networks:
@@ -244,6 +268,11 @@ services:
"logging.level.org.springframework" : "INFO",
"logging.level.org.etsi.osl.osom" : "INFO"
}'
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1g"
+ max-file: "3"
ports:
- 13100:13100
networks:
@@ -340,8 +369,8 @@ services:
"spring.activemq.brokerUrl": "tcp://anartemis:61616?jms.watchTopicAdvisories=false",
"spring.activemq.user": "artemis",
"spring.activemq.password": "artemis",
- "logging.level.org.springframework" : "DEBUG",
- "logging.level.org.etsi.osl.metrico" : "DEBUG"
+ "logging.level.org.springframework" : "INFO",
+ "logging.level.org.etsi.osl.metrico" : "INFO"
}'
logging:
driver: "json-file"
@@ -355,6 +384,43 @@ services:
- osscapi
- mysql-portal
+ oslmcp:
+ container_name: openslice-mcp
+ restart: always
+ profiles: ["prod"]
+ build:
+ context: ../../org.etsi.osl.mcp.server/
+ dockerfile: Dockerfile
+ image: labs.etsi.org:5050/osl/code/org.etsi.osl.mcp.server:latest
+ environment:
+ SPRING_APPLICATION_JSON: '{
+ "spring.datasource.url": "jdbc:mysql://amysql/osdb?createDatabaseIfNotExist=true",
+ "spring.datasource.username":"root",
+ "spring.datasource.password":"letmein",
+ "spring-addons.issuers[0].uri": "http://keycloak:8080/auth/realms/openslice",
+ "spring-addons.issuers[0].username-json-path":"$.preferred_username",
+ "spring-addons.issuers[0].claims[0].jsonPath":"$.realm_access.roles",
+ "spring-addons.issuers[0].claims[1].jsonPath":"$.resource_access.*.roles",
+ "spring.security.oauth2.resourceserver.jwt.issuer-uri": "http://keycloak:8080/auth/realms/openslice",
+ "springdoc.oAuthFlow.authorizationUrl": "http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/auth",
+ "springdoc.oAuthFlow.tokenUrl": "http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/token",
+ "springdoc.oauth.client-id" : "osapiWebClientId",
+ "springdoc.oauth.clientsecret" : "secret",
+ "spring.activemq.brokerUrl": "tcp://anartemis:61616?jms.watchTopicAdvisories=false",
+ "spring.activemq.user": "artemis",
+ "spring.activemq.password": "artemis",
+ "logging.level.org.springframework" : "INFO"
+ }'
+ ports:
+ - 13015:13015
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "500m"
+ max-file: "2"
+ networks:
+ - front
+ - back
portainer:
container_name: portainer
@@ -363,6 +429,11 @@ services:
profiles: ["dev", "prod"]
networks:
- front
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "3"
ports:
- 9000:9000
volumes:
@@ -385,6 +456,11 @@ services:
"centrallogurl":"http://elk_ip:elk_port/index_name/_doc",
"logging.level.org.springframework" : "INFO"
}'
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "800m"
+ max-file: "3"
ports:
- 13013:13013
networks:
@@ -399,6 +475,11 @@ services:
- blockdiag
environment:
- KROKI_BLOCKDIAG_HOST=blockdiag
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "500m"
+ max-file: "3"
ports:
- "8000:8000"
networks:
diff --git a/kubernetes/helm/openslice/Chart.yaml b/kubernetes/helm/openslice/Chart.yaml
index 8a0612ac2f0ea3b8c892ff22bfd446fba9221d44..506eb599e0f01c98092568510fa2fa7eaff9c5a3 100644
--- a/kubernetes/helm/openslice/Chart.yaml
+++ b/kubernetes/helm/openslice/Chart.yaml
@@ -15,9 +15,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 2.0.0
+version: 2.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
-appVersion: 2024Q4
+appVersion: 2025Q2
diff --git a/kubernetes/helm/openslice/templates/kroki-ingress.yaml b/kubernetes/helm/openslice/templates/kroki-ingress.yaml
index 5127bdb12296565a01db48edf23d8da25c270674..c1467645d8ef1159f30a4db93d165a20e737a367 100644
--- a/kubernetes/helm/openslice/templates/kroki-ingress.yaml
+++ b/kubernetes/helm/openslice/templates/kroki-ingress.yaml
@@ -10,7 +10,7 @@ metadata:
nginx.ingress.kubernetes.io/rewrite-target: "/$1"
name: {{ include "openslice.fullname" . }}-kroki-ingress
spec:
- ingressClassName: nginx
+ ingressClassName: {{ .Values.ingress.ingressClassName | quote }}
rules:
- http:
paths:
diff --git a/kubernetes/helm/openslice/templates/mcp-server-ingress.yaml.yaml b/kubernetes/helm/openslice/templates/mcp-server-ingress.yaml.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0c515e6a3a99a2611615397d092384d737e51745
--- /dev/null
+++ b/kubernetes/helm/openslice/templates/mcp-server-ingress.yaml.yaml
@@ -0,0 +1,23 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ include "openslice.fullname" . }}
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
+ {{- include "openslice.labels" . | nindent 4 }}
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: "/$1"
+ name: {{ include "openslice.fullname" . }}-mcpserver-ingress
+spec:
+ ingressClassName: {{ .Values.ingress.ingressClassName | quote }}
+ rules:
+ - http:
+ paths:
+ - pathType: ImplementationSpecific
+ path: "/mcpserver/(.*)"
+ backend:
+ service:
+ name: {{ include "openslice.fullname" . }}-mcpserver
+ port:
+ number: 13015
diff --git a/kubernetes/helm/openslice/templates/mcp-server.yaml b/kubernetes/helm/openslice/templates/mcp-server.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..942f9a9a170321dff7bfe69224f30655f25c15e3
--- /dev/null
+++ b/kubernetes/helm/openslice/templates/mcp-server.yaml
@@ -0,0 +1,76 @@
+{{- if .Values.mcpserver.enabled }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ include "openslice.fullname" . }}
+ org.etsi.osl.service: mcpserver
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
+ {{- include "openslice.labels" . | nindent 4 }}
+ name: {{ include "openslice.fullname" . }}-mcpserver
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ include "openslice.fullname" . }}
+ org.etsi.osl.service: mcpserver
+ {{- include "openslice.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ labels:
+ app: {{ include "openslice.fullname" . }}
+ org.etsi.osl.service: mcpserver
+ {{- include "openslice.selectorLabels" . | nindent 8 }}
+ spec:
+ containers:
+ - name: {{ include "openslice.fullname" . }}-mcpserver
+ image: "{{ .Values.image.mcpserver.repository }}:{{ .Values.image.mcpserver.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.mcpserver.pullPolicy | default "Always" }}
+ env:
+ - name: SPRING_APPLICATION_JSON
+ value: >-
+ {
+ "spring.datasource.url": "jdbc:mysql://{{ include "openslice.fullname" . }}-mysql/osdb?createDatabaseIfNotExist=true",
+ "spring.datasource.username": "{{ .Values.oscreds.mysql.username }}",
+ "spring.datasource.password": "{{ .Values.oscreds.mysql.password }}",
+ "spring-addons.issuers[0].uri": "{{ .Values.rooturl }}/auth/realms/openslice",
+ "spring-addons.issuers[0].username-json-path":"$.preferred_username",
+ "spring-addons.issuers[0].claims[0].jsonPath":"$.realm_access.roles",
+ "spring-addons.issuers[0].claims[1].jsonPath":"$.resource_access.*.roles",
+ "spring.security.oauth2.resourceserver.jwt.issuer-uri": "{{ .Values.rooturl }}/auth/realms/openslice",
+ "springdoc.oAuthFlow.authorizationUrl": "{{ .Values.rooturl }}/auth/realms/openslice/protocol/openid-connect/auth",
+ "springdoc.oAuthFlow.tokenUrl": "{{ .Values.rooturl }}/auth/realms/openslice/protocol/openid-connect/token",
+ "springdoc.oauth.client-id": "osapiWebClientId",
+ "springdoc.oauth.clientsecret": "{{ .Values.mcpserver.springdoc.clientSecret }}",
+ "spring.activemq.brokerUrl": "tcp://{{ include "openslice.fullname" . }}-artemis:61616?jms.watchTopicAdvisories=false",
+ "spring.activemq.user": "{{ .Values.oscreds.activemq.user }}",
+ "spring.activemq.password": "{{ .Values.oscreds.activemq.password }}",
+ "logging.level.org.springframework": "{{ .Values.mcpserver.spring.logLevel | default "INFO" }}"
+ }
+ ports:
+ - containerPort: 13015
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ restartPolicy: Always
+---
+apiVersion: v1
+kind: Service
+metadata:
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ include "openslice.fullname" . }}
+ org.etsi.osl.service: mcpserver
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
+ {{- include "openslice.labels" . | nindent 4 }}
+ name: {{ include "openslice.fullname" . }}-mcpserver
+spec:
+ ports:
+ - name: "13015"
+ port: 13015
+ targetPort: 13015
+ selector:
+ app: {{ include "openslice.fullname" . }}
+ org.etsi.osl.service: mcpserver
+ {{- include "openslice.selectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/kubernetes/helm/openslice/templates/openslice-ingress.yaml b/kubernetes/helm/openslice/templates/openslice-ingress.yaml
index a5f731485acad1a42297e77910cf176a152cc576..365ffc7a6caeeec3d9bc76c7740e7e0090d25989 100644
--- a/kubernetes/helm/openslice/templates/openslice-ingress.yaml
+++ b/kubernetes/helm/openslice/templates/openslice-ingress.yaml
@@ -10,7 +10,7 @@ metadata:
{{- toYaml .Values.ingress.annotations | nindent 4 }}
name: {{ include "openslice.fullname" . }}-openslice-ingress
spec:
- ingressClassName: nginx
+ ingressClassName: {{ .Values.ingress.ingressClassName | quote }}
rules:
- http:
paths:
diff --git a/kubernetes/helm/openslice/values.yaml b/kubernetes/helm/openslice/values.yaml
index ba45552be15c1de84c7e87548b52b0985b7b0d9a..cc86020d7d3eb3c0d9084c177ab5dc911e7e16c7 100644
--- a/kubernetes/helm/openslice/values.yaml
+++ b/kubernetes/helm/openslice/values.yaml
@@ -85,6 +85,11 @@ image:
pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion.
tag: "latest"
+ mcpserver:
+ repository: labs.etsi.org:5050/osl/code/org.etsi.osl.mcp.server
+ # Overrides the image tag whose default is the chart appVersion.
+ tag: latest
+ pullPolicy: Always
bugzillaurl: example.com:443/bugzilla
bugzillakey: VH2Vw0iI5aYgALFFzVDWqhACwt6Hu3bXla9kSC1Z
@@ -118,9 +123,9 @@ mysql:
metrico:
enabled: true
- logLevel: DEBUG
+ logLevel: INFO
spring:
- loglevel: DEBUG
+ loglevel: INFO
cridge:
enabled: true
@@ -154,6 +159,13 @@ osscapi:
spring:
loglevel: INFO
+mcpserver:
+ enabled: true
+ springdoc:
+ clientSecret: secret
+ spring:
+ logLevel: INFO
+
# Storage class to be used for provisioning. Default is manual
# storageClass: ~
@@ -190,6 +202,7 @@ service:
port: 80
ingress:
+ ingressClassName: nginx
paths:
- path: "/tmf-api"
service: "osscapi"
diff --git a/pom.xml b/pom.xml
index bfa0fc3e38a54253ce40a2a03ce7f78502c673d6..476803810245d5eadcb013bcd877bfcddc6e92e1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.etsi.osl
org.etsi.osl.main
- 2024Q4
+ 2025Q2
pom
org.etsi.osl.main
@@ -33,24 +33,25 @@
1.7.0
- 1.0.1
- 1.0.1
- 1.0.1
- 1.1.0
- 2024Q4
- 1.0.1
- 1.1.0
- 1.0.1
- 1.1.0
- 1.0.1
- 1.1.0
- 1.0.1
- 1.0.1
- 1.0.1
- 1.0.1
- 1.1.0
- 1.1.0
- 0.9
+ 1.0.2
+ 1.0.2
+ 1.0.2
+ 1.2.0
+ 2025Q2
+ 1.0.2
+ 1.1.1
+ 1.1.0
+ 1.2.0
+ 1.0.2
+ 1.2.0
+ 1.1.0
+ 1.0.2
+ 1.0.2
+ 1.0.2
+ 1.2.0
+ 1.2.0
+ 1.0.0
+ 1.0.0