diff --git a/Dockerfile b/Dockerfile index 6dca988..6a50106 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM +FROM python:3.13-slim ARG USER_ID=60577 ARG USER_NAME="eric-sdk" diff --git a/README.md b/README.md index 6999855..c6bf902 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ with the correct Python Sample App version. Run the following commands from within your project directory `eric-oss-hello-world-python-app-`. +**Note:** The App code present in the SDK portal ZIP package uses mTLS for communication with the platform. + ```bash mkdir -p helloworldAppPackage ``` @@ -166,10 +168,10 @@ See [Client Access to REST APIs](https://developer.intelligentautomationplatform Use the following command to generate a valid access token: ```bash -curl --cacert --request POST \ +curl --cert --key --cacert --request POST \ https:///auth/realms/master/protocol/openid-connect/token \ --header 'content-type: application/x-www-form-urlencoded' \ ---data "grant_type=client_credentials&client_id=&client_secret=" +--data "grant_type=client_credentials&client_id=" ``` This command returns an access token, which is used in the commands in the @@ -193,7 +195,7 @@ To start the onboarding of the Hello World CSAR app, run the following command in a command line tool. ```bash -curl --cacert --location --request POST 'https:///app-onboarding/v2/app-packages' \ +curl --cert --key --cacert --location --request POST 'https:///app-onboarding/v2/app-packages' \ --header 'Authorization: Bearer ' \ --header 'accept: application/json' \ --form 'file=@"/helloworldAppPackage.csar"' @@ -205,8 +207,8 @@ Example of command result: { "fileName": "helloworldAppPackage.csar", "onboardingJob": { - "id": "a2f0a43d-730a-4991-8481-746c3e76556e", - "href": "app-onboarding/v2/onboarding-jobs/a2f0a43d-730a-4991-8481-746c3e76556e" + "id": "af036040-a732-4af9-b65a-8103da56c35c", + "href": "/onboarding-jobs/af036040-a732-4af9-b65a-8103da56c35c" } } ``` @@ -217,7 +219,7 @@ This is the `JOB_ID`. Use the `JOB_ID` to get the status of the onboarding process in the following commands: ```bash -curl --cacert --location --request GET 'https:///app-onboarding/v2/onboarding-jobs/' \ +curl --cert --key --cacert --location --request GET 'https:///app-onboarding/v2/onboarding-jobs/' \ --header 'Authorization: Bearer ' \ --header 'accept: application/json' ``` @@ -229,37 +231,43 @@ Example of command result: ```json { - "id": "a2f0a43d-730a-4991-8481-746c3e76556e", + "id": "af036040-a732-4af9-b65a-8103da56c35c", "fileName": "helloworldAppPackage.csar", "packageVersion": "3.1.1-0", - "packageSize": "53.1282MiB", + "packageSize": "51.7659MiB", "vendor": "Ericsson", "type": "rApp", - "onboardStartedAt": "2024-09-13T09:48:53.239542Z", + "onboardStartedAt": "2025-05-31T13:51:56.616Z", "status": "ONBOARDED", - "onboardEndedAt": "2024-09-13T09:49:01.299826Z", + "onboardEndedAt": "2025-05-31T13:51:59.955Z", "events": [ { "type": "INFO", - "title": "Stored 1 out of 3 artifacts", - "detail": "Uploaded eric-oss-hello-world-python-app", - "occurredAt": "2024-09-13T09:48:57.556164Z" + "title": "Stored 1 out of 4 artifacts", + "detail": "Uploaded eric-oss-hello-world-python-appASD.yaml", + "occurredAt": "2025-05-31T13:51:58.042Z" }, { "type": "INFO", - "title": "Stored 2 out of 3 artifacts", - "detail": "Uploaded eric-oss-hello-world-python-appASD.yaml", - "occurredAt": "2024-09-13T09:48:57.556165Z" + "title": "Stored 2 out of 4 artifacts", + "detail": "Uploaded eric-oss-hello-world-python-app", + "occurredAt": "2025-05-31T13:51:58.043Z" }, { "type": "INFO", - "title": "Stored 3 out of 3 artifacts", + "title": "Stored 3 out of 4 artifacts", "detail": "Uploaded docker.tar", - "occurredAt": "2024-09-13T09:49:00.962182Z" + "occurredAt": "2025-05-31T13:51:59.792Z" + }, + { + "type": "INFO", + "title": "Stored 4 out of 4 artifacts", + "detail": "Uploaded security-metadata.json", + "occurredAt": "2025-05-31T13:51:59.812Z" } ], "self": { - "href": "app-onboarding/v2/onboarding-jobs/a2f0a43d-730a-4991-8481-746c3e76556e" + "href": "/onboarding-jobs/af036040-a732-4af9-b65a-8103da56c35c" }, "app": { "id": "rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0", @@ -273,7 +281,7 @@ command (rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0 in the example). Run the following command to initialize the App. ```bash -curl --cacert --location --request POST 'https:///app-lifecycle-management/v3/apps//initialization-actions' \ +curl --cert --key --cacert --location --request POST 'https:///app-lifecycle-management/v3/apps//initialization-actions' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' \ -d '{"action": "INITIALIZE"}' @@ -286,7 +294,7 @@ Example of command result: "app": { "status": "INITIALIZING", "id": "rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0", - "href": "/app-lifecycle-management/v3/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" + "href": "/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" } } ``` @@ -294,7 +302,7 @@ Example of command result: Repeat the following command until the status is changed to `INITIALIZED`. ```shell -curl --cacert --location --request GET 'https:///app-lifecycle-management/v3/apps/' \ +curl --cert --key --cacert --location --request GET 'https:///app-lifecycle-management/v3/apps/' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' ``` @@ -309,11 +317,11 @@ Example of command result: "name": "eric-oss-hello-world-python-app", "version": "3.1.1-0", "mode": "DISABLED", - "status": "INITIALIZING", - "createdAt": "2024-09-13T09:49:01.273Z", + "status": "INITIALIZED", + "createdAt": "2025-05-31T13:51:59.931Z", "components": [ { - "type": "MICROSERVICE", + "type": "ASD", "name": "eric-oss-hello-world-python-app", "version": "3.1.1-0", "artifacts": [ @@ -321,12 +329,23 @@ Example of command result: "name": "docker.tar", "type": "IMAGE" }, + { + "name": "eric-oss-hello-world-python-appASD.yaml", + "type": "OPAQUE" + }, { "name": "eric-oss-hello-world-python-app", "type": "HELM" - }, + } + ] + }, + { + "type": "SECURITYMANAGEMENT", + "name": "security-mgmt", + "version": "1.0.0", + "artifacts": [ { - "name": "eric-oss-hello-world-python-appASD.yaml", + "name": "security-metadata.json", "type": "OPAQUE" } ] @@ -339,9 +358,28 @@ Example of command result: } ], "roles": [], - "events": [], + "events": [ + { + "type": "INITIALIZE", + "title": "SUCCEEDED", + "detail": "INITIALIZE has successfully completed", + "createdAt": "2025-05-31T13:55:50.421Z" + }, + { + "type": "INITIALIZE", + "title": "STARTED", + "detail": "INITIALIZE has started", + "createdAt": "2025-05-31T13:55:34.171Z" + }, + { + "type": "CREATE", + "title": "SUCCEEDED", + "detail": "CREATE has successfully completed", + "createdAt": "2025-05-31T13:51:59.945Z" + } + ], "self": { - "href": "/app-lifecycle-management/v3/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" + "href": "/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" } } ``` @@ -349,7 +387,7 @@ Example of command result: Run the following command to switch the app mode from 'DISABLED' to 'ENABLED'. ```bash -curl --cacert --location --request PUT 'https:///app-lifecycle-management/v3/apps//mode' \ +curl --cert --key --cacert --location --request PUT 'https:///app-lifecycle-management/v3/apps//mode' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' \ -d '{"mode": "ENABLED"}' @@ -362,7 +400,7 @@ Example of command result: "mode": "ENABLED", "app": { "id": "rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0", - "href": "/app-lifecycle-management/v3/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" + "href": "/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" } } ``` @@ -386,14 +424,15 @@ This section describes how the App can communicate with IAM and produce logs to sample App first communicates with IAM to obtain a client token (login) before returning the "Hello World!!" string output. - The `platformCaCertSecretName` and `platformCaCertFileName` to enable - secure TLS communication. Refer to + secure communication. Refer to [App Certificate Provisioning Developer Guide](https://developer.intelligentautomationplatform.ericsson.net/#capabilities/app-cert-provisioning/developer-guide) to understand how certificates are loaded into the App during instantiation for secure communication. - - The `appSecretName`, `logEndpoint`, - `appKeyFileName`, `appCertFileName` - for mTLS communication. For more information on the variable values + - The `logEndpoint` endpoint designed to capture log data, supports only + mTLS communication. For more information on the variable values required, see [App Logging Developer Guide to Produce logs](https://developer.intelligentautomationplatform.ericsson.net/#capabilities/app-logging/how-to-produce-logs?chapter=identify-environment-and-secret-variables-names). + - The `appSecretName`, `appKeyFileName`, `appCertFileName` + used for mTLS communication to verify the client. ### Steps for Instantiation @@ -406,7 +445,7 @@ Run the following commands to start the instantiation process using the #### Create App Instance ```shell -curl --cacert --location --request POST 'https:///app-lifecycle-management/v3/app-instances' \ +curl --cert --key --cacert --location --request POST 'https:///app-lifecycle-management/v3/app-instances' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' \ @@ -419,35 +458,44 @@ Example command result: ```json { - "id": "rapp-ericsson-eric-oss-hello-world-python-app-28057851", + "id": "rapp-ericsson-eric-oss-hello-world-python-app-68129972", "appId": "rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0", "status": "UNDEPLOYED", "credentials": { - "clientId": "rapp-ericsson-eric-oss-hello-world-python-app-28057851" + "clientId": "rapp-ericsson-eric-oss-hello-world-python-app-68129972" }, "componentInstances": [ { "name": "eric-oss-hello-world-python-app", "version": "3.1.1-0", - "type": "MICROSERVICE", + "type": "ASD", "deployState": "UNDEPLOYED", "properties": { + "userDefinedHelmParameters": {}, "namespace": "", "timeout": 5 } + }, + { + "name": "security-mgmt", + "version": "1.0.0", + "type": "SECURITYMANAGEMENT", + "properties": { + "authenticatorType": "client-x509" + } } ], "self": { - "href": "/app-lifecycle-management/v3/app-instances/rapp-ericsson-eric-oss-hello-world-python-app-28057851" + "href": "/app-instances/rapp-ericsson-eric-oss-hello-world-python-app-68129972" }, "app": { - "href": "/app-lifecycle-management/v3/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" + "href": "/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" } } ``` An app-instance `id` is shown in the command result - (rapp-ericsson-eric-oss-hello-world-python-app-28057851 in the example). This + (rapp-ericsson-eric-oss-hello-world-python-app-68129972 in the example). This is the `APP_INSTANCE_ID` used in the following commands. #### Deploy App Instance @@ -455,8 +503,13 @@ An app-instance `id` is shown in the command result > All `userDefinedHelmParameters` are required for successful instantiation of your App. + **Note:** The `authenticationType` defines the authentication method the sample app + will use to communicate with IAM - set to `client-x509` for mTLS or + `client-secret` for TLS. This parameter is only used to navigate between TLS and mTLS + within the app code. + ```shell -curl --cacert --location --request POST 'https:///app-lifecycle-management/v3/app-instances//deployment-actions' \ +curl --cert --key --cacert --location --request POST 'https:///app-lifecycle-management/v3/app-instances//deployment-actions' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' \ @@ -475,13 +528,14 @@ curl --cacert --location --request POST 'https://", "platformCaCertFileName": "", "appKeyFileName": "", - "appCertFileName": "" + "appCertFileName": "", + "authenticationType": "" } } } ] } -}' \ +}' ``` See the following example command result: @@ -502,7 +556,8 @@ See the following example command result: "appSecretName": "", "logEndpoint": "", "appKeyFileName": "", - "appCertFileName": "" + "appCertFileName": "", + "authenticationType": "", } } } @@ -510,7 +565,7 @@ See the following example command result: }, "appInstance": { "status": "DEPLOYING", - "href": "/app-lifecycle-management/v3/app-instances/rapp-ericsson-eric-oss-hello-world-python-app-28057851" + "href": "/app-instances/rapp-ericsson-eric-oss-hello-world-python-app-68129972" } } ``` @@ -520,7 +575,7 @@ Use the App instance ID in the following command to check the instantiation to `"status":"DEPLOYED"`. ```shell -curl --cacert --location --request GET 'https:///app-lifecycle-management/v3/app-instances/' \ +curl --cert --key --cacert --location --request GET 'https:///app-lifecycle-management/v3/app-instances/' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' @@ -528,41 +583,69 @@ curl --cacert --location --request GET 'https://", - "platformCaCertFileName": "", "iamBaseUrl": "https://", - "appSecretName": "", "logEndpoint": "", + "platformCaCertSecretName": "", + "appSecretName": "", + "platformCaCertFileName": "", "appKeyFileName": "", - "appCertFileName": "" + "appCertFileName": "", + "authenticationType": "", }, "namespace": "", "timeout": 5 } + }, + { + "name": "security-mgmt", + "version": "1.0.0", + "type": "SECURITYMANAGEMENT", + "properties": { + "authenticatorType": "client-x509" + } + } + ], + "events": [ + { + "type": "DEPLOY", + "title": "SUCCEEDED", + "detail": "DEPLOY has successfully completed", + "createdAt": "2025-05-31T14:04:16.297Z" + }, + { + "type": "DEPLOY", + "title": "STARTED", + "detail": "DEPLOY has started", + "createdAt": "2025-05-31T14:04:15.609Z" + }, + { + "type": "CREATE", + "title": "SUCCEEDED", + "detail": "CREATE has successfully completed", + "createdAt": "2025-05-31T14:01:01.753Z" } ], - "events": [], "self": { - "href": "/app-lifecycle-management/v3/app-instances/rapp-ericsson-eric-oss-hello-world-python-app-28057851" + "href": "/app-instances/rapp-ericsson-eric-oss-hello-world-python-app-68129972" }, "app": { - "href": "/app-lifecycle-management/v3/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" + "href": "/apps/rapp-ericsson-eric-oss-hello-world-python-app-3-1-1-0" } } ``` @@ -578,7 +661,7 @@ For details, see [Service Exposure - Developer Guide](https://developer.intellig To create an API to be onboarded, run the following commands: ```bash -curl --cacert --location --request POST 'https:///hub/apiprovisioning/v1/admin/v3/apis' \ +curl --cert --key --cacert --location --request POST 'https:///hub/apiprovisioning/v1/admin/v3/apis' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ @@ -604,7 +687,7 @@ To create an endpoint for the previously generated API, run the following command: ```bash -curl --cacert --location --request POST 'https:///hub/apiprovisioning/v1/admin/v3/apis/hello-world-python-route-001/endpoints' \ +curl --cert --key --cacert --location --request POST 'https:///hub/apiprovisioning/v1/admin/v3/apis/hello-world-python-route-001/endpoints' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ @@ -617,7 +700,7 @@ To bind the plugin for authorization of the previously generated API, run the following command: ```bash -curl --cacert --location --request PUT 'https:///hub/apiprovisioning/v1/admin/v3/apis/hello-world-python-route-001/phases/auth/plugin-list' \ +curl --cert --key --cacert --location --request PUT 'https:///hub/apiprovisioning/v1/admin/v3/apis/hello-world-python-route-001/phases/auth/plugin-list' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '[ @@ -631,7 +714,7 @@ To configure the binded plugin for authorization, run the following command: ```bash -curl --cacert --location --request PUT 'https:///hub/apiprovisioning/v1/admin/v3/apis/hello-world-python-route-001/plugins/requestPartyTokenInterceptor/configuration' \ +curl --cert --key --cacert --location --request PUT 'https:///hub/apiprovisioning/v1/admin/v3/apis/hello-world-python-route-001/plugins/requestPartyTokenInterceptor/configuration' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ @@ -649,7 +732,7 @@ Role-Based Access Control (RBAC) configuration is required. To add the RBAC policy run the following curl command: ```bash -curl --cacert --location --request POST 'https:///idm/rolemgmt/v1/extapp/rbac' \ +curl --cert --key --cacert --location --request POST 'https:///idm/rolemgmt/v1/extapp/rbac' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' \ --data '{ diff --git a/charts/eric-oss-hello-world-python-app/Chart.yaml b/charts/eric-oss-hello-world-python-app/Chart.yaml index 2f6aa4f..2a2ddd9 100644 --- a/charts/eric-oss-hello-world-python-app/Chart.yaml +++ b/charts/eric-oss-hello-world-python-app/Chart.yaml @@ -3,4 +3,4 @@ appVersion: "2.0.0" description: IDUN SDK Hello World App name: eric-oss-hello-world-python-app type: application -version: VERSION +version: 1.0.1-1 diff --git a/charts/eric-oss-hello-world-python-app/eric-product-info.yaml b/charts/eric-oss-hello-world-python-app/eric-product-info.yaml index ecd4eb7..d2964cd 100644 --- a/charts/eric-oss-hello-world-python-app/eric-product-info.yaml +++ b/charts/eric-oss-hello-world-python-app/eric-product-info.yaml @@ -5,6 +5,6 @@ images: productName: "Python hello world sample app image" productNumber: "" registry: "armdocker.rnd.ericsson.se" - repoPath: "REPO_PATH" + repoPath: "proj-eric-oss-drop" name: "eric-oss-hello-world-python-app" - tag: "VERSION" + tag: "1.0.1-1" diff --git a/charts/eric-oss-hello-world-python-app/templates/_helpers.tpl b/charts/eric-oss-hello-world-python-app/templates/_helpers.tpl index b584d95..25f27e0 100644 --- a/charts/eric-oss-hello-world-python-app/templates/_helpers.tpl +++ b/charts/eric-oss-hello-world-python-app/templates/_helpers.tpl @@ -341,4 +341,21 @@ Define the annotations for security policy */}} {{- define "eric-oss-hello-world-python-app.securityPolicy.annotations" -}} # Automatically generated annotations for documentation purposes. -{{- end -}} \ No newline at end of file +{{- end -}} + +{{/* +Define the function to get the secret name + */}} +{{- define "eric-oss-hello-world-python-app.clientSecret" -}} +{{- $clientSecret := "" -}} +{{- if .Values.global }} + {{- if .Values.global.clientCredentials }} + {{- if .Values.global.clientCredentials.secret }} + {{- if .Values.global.clientCredentials.secret.name }} + {{- $clientSecret = .Values.global.clientCredentials.secret.name }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- print $clientSecret }} +{{- end }} \ No newline at end of file diff --git a/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml b/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml index 511d61e..78bd37c 100644 --- a/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml @@ -63,6 +63,10 @@ spec: secret: secretName: {{ index .Values "appSecretName" | quote }} defaultMode: 420 + - name: client-creds + secret: + secretName: {{ include "eric-oss-hello-world-python-app.clientSecret" . | quote }} + defaultMode: 420 containers: - name: eric-oss-hello-world-python-app image: {{ template "eric-oss-hello-world-python-app.imagePath" (dict "imageId" "eric-oss-hello-world-python-app" "values" .Values "files" .Files) }} @@ -89,6 +93,9 @@ spec: - name: app-certs mountPath: {{ index .Values "appCertMountPath" | default .Values.instantiationDefaults.appCertMountPath | quote }} readOnly: true + - name: client-creds + mountPath: {{ index .Values "clientCredsMountPath" | default .Values.instantiationDefaults.clientCredsMountPath | quote }} + readOnly: true env: - name: IAM_CLIENT_ID value: {{ index .Values "clientId" | quote }} @@ -108,6 +115,12 @@ spec: value: {{ index .Values "appCertFileName" | quote }} - name: APP_CERT_FILE_PATH value: {{ index .Values "appCertMountPath" | default .Values.instantiationDefaults.appCertMountPath | quote }} + - name: CLIENT_CREDS_FILE_PATH + value: {{ index .Values "clientCredsMountPath" | default .Values.instantiationDefaults.clientCredsMountPath | quote }} + - name: CLIENT_ID_FILE_NAME + value: {{ .Values.global.clientCredentials.secret.clientIdKey | quote }} + - name: AUTHENTICATION_TYPE + value: {{ index .Values "authenticationType" | default .Values.instantiationDefaults.authenticationType | quote }} - name: SERVICE_NAME value: {{ .Chart.Name }} - name: CONTAINER_NAME diff --git a/charts/eric-oss-hello-world-python-app/values.yaml b/charts/eric-oss-hello-world-python-app/values.yaml index 3acc20f..06ff323 100644 --- a/charts/eric-oss-hello-world-python-app/values.yaml +++ b/charts/eric-oss-hello-world-python-app/values.yaml @@ -5,13 +5,13 @@ global: timezone: UTC registry: url: armdocker.rnd.ericsson.se - imagePullPolicy: IfNotPresent + imagePullPolicy: Always pullSecret: internalIPFamily: imageCredentials: repoPath: - pullPolicy: IfNotPresent + pullPolicy: Always registry: url: pullSecret: @@ -126,3 +126,10 @@ podPriority: instantiationDefaults: platformCaCertMountPath: "/etc/tls-ca/platform/" appCertMountPath: "/etc/tls/log/" + clientCredsMountPath: "/etc/client-creds/" + +global: + clientCredentials: + secret: + clientIdKey: "clientId" + name: "-cc" diff --git a/csar/Definitions/AppDescriptor.yaml b/csar/Definitions/AppDescriptor.yaml index 0fb0a96..876c9fb 100644 --- a/csar/Definitions/AppDescriptor.yaml +++ b/csar/Definitions/AppDescriptor.yaml @@ -1,10 +1,14 @@ #tosca_definitions_version: Metadata/Tosca.meta Description of an APP: APPName: eric-oss-hello-world-python-app - APPVersion: VERSION + APPVersion: 1.0.1-1 APPType: rApp -APPComponent: - NameofComponent: eric-oss-hello-world-python-app - Version: VERSION - Path: OtherDefinitions/ASD/eric-oss-hello-world-python-appASD.yaml - ArtefactType: Microservice +AppComponentList: + - NameofComponent: eric-oss-hello-world-python-app + Version: 1.0.1-1 + Path: OtherDefinitions/ASD/eric-oss-hello-world-python-appASD.yaml + ArtefactType: ASD + - NameofComponent: security-mgmt + Version: 1.0.0 + Path: OtherDefinitions/SecurityManagement + ArtefactType: SecurityManagement \ No newline at end of file diff --git a/csar/OtherDefinitions/ASD/eric-oss-hello-world-python-appASD.yaml b/csar/OtherDefinitions/ASD/eric-oss-hello-world-python-appASD.yaml index c570dd0..d2cf1dd 100644 --- a/csar/OtherDefinitions/ASD/eric-oss-hello-world-python-appASD.yaml +++ b/csar/OtherDefinitions/ASD/eric-oss-hello-world-python-appASD.yaml @@ -2,9 +2,9 @@ asdId: 1 asdSchemaVersion: 1.0.0 asdProvider: Ericsson asdApplicationName: eric-oss-hello-world-python-app -asdApplicationVersion: VERSION +asdApplicationVersion: 1.0.1-1 asdApplicationInfoName: Hello World Python Application asdInfoDescription: Hello World Python application for App Onboarding deploymentItems: deploymentItemId: 1 - artifactId: OtherDefinitions/ASD/eric-oss-hello-world-python-app-VERSION.tgz \ No newline at end of file + artifactId: OtherDefinitions/ASD/eric-oss-hello-world-python-app-1.0.1-1.tgz \ No newline at end of file diff --git a/csar/OtherDefinitions/SecurityManagement/security-metadata.json b/csar/OtherDefinitions/SecurityManagement/security-metadata.json new file mode 100644 index 0000000..e3f8d86 --- /dev/null +++ b/csar/OtherDefinitions/SecurityManagement/security-metadata.json @@ -0,0 +1,3 @@ +{ + "authenticatorType": "client-x509" +} \ No newline at end of file diff --git a/eric-oss-hello-world-python-app/config.py b/eric-oss-hello-world-python-app/config.py index e9bb85b..f075aff 100644 --- a/eric-oss-hello-world-python-app/config.py +++ b/eric-oss-hello-world-python-app/config.py @@ -15,6 +15,9 @@ def get_config(): app_key = get_os_env_string("APP_KEY", "") app_cert = get_os_env_string("APP_CERT", "") app_cert_file_path = get_os_env_string("APP_CERT_FILE_PATH", "") + authentication_type = get_os_env_string("AUTHENTICATION_TYPE", "") + client_creds_file_path = get_os_env_string("CLIENT_CREDS_FILE_PATH", "") + client_id_file_name = get_os_env_string("CLIENT_ID_FILE_NAME", "") config = { "iam_client_id": iam_client_id, @@ -26,7 +29,10 @@ def get_config(): "log_endpoint": log_endpoint, "app_key": app_key, "app_cert": app_cert, - "app_cert_file_path": app_cert_file_path + "app_cert_file_path": app_cert_file_path, + "authentication_type": authentication_type, + "client_creds_file_path": client_creds_file_path, + "client_id_file_name": client_id_file_name } return config diff --git a/eric-oss-hello-world-python-app/login.py b/eric-oss-hello-world-python-app/login.py index 4112a04..ed97dd2 100644 --- a/eric-oss-hello-world-python-app/login.py +++ b/eric-oss-hello-world-python-app/login.py @@ -7,6 +7,8 @@ from urllib.parse import urljoin import json import requests +import logging +import re from config import get_config class LoginError(Exception): @@ -23,15 +25,16 @@ def login(): headers = { "Content-Type": "application/x-www-form-urlencoded" } - form_data = { - "grant_type": "client_credentials", - "client_id": config.get("iam_client_id"), - "client_secret": config.get("iam_client_secret"), - "tenant_id": "master" - } try: - resp = tls_login(login_url, form_data, headers) - except LoginError: + resp = tls_login(login_url, headers) + except LoginError as e: + error_message = str(e) + match = re.search(r'\((\d{3})\)', error_message) + if match: + status_code = int(match.group(1)) + print(f"Login failed with status code: {status_code}") + else: + print(f"Login failed: {error_message}") return None, 0 resp = json.loads(resp.decode('utf-8')) @@ -39,16 +42,67 @@ def login(): time_until_expiry -= 10 # add a buffer to ensure our session doesn't expire mid-request return token, time_until_expiry -def tls_login(url, form_data, headers): +def tls_login(url, headers): ''' This function sends an HTTP POST request with TLS for the login operation ''' config = get_config() - cert = os.path.join("/", config.get("ca_cert_file_path"), config.get("ca_cert_file_name")) + ca_cert = os.path.join("/", config.get("ca_cert_file_path"), config.get("ca_cert_file_name")) + app_cert = os.path.join("/", config.get("app_cert_file_path"), config.get("app_cert")) + app_key = os.path.join("/", config.get("app_cert_file_path"), config.get("app_key")) + authentication_type = config.get("authentication_type").lower() try: - response = requests.post(url, data=form_data, headers = headers, timeout=5, verify=cert) + + print("Headers:", headers) + if authentication_type == "client-x509": + print("client_creds_file_path:", config.get("client_creds_file_path")) + print("client_id_file_name:", config.get("client_id_file_name")) + client_id_file_path = os.path.join("/", config.get("client_creds_file_path"), config.get("client_id_file_name")) + print("Hello 1:", client_id_file_path) + client_id = read_file(client_id_file_path) + print("Hello 2:", client_id) + form_data = { + "grant_type": "client_credentials", + "client_id": client_id, + "tenant_id": "master" + } + print("Form data1:", form_data) + print(f"Login1") + response = requests.post( + url, + data=form_data, + headers=headers, + timeout=5, + verify=ca_cert, + cert=(app_cert, app_key) + ) + elif authentication_type == "client-secret": + form_data = { + "grant_type": "client_credentials", + "client_id": config.get("iam_client_id"), + "client_secret": config.get("iam_client_secret"), + "tenant_id": "master" + } + print("Form data2:", form_data) + print(f"Login2") + response = requests.post( + url, + data=form_data, + headers=headers, + timeout=5, + verify=ca_cert + ) if response.status_code != 200: + print(f"Log POST to https://{url} responded with {response.status_code}: {response.text}") + print(f"Login3") + print("Response status code:", response.status_code) + print("Response content:", response.text) raise LoginError(f"Login failed ({response.status_code})") except Exception as exception: + print(f"Login4") raise LoginError(f"Login failed ({exception})") from exception return response.content + +def read_file(path): + with open(path, "r") as f: + return f.read().strip() diff --git a/eric-oss-hello-world-python-app/mtls_logging.py b/eric-oss-hello-world-python-app/mtls_logging.py index dc91c70..cc143f6 100644 --- a/eric-oss-hello-world-python-app/mtls_logging.py +++ b/eric-oss-hello-world-python-app/mtls_logging.py @@ -97,8 +97,18 @@ def log(self, message, severity): ca_cert = os.path.join("/", self.config.get("ca_cert_file_path"), self.config.get("ca_cert_file_name")) app_cert = os.path.join("/", self.config.get("app_cert_file_path"), self.config.get("app_cert")) app_key = os.path.join("/", self.config.get("app_cert_file_path"), self.config.get("app_key")) - requests.post(f"https://{log_url}", json=json_data, timeout=5, - headers = headers, verify=ca_cert, cert=(app_cert, app_key)) + response = requests.post( + f"https://{log_url}", + json=json_data, + timeout=5, + headers=headers, + verify=ca_cert, + cert=(app_cert, app_key) + ) + + # Add this log after the request + print(f"Log POST to https://{log_url} responded with {response.status_code}: {response.text}") + except (requests.exceptions.InvalidURL, requests.exceptions.MissingSchema) as exception: # logs to console if failed to log to log transformer - self.logger.error("Request failed for mTLS logging: %s", exception) + self.logger.error("Request failed for mTLS logging: %s", exception) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index f37ed8d..50df0a4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ flask==3.0.1 -requests==2.32.0 +requests==2.32.4 prometheus-client==0.20.0 \ No newline at end of file