From 9ca776c7ea559658991abc192e21f756621fd571 Mon Sep 17 00:00:00 2001 From: D056267 Date: Wed, 22 Nov 2023 16:55:09 +0100 Subject: [PATCH] versions, kyma cli, btp operator, ... --- .../k8s/elk-stack/kibana-expose.yaml | 2 +- .../day2/rest/service/UserRestControler.java | 2 + code/day2-operations/source/day2-ui/README.md | 2 +- .../deployment/docker/Dockerfile-approuter | 2 +- .../deployment/docker/Dockerfile-bp-service | 4 +- .../deployment/docker/Dockerfile-broker | 2 +- .../docker/Dockerfile-business-partner-mock | 2 +- .../deployment/docker/Dockerfile-db-service | 8 +- .../deployment/docker/Dockerfile-ef-service | 4 +- .../docker/Dockerfile-email-service | 2 +- .../deployment/docker/Dockerfile-ui | 4 +- .../deployment/k8s/bp-service.yaml | 2 +- code/easyfranchise/deployment/k8s/broker.yaml | 2 +- .../deployment/k8s/business-partner-mock.yaml | 2 +- code/easyfranchise/source/README.md | 14 ++ .../source/approuter/approuter-start.js | 6 +- .../source/approuter/package.json | 10 +- code/easyfranchise/source/approuter/readme.md | 3 + code/easyfranchise/source/backend/README.md | 3 + .../easyfranchise/bpservice/BPService.java | 5 +- code/easyfranchise/source/backend/pom.xml | 8 +- .../communication/Connection.java | 3 - code/easyfranchise/source/broker/readme.md | 3 + .../business-partner-mock-server/readme.md | 3 + .../business-partner-mock-server/server.js | 2 +- .../source/email-service/README.md | 3 + code/easyfranchise/source/ui/README.md | 3 + .../easyfranchise/source/ui/public/index.html | 2 +- .../ui/src/assets/logo-bike-sharing.png | Bin 0 -> 18502 bytes .../ui/src/assets/logo-city-scooter.png | Bin 0 -> 24911 bytes .../ui/src/assets/logo-easy-franchise.png | Bin 0 -> 7515 bytes .../source/ui/src/assets/logo-placeholder.png | Bin 0 -> 7938 bytes code/easyfranchise/source/ui/vue.config.js | 2 +- .../btp-setup-automator/btpsa-deployment.sh | 143 +++++++++++++----- code/setup/day2-operations-deployment.sh | 4 +- code/setup/easyfranchise-deployment.sh | 63 +++++++- 36 files changed, 239 insertions(+), 81 deletions(-) create mode 100644 code/easyfranchise/source/README.md create mode 100644 code/easyfranchise/source/approuter/readme.md create mode 100644 code/easyfranchise/source/backend/README.md create mode 100644 code/easyfranchise/source/broker/readme.md create mode 100644 code/easyfranchise/source/business-partner-mock-server/readme.md create mode 100644 code/easyfranchise/source/email-service/README.md create mode 100644 code/easyfranchise/source/ui/README.md create mode 100644 code/easyfranchise/source/ui/src/assets/logo-bike-sharing.png create mode 100644 code/easyfranchise/source/ui/src/assets/logo-city-scooter.png create mode 100644 code/easyfranchise/source/ui/src/assets/logo-easy-franchise.png create mode 100644 code/easyfranchise/source/ui/src/assets/logo-placeholder.png mode change 100755 => 100644 code/setup/easyfranchise-deployment.sh diff --git a/code/day2-operations/deployment/k8s/elk-stack/kibana-expose.yaml b/code/day2-operations/deployment/k8s/elk-stack/kibana-expose.yaml index 6efca5e..3b72aa7 100644 --- a/code/day2-operations/deployment/k8s/elk-stack/kibana-expose.yaml +++ b/code/day2-operations/deployment/k8s/elk-stack/kibana-expose.yaml @@ -24,7 +24,7 @@ metadata: name: kibana-expose spec: gateway: kyma-gateway.kyma-system.svc.cluster.local - host: kibana + host: kibana service: name: ef-kibana-kb-http port: 5601 diff --git a/code/day2-operations/source/day2-service/src/main/java/dev/kyma/samples/easyfranchise/day2/rest/service/UserRestControler.java b/code/day2-operations/source/day2-service/src/main/java/dev/kyma/samples/easyfranchise/day2/rest/service/UserRestControler.java index ae3eaa1..172af78 100644 --- a/code/day2-operations/source/day2-service/src/main/java/dev/kyma/samples/easyfranchise/day2/rest/service/UserRestControler.java +++ b/code/day2-operations/source/day2-service/src/main/java/dev/kyma/samples/easyfranchise/day2/rest/service/UserRestControler.java @@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -31,6 +32,7 @@ public class UserRestControler { @Autowired private UserLoginInfoService userLoginInfoService; + @CrossOrigin //we have to allow CrossOrigin for local testing. Don't allow CrossOrigin for production running applications!! @GetMapping("/user/metric") public List getUserMetric(@RequestParam @NotNull int year, @RequestParam @NotNull @Min(1) @Max(12) Integer month) { diff --git a/code/day2-operations/source/day2-ui/README.md b/code/day2-operations/source/day2-ui/README.md index 964ddbf..13d74c1 100644 --- a/code/day2-operations/source/day2-ui/README.md +++ b/code/day2-operations/source/day2-ui/README.md @@ -1,4 +1,4 @@ -# Metering Dashboard UI +# Day2 UI ## How to Run the Service diff --git a/code/easyfranchise/deployment/docker/Dockerfile-approuter b/code/easyfranchise/deployment/docker/Dockerfile-approuter index a1bc6e9..1bf3852 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-approuter +++ b/code/easyfranchise/deployment/docker/Dockerfile-approuter @@ -1,4 +1,4 @@ -FROM node:14 +FROM --platform=linux/amd64 node:20 WORKDIR /app diff --git a/code/easyfranchise/deployment/docker/Dockerfile-bp-service b/code/easyfranchise/deployment/docker/Dockerfile-bp-service index 0dabbbe..7304c27 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-bp-service +++ b/code/easyfranchise/deployment/docker/Dockerfile-bp-service @@ -1,4 +1,4 @@ -FROM maven:3-openjdk-17-slim as BUILDER +FROM --platform=linux/amd64 maven:3-openjdk-17-slim as BUILDER WORKDIR /opt/app COPY code/easyfranchise/source/backend/bp-service/pom.xml bp-service/pom.xml COPY code/easyfranchise/source/backend/db-service/pom.xml db-service/pom.xml @@ -12,7 +12,7 @@ COPY code/easyfranchise/source/backend/db-service/src /opt/app/db-service/src RUN mvn clean install -DskipTests=true # At this point, BUILDER stage should have your .jar or whatever in some path -FROM sapmachine:16 as production-stage +FROM --platform=linux/amd64 sapmachine:latest as production-stage LABEL maintainer="alexander.rieder@sap.com" WORKDIR /opt/app COPY --from=BUILDER /opt/app/bp-service/target/bp-service.jar /opt/app/bp-service.jar diff --git a/code/easyfranchise/deployment/docker/Dockerfile-broker b/code/easyfranchise/deployment/docker/Dockerfile-broker index a6c6a21..8157d24 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-broker +++ b/code/easyfranchise/deployment/docker/Dockerfile-broker @@ -1,4 +1,4 @@ -FROM node:14 +FROM --platform=linux/amd64 node:14 EXPOSE 3002 diff --git a/code/easyfranchise/deployment/docker/Dockerfile-business-partner-mock b/code/easyfranchise/deployment/docker/Dockerfile-business-partner-mock index 75e0a57..015fd9a 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-business-partner-mock +++ b/code/easyfranchise/deployment/docker/Dockerfile-business-partner-mock @@ -1,4 +1,4 @@ -FROM node:latest +FROM --platform=linux/amd64 node:latest EXPOSE 8081 diff --git a/code/easyfranchise/deployment/docker/Dockerfile-db-service b/code/easyfranchise/deployment/docker/Dockerfile-db-service index 247dc39..7ea5a99 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-db-service +++ b/code/easyfranchise/deployment/docker/Dockerfile-db-service @@ -1,4 +1,4 @@ -FROM maven:3-openjdk-17-slim as BUILDER +FROM --platform=linux/amd64 maven:3-openjdk-17-slim as BUILDER WORKDIR /opt/app COPY code/easyfranchise/source/backend/bp-service/pom.xml bp-service/pom.xml COPY code/easyfranchise/source/backend/db-service/pom.xml db-service/pom.xml @@ -11,13 +11,11 @@ COPY code/easyfranchise/source/backend/ef-service/src /opt/app/ef-service/src COPY code/easyfranchise/source/backend/db-service/src /opt/app/db-service/src RUN mvn clean install -DskipTests=true -FROM sapmachine:16 as production-stage +FROM --platform=linux/amd64 sapmachine:latest as production-stage LABEL maintainer="alexander.rieder@sap.com" WORKDIR /opt/app COPY --from=BUILDER /opt/app/db-service/target/db-service.jar /opt/app/db-service.jar COPY --from=BUILDER /opt/app/db-service/target/dependency/* /opt/app/ ENV JAVA_OPTS="" EXPOSE 8080 -EXPOSE 9999 - -CMD ["java", "-Dcom.sun.management.jmxremote.port=9999", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.ssl=false", "-cp", "/opt/app/*", "dev.kyma.samples.easyfranchise.ServerApp", "8080"] +CMD ["java", "-cp", "/opt/app/*", "dev.kyma.samples.easyfranchise.ServerApp", "8080"] \ No newline at end of file diff --git a/code/easyfranchise/deployment/docker/Dockerfile-ef-service b/code/easyfranchise/deployment/docker/Dockerfile-ef-service index bd91151..ab88490 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-ef-service +++ b/code/easyfranchise/deployment/docker/Dockerfile-ef-service @@ -1,4 +1,4 @@ -FROM maven:3-openjdk-17-slim as BUILDER +FROM --platform=linux/amd64 maven:3-openjdk-17-slim as BUILDER WORKDIR /opt/app COPY code/easyfranchise/source/backend/bp-service/pom.xml bp-service/pom.xml COPY code/easyfranchise/source/backend/db-service/pom.xml db-service/pom.xml @@ -11,7 +11,7 @@ COPY code/easyfranchise/source/backend/ef-service/src /opt/app/ef-service/src COPY code/easyfranchise/source/backend/db-service/src /opt/app/db-service/src RUN mvn clean install -DskipTests=true -FROM sapmachine:16 as production-stage +FROM --platform=linux/amd64 sapmachine:latest as production-stage LABEL maintainer="alexander.rieder@sap.com" WORKDIR /opt/app COPY --from=BUILDER /opt/app/ef-service/target/ef-service.jar /opt/app/ef-service.jar diff --git a/code/easyfranchise/deployment/docker/Dockerfile-email-service b/code/easyfranchise/deployment/docker/Dockerfile-email-service index d97d75f..f506d5d 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-email-service +++ b/code/easyfranchise/deployment/docker/Dockerfile-email-service @@ -1,4 +1,4 @@ -FROM node:latest +FROM --platform=linux/amd64 node:latest EXPOSE 3002 diff --git a/code/easyfranchise/deployment/docker/Dockerfile-ui b/code/easyfranchise/deployment/docker/Dockerfile-ui index e0742aa..923dab0 100644 --- a/code/easyfranchise/deployment/docker/Dockerfile-ui +++ b/code/easyfranchise/deployment/docker/Dockerfile-ui @@ -1,5 +1,5 @@ # build stage -FROM node:14-alpine as build-stage +FROM --platform=linux/amd64 node:14-alpine as build-stage WORKDIR /app COPY code/easyfranchise/source/ui/package*.json ./ RUN npm install @@ -7,7 +7,7 @@ COPY code/easyfranchise/source/ui/. . RUN npm run build # production stage -FROM nginx:stable-alpine as production-stage +FROM --platform=linux/amd64 nginx:stable-alpine as production-stage COPY --from=build-stage /app/resources /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/code/easyfranchise/deployment/k8s/bp-service.yaml b/code/easyfranchise/deployment/k8s/bp-service.yaml index e4b1853..e31ea41 100644 --- a/code/easyfranchise/deployment/k8s/bp-service.yaml +++ b/code/easyfranchise/deployment/k8s/bp-service.yaml @@ -21,7 +21,7 @@ spec: imagePullSecrets: - name: registry-secret containers: - - image: + - image: # use your own image name: bp-service imagePullPolicy: Always resources: {} diff --git a/code/easyfranchise/deployment/k8s/broker.yaml b/code/easyfranchise/deployment/k8s/broker.yaml index 9f53dd8..7313f3b 100644 --- a/code/easyfranchise/deployment/k8s/broker.yaml +++ b/code/easyfranchise/deployment/k8s/broker.yaml @@ -18,7 +18,7 @@ spec: imagePullSecrets: - name: registry-secret # replace with your own registry secret containers: - - image: #cp-enablement.docker.repositories.sap.ondemand.com/easyfranchise/broker # use your own image + - image: # use your own image name: broker imagePullPolicy: Always env: diff --git a/code/easyfranchise/deployment/k8s/business-partner-mock.yaml b/code/easyfranchise/deployment/k8s/business-partner-mock.yaml index 4b60e57..22936e1 100644 --- a/code/easyfranchise/deployment/k8s/business-partner-mock.yaml +++ b/code/easyfranchise/deployment/k8s/business-partner-mock.yaml @@ -18,7 +18,7 @@ spec: imagePullSecrets: - name: registry-secret # replace with your own registry secret containers: - - image: # e.g. cp-enablement.docker.repositories.sap.ondemand.com/com.sap.easyfranchise/s4hanamock: + - image: # use your own image name: business-partner-mock imagePullPolicy: Always ports: diff --git a/code/easyfranchise/source/README.md b/code/easyfranchise/source/README.md new file mode 100644 index 0000000..bd88826 --- /dev/null +++ b/code/easyfranchise/source/README.md @@ -0,0 +1,14 @@ +# Easy Franchise Components + +This section contains all components that are needed to run the Easy Franchise application. + +- [backend](backend): JAVA-based backend services that manage database, SAP S/4HANA Cloud system and the logic of the application + - [Database Service](backend/db-service) + - [Business Partner Service](backend/bp-service) + - [Easy Franchise Service](backend/ef-service) +- [email-service](email-service): node.js-based service that sends notifications +- [ui](ui): vue.js-based user interface +- [Approuter](approuter): node.js-based application router for authorization and authentication +- [broker](broker): service that onboards/offboards new customers of the multitenant application +- [business-partner-mock-server](business-partner-mock-server): service to simulate an SAP S/4HANA Cloud system if not available + diff --git a/code/easyfranchise/source/approuter/approuter-start.js b/code/easyfranchise/source/approuter/approuter-start.js index c5b5b74..4eee10e 100644 --- a/code/easyfranchise/source/approuter/approuter-start.js +++ b/code/easyfranchise/source/approuter/approuter-start.js @@ -1,7 +1,7 @@ -const jwt_decode = require('jwt-decode'); const approuter = require('@sap/approuter'); const xssec = require('@sap/xssec'); const xsenv = require('@sap/xsenv'); +const { jwtDecode } = require('jwt-decode'); var ar = approuter(); ar.beforeRequestHandler.use('/backend', function (req, res, next) { @@ -10,7 +10,7 @@ ar.beforeRequestHandler.use('/backend', function (req, res, next) { res.statusCode = 403; res.end("Missing JWT Token"); } else { - const decodedToken = jwt_decode(token); + const decodedToken = jwtDecode(token); const tenant = decodedToken && decodedToken.zid; req.headers['x-tenant-id'] = tenant; next(); @@ -24,7 +24,7 @@ ar.beforeRequestHandler.use('/userInfo', function (req, res, next) { res.end("Missing JWT Token"); } else { res.statusCode = 200; - let decodedToken = jwt_decode(token); + let decodedToken = jwtDecode(token); res.end(JSON.stringify({ userid: decodedToken.user_name, email: decodedToken.email, diff --git a/code/easyfranchise/source/approuter/package.json b/code/easyfranchise/source/approuter/package.json index d3e2d2e..51e9053 100644 --- a/code/easyfranchise/source/approuter/package.json +++ b/code/easyfranchise/source/approuter/package.json @@ -7,13 +7,13 @@ "start": "node approuter-start.js" }, "dependencies": { - "@sap/approuter": "10.8.2", - "@sap/xsenv": "^3.1.1", - "@sap/xssec": "^3.2.8", - "jwt-decode": "^3.1.2" + "@sap/approuter": "14.3.4", + "@sap/xsenv": "^4.0.0", + "@sap/xssec": "^3.4.0", + "jwt-decode": "^4.0.0" }, "devDependencies": {}, "engines": { - "node": "14.x.x" + "node": "20.x.x" } } diff --git a/code/easyfranchise/source/approuter/readme.md b/code/easyfranchise/source/approuter/readme.md new file mode 100644 index 0000000..038ea28 --- /dev/null +++ b/code/easyfranchise/source/approuter/readme.md @@ -0,0 +1,3 @@ +# Easy Franchise Approuter + +Please refer to [documentation](/documentation/explore/approuter/README.md) for more details. diff --git a/code/easyfranchise/source/backend/README.md b/code/easyfranchise/source/backend/README.md new file mode 100644 index 0000000..ebe4438 --- /dev/null +++ b/code/easyfranchise/source/backend/README.md @@ -0,0 +1,3 @@ +# Easy Franchise Backend + +Please refer to [documentation](/documentation/explore/README.md) for more details. diff --git a/code/easyfranchise/source/backend/bp-service/src/main/java/dev/kyma/samples/easyfranchise/bpservice/BPService.java b/code/easyfranchise/source/backend/bp-service/src/main/java/dev/kyma/samples/easyfranchise/bpservice/BPService.java index c915ef1..9440f4d 100644 --- a/code/easyfranchise/source/backend/bp-service/src/main/java/dev/kyma/samples/easyfranchise/bpservice/BPService.java +++ b/code/easyfranchise/source/backend/bp-service/src/main/java/dev/kyma/samples/easyfranchise/bpservice/BPService.java @@ -1,8 +1,5 @@ package dev.kyma.samples.easyfranchise.bpservice; -import java.net.InetSocketAddress; -import java.net.Proxy; - import org.apache.http.HttpStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,10 +16,10 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriInfo; -import jakarta.ws.rs.core.HttpHeaders; /** * Rest service for S/4HANA connectivity * diff --git a/code/easyfranchise/source/backend/pom.xml b/code/easyfranchise/source/backend/pom.xml index d297969..b4f38d4 100644 --- a/code/easyfranchise/source/backend/pom.xml +++ b/code/easyfranchise/source/backend/pom.xml @@ -7,9 +7,9 @@ 1.0-SNAPSHOT pom - 11.0.3 - 3.0.1 - 2.0.0-alpha1 + 11.0.18 + 3.1.3 + 2.0.9 ISO-8859-1 @@ -20,7 +20,7 @@ maven-compiler-plugin 3.8.1 - 15 + 17 diff --git a/code/easyfranchise/source/backend/shared-code/src/main/java/dev/kyma/samples/easyfranchise/communication/Connection.java b/code/easyfranchise/source/backend/shared-code/src/main/java/dev/kyma/samples/easyfranchise/communication/Connection.java index 74f5052..15371c7 100644 --- a/code/easyfranchise/source/backend/shared-code/src/main/java/dev/kyma/samples/easyfranchise/communication/Connection.java +++ b/code/easyfranchise/source/backend/shared-code/src/main/java/dev/kyma/samples/easyfranchise/communication/Connection.java @@ -4,9 +4,6 @@ import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Proxy; import java.net.SocketTimeoutException; import java.net.URL; import java.nio.charset.StandardCharsets; diff --git a/code/easyfranchise/source/broker/readme.md b/code/easyfranchise/source/broker/readme.md new file mode 100644 index 0000000..51eca26 --- /dev/null +++ b/code/easyfranchise/source/broker/readme.md @@ -0,0 +1,3 @@ +# Broker + +Please refer to [documentation](/documentation/explore/broker/README.md) for more details. diff --git a/code/easyfranchise/source/business-partner-mock-server/readme.md b/code/easyfranchise/source/business-partner-mock-server/readme.md new file mode 100644 index 0000000..356df18 --- /dev/null +++ b/code/easyfranchise/source/business-partner-mock-server/readme.md @@ -0,0 +1,3 @@ +# SAP Business Partner Mock Server + +Please refer to [documentation](/documentation/appendix/business-partner-mock) for more details. diff --git a/code/easyfranchise/source/business-partner-mock-server/server.js b/code/easyfranchise/source/business-partner-mock-server/server.js index 0975c63..ac92f99 100644 --- a/code/easyfranchise/source/business-partner-mock-server/server.js +++ b/code/easyfranchise/source/business-partner-mock-server/server.js @@ -17,7 +17,7 @@ app.get('/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner', function (r }); }) -var server = app.listen(8081, '127.0.0.1', function () { +var server = app.listen(8081, '0.0.0.0', function () { var host = server.address().address; if (host === '::') { host = 'localhost'; diff --git a/code/easyfranchise/source/email-service/README.md b/code/easyfranchise/source/email-service/README.md new file mode 100644 index 0000000..c777129 --- /dev/null +++ b/code/easyfranchise/source/email-service/README.md @@ -0,0 +1,3 @@ +# Email Service + +Please refer to [documentation](/documentation/explore/email-service/README.md) for more details. diff --git a/code/easyfranchise/source/ui/README.md b/code/easyfranchise/source/ui/README.md new file mode 100644 index 0000000..407c6d2 --- /dev/null +++ b/code/easyfranchise/source/ui/README.md @@ -0,0 +1,3 @@ +# Easy Franchise Backend + +Please refer to [documentation](/documentation/explore/ui/README.md) for more details. diff --git a/code/easyfranchise/source/ui/public/index.html b/code/easyfranchise/source/ui/public/index.html index cb1d076..4cae005 100644 --- a/code/easyfranchise/source/ui/public/index.html +++ b/code/easyfranchise/source/ui/public/index.html @@ -4,7 +4,7 @@ - + <%= htmlWebpackPlugin.options.title %> diff --git a/code/easyfranchise/source/ui/src/assets/logo-bike-sharing.png b/code/easyfranchise/source/ui/src/assets/logo-bike-sharing.png new file mode 100644 index 0000000000000000000000000000000000000000..412b918f30f6138bf240b0ec9c96d985bd4e2dea GIT binary patch literal 18502 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 literal 0 HcmV?d00001 diff --git a/code/easyfranchise/source/ui/src/assets/logo-placeholder.png b/code/easyfranchise/source/ui/src/assets/logo-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..aac3858e96d95c89bb1492ba32bb6114bdc7ba03 GIT binary patch literal 7938 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 V90TvWy7ezLTKA+*v6jPy{{qeB%Z~s6 literal 0 HcmV?d00001 diff --git a/code/easyfranchise/source/ui/vue.config.js b/code/easyfranchise/source/ui/vue.config.js index 5e8bf56..a70a685 100644 --- a/code/easyfranchise/source/ui/vue.config.js +++ b/code/easyfranchise/source/ui/vue.config.js @@ -2,6 +2,6 @@ module.exports = { devServer: { host: '0.0.0.0', hot: true, - allowedHosts: "all", + allowedHosts: ['all'], }, }; \ No newline at end of file diff --git a/code/setup/btp-setup-automator/btpsa-deployment.sh b/code/setup/btp-setup-automator/btpsa-deployment.sh index 7cb707a..ff58c23 100644 --- a/code/setup/btp-setup-automator/btpsa-deployment.sh +++ b/code/setup/btp-setup-automator/btpsa-deployment.sh @@ -7,6 +7,21 @@ log() { echo -e "${yellow}$*${no_color}" } +for i in "$@"; do + case $i in + -v=*|--variant=*) + VARIANT_NUMBER="${i#*=}" + VARIANT_NUMBER_SELECTED=true + ;; + *) + # unknown option + log "Error: Unknown argument ${i}" + usage + ;; + esac +done + + continue_prompt_bool() { log read -p "$1 (y or yes to accept): " -r varname @@ -80,20 +95,22 @@ echo "########################################################################## echo "" read_automator_config -log "Choose Deployment option, Variant 1 will deploy the application ready for the Mission. Variant 2 contains all the enhancements which will be introduced throughout the mission:" -declare -a arr="(Mission-Start Mission-End)" # must be quoted like this -createmenu "${arr[@]}" -VARIANT_NUMBER="$retval" - -case $VARIANT_NUMBER in - 1) - BTPSA_KYMA_IMAGE_TAG="main" - ;;& - 2) - BTPSA_KYMA_IMAGE_TAG="endresult" - log "Checkout endresult branch" - cd /home/user/tutorial || exit - git checkout endresult +if [ "$VARIANT_SELECTED" = false ]; then + log "Choose Deployment option, Variant 1 will deploy the application ready for the Mission. Variant 2 contains all the enhancements which will be introduced throughout the mission:" + declare -a arr="(Mission-Start Mission-End)" # must be quoted like this + createmenu "${arr[@]}" + VARIANT_NUMBER="$retval" +fi + + case $VARIANT_NUMBER in + 1) + BTPSA_KYMA_IMAGE_TAG="main" + ;;& + 2) + BTPSA_KYMA_IMAGE_TAG="endresult" + log "Checkout endresult branch" + cd /home/user/tutorial || exit + git checkout endresult ;; esac @@ -126,7 +143,63 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then log "####################################################################################################" echo "" - log "Step 2.1 - Create Namepaces" + log "Step 2.1 - Enable BTP Operator" + # Download and Install Kyma CLI + curl -Lo kyma.tar.gz "https://github.com/kyma-project/cli/releases/download/$(curl -s https://api.github.com/repos/kyma-project/cli/releases/latest | grep tag_name | cut -d '"' -f 4)/kyma_Linux_x86_64.tar.gz" \ + && mkdir kyma-release && tar -C kyma-release -zxvf kyma.tar.gz && chmod +x kyma-release/kyma && sudo mv kyma-release/kyma /usr/local/bin \ + && rm -rf kyma-release kyma.tar.gz + + # Wait for Kyma CLI to be ready + KYMA_CLI_READY=0 + MAX_RETRIES=5 + RETRY_INTERVAL=5 + + for ((i=1; i<=MAX_RETRIES; i++)); do + if kyma version; then + KYMA_CLI_READY=1 + break + else + echo "Waiting for Kyma CLI to be ready... retry $i/$MAX_RETRIES" + sleep $RETRY_INTERVAL + fi + done + + if [ $KYMA_CLI_READY -eq 0 ]; then + echo "Kyma CLI is not ready. Exiting..." + exit 1 + else + echo "Kyma CLI is ready." + fi + + # Enable BTP Operator + kyma alpha enable module btp-operator --channel regular --kyma-name default --wait + + + # Wait for BTP Operator to be ready + BTP_OPERATOR_READY=0 + MAX_RETRIES=30 + RETRY_INTERVAL=10 + + for ((i=1; i<=MAX_RETRIES; i++)); do + if kubectl get pods -n kyma-system | grep -q 'btp-operator.*Running'; then + BTP_OPERATOR_READY=1 + break + else + echo "Waiting for BTP Operator to be ready... retry $i/$MAX_RETRIES" + sleep $RETRY_INTERVAL + fi + done + + if [ $BTP_OPERATOR_READY -eq 0 ]; then + echo "BTP Operator is not ready. Exiting..." + exit 1 + else + echo "BTP Operator is ready." + fi + + echo + + log "Step 2.2 - Create Namepaces" kubectl create namespace integration || true kubectl create namespace backend || true kubectl create namespace mock || true @@ -138,74 +211,74 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then kubectl label namespace frontend istio-injection=enabled --overwrite || true echo - log "Step 2.2 - DB Secret: " + log "Step 2.3 - DB Secret: " cat /home/user/tutorial/code/easyfranchise/deployment/k8s/db-secret.yaml | sed "s~~$DB_SQLENDPOINT~g" | sed "s~~$DB_ADMIN~g" | sed "s~~$DB_ADMIN_PASSWORD~g" | kubectl apply -f - || true echo - log "Step 2.3 - Backend Configmap" + log "Step 2.4 - Backend Configmap" kubectl apply -n backend -f /home/user/tutorial/code/easyfranchise/deployment/k8s/backend-configmap.yaml kubectl apply -n integration -f /home/user/tutorial/code/easyfranchise/deployment/k8s/backend-configmap.yaml echo - log "Step 2.4 - BTP Service Deployment" + log "Step 2.5 - BTP Service Deployment" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/btp-services.yaml" | sed "s~~$SUBDOMAIN~g" | sed "s~~$CLUSTER_DOMAIN~g" | kubectl apply -f - echo PROJECT=approuter - log "Step 2.5 - Deploy $PROJECT" + log "Step 2.6 - Deploy $PROJECT" FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_APPROUTER:$BTPSA_KYMA_IMAGE_TAG cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | sed "s~~$SUBDOMAIN~g" | sed "s~~$CLUSTER_DOMAIN~g" | kubectl apply -f - PROJECT=db-service FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_DB_SERVICE:$BTPSA_KYMA_IMAGE_TAG - log "Step 2.6 - Deploy $PROJECT" + log "Step 2.7 - Deploy $PROJECT" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | kubectl apply -f - PROJECT=bp-service FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_BP_SERVICE:$BTPSA_KYMA_IMAGE_TAG - log "Step 2.7 - Deploy $PROJECT" + log "Step 2.8 - Deploy $PROJECT" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | kubectl apply -f - PROJECT=ef-service FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_EF_SERVICE:$BTPSA_KYMA_IMAGE_TAG - log "Step 2.8 - Deploy $PROJECT" + log "Step 2.9 - Deploy $PROJECT" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | kubectl apply -f - PROJECT=broker FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_BROKER:$BTPSA_KYMA_IMAGE_TAG - log "Step 2.9 - Deploy $PROJECT" + log "Step 2.10 - Deploy $PROJECT" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | kubectl apply -f - PROJECT=email-service FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_EMAIL_SERVICE:$BTPSA_KYMA_IMAGE_TAG - log "Step 2.10 - Deploy $PROJECT" + log "Step 2.11 - Deploy $PROJECT" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | kubectl apply -f - PROJECT=ui FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_UI:$BTPSA_KYMA_IMAGE_TAG - log "Step 2.11 - Deploy $PROJECT" + log "Step 2.12 - Deploy $PROJECT" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | kubectl apply -f - PROJECT=business-partner-mock FULL_NAME=$BTPSA_KYMA_IMAGE_NAME_BUSINESS_PARTNER_MOCK:$BTPSA_KYMA_IMAGE_TAG - log "Step 2.12 - Deploy $PROJECT" + log "Step 2.13 - Deploy $PROJECT" cat "/home/user/tutorial/code/easyfranchise/deployment/k8s/$PROJECT.yaml" | sed "s~~$FULL_NAME~g" | kubectl apply -f - -if [ "$BTPSA_KYMA_IMAGE_TAG" = "endresult" ]; then - kubectl create namespace day2-operations || true - kubectl label namespace day2-operations istio-injection=enabled --overwrite || true - - PROJECT=day2-approuter - log "Step 2.13 - Deploy $PROJECT" - helm upgrade "$PROJECT" "/home/user/tutorial/code/day2-operations/deployment/helmCharts/day2-approuter-chart" --install --namespace "day2-operations" --set clusterdomain="$CLUSTER_DOMAIN" --set image.repository="$BTPSA_KYMA_IMAGE_NAME_DAY2_APPROUTER" --set image.tag="$BTPSA_KYMA_IMAGE_TAG" --wait --timeout 90s --atomic + if [ "$BTPSA_KYMA_IMAGE_TAG" = "endresult" ]; then + kubectl create namespace day2-operations || true + kubectl label namespace day2-operations istio-injection=enabled --overwrite || true + + PROJECT=day2-approuter + log "Step 2.14 - Deploy $PROJECT" + helm upgrade "$PROJECT" "/home/user/tutorial/code/day2-operations/deployment/helmCharts/day2-approuter-chart" --install --namespace "day2-operations" --set clusterdomain="$CLUSTER_DOMAIN" --set image.repository="$BTPSA_KYMA_IMAGE_NAME_DAY2_APPROUTER" --set image.tag="$BTPSA_KYMA_IMAGE_TAG" --wait --timeout 90s --atomic PROJECT=day2-ui - log "Step 2.14 - Deploy $PROJECT" + log "Step 2.15 - Deploy $PROJECT" helm upgrade "$PROJECT" "/home/user/tutorial/code/day2-operations/deployment/helmCharts/day2-ui-chart" --install --namespace "day2-operations" --set image.repository="$BTPSA_KYMA_IMAGE_NAME_DAY2_UI" --set image.tag="$BTPSA_KYMA_IMAGE_TAG" --wait --timeout 90s --atomic PROJECT=day2-service - log "Step 2.15 - Deploy $PROJECT" + log "Step 2.16 - Deploy $PROJECT" helm upgrade "$PROJECT" "/home/user/tutorial/code/day2-operations/deployment/helmCharts/day2-service-chart" --install --namespace "day2-operations" --set db.sqlendpoint="$DB_SQLENDPOINT" --set db.admin="$DB_ADMIN" --set db.password="$DB_ADMIN_PASSWORD" --set image.repository="$BTPSA_KYMA_IMAGE_NAME_DAY2_SERVICE" --set image.tag="$BTPSA_KYMA_IMAGE_TAG" --wait --timeout 90s --atomic fi fi diff --git a/code/setup/day2-operations-deployment.sh b/code/setup/day2-operations-deployment.sh index 8e08138..69e07c7 100755 --- a/code/setup/day2-operations-deployment.sh +++ b/code/setup/day2-operations-deployment.sh @@ -401,9 +401,9 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then kubectl create namespace "logging" || true kubectl create namespace "otel-system" || true - kubectl label namespace "$NAMESPACE" istio-injection=enabled --overwrite || true + kubectl label namespace "$NAMESPACE" istio-injection=enabled --overwrite || true kubectl label namespace "logging" istio-injection=enabled --overwrite || true - kubectl label namespace "otel-system" istio-injection=enabled --overwrite || true + kubectl label namespace "otel-system" istio-injection=enabled --overwrite || true else log "Skipped for Dry Run" fi diff --git a/code/setup/easyfranchise-deployment.sh b/code/setup/easyfranchise-deployment.sh old mode 100755 new mode 100644 index aefd5c8..0a8bbfb --- a/code/setup/easyfranchise-deployment.sh +++ b/code/setup/easyfranchise-deployment.sh @@ -319,7 +319,66 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then log "=================================================================================================" echo "" - log "Step 3.1 - Create Namepaces" + log "Step 3.1 - Enable BTP Operator" + if [ "$DRY_RUN" = false ]; then + # Download and Install Kyma CLI + curl -Lo kyma.tar.gz "https://github.com/kyma-project/cli/releases/download/$(curl -s https://api.github.com/repos/kyma-project/cli/releases/latest | grep tag_name | cut -d '"' -f 4)/kyma_Linux_x86_64.tar.gz" \ + && mkdir kyma-release && tar -C kyma-release -zxvf kyma.tar.gz && chmod +x kyma-release/kyma && sudo mv kyma-release/kyma /usr/local/bin \ + && rm -rf kyma-release kyma.tar.gz + + # Wait for Kyma CLI to be ready + KYMA_CLI_READY=0 + MAX_RETRIES=5 + RETRY_INTERVAL=5 + + for ((i=1; i<=MAX_RETRIES; i++)); do + if kyma version; then + KYMA_CLI_READY=1 + break + else + echo "Waiting for Kyma CLI to be ready... retry $i/$MAX_RETRIES" + sleep $RETRY_INTERVAL + fi + done + + if [ $KYMA_CLI_READY -eq 0 ]; then + echo "Kyma CLI is not ready. Exiting..." + exit 1 + else + echo "Kyma CLI is ready." + fi + + # Enable BTP Operator + kyma alpha enable module btp-operator --channel regular --kyma-name default --wait + + + # Wait for BTP Operator to be ready + BTP_OPERATOR_READY=0 + MAX_RETRIES=30 + RETRY_INTERVAL=10 + + for ((i=1; i<=MAX_RETRIES; i++)); do + if kubectl get pods -n kyma-system | grep -q 'btp-operator.*Running'; then + BTP_OPERATOR_READY=1 + break + else + echo "Waiting for BTP Operator to be ready... retry $i/$MAX_RETRIES" + sleep $RETRY_INTERVAL + fi + done + + if [ $BTP_OPERATOR_READY -eq 0 ]; then + echo "BTP Operator is not ready. Exiting..." + exit 1 + else + echo "BTP Operator is ready." + fi + else + log "Skipped for Dry Run" + fi + + echo + log "Step 3.2 - Create Namepaces" if [ "$DRY_RUN" = false ]; then kubectl create namespace integration || true kubectl create namespace backend || true @@ -335,7 +394,7 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then fi echo - log "Step 3.2 - Create Secrets, Configmap and depended Services" + log "Step 3.3 - Create Secrets, Configmap and depended Services" echo log "DB Secret: " if [ "$DRY_RUN" = true ]; then