diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..8cbb2304 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,69 @@ +version: 2.1 + +orbs: + kubernetes: circleci/kubernetes@1.0.0 + helm: circleci/helm@2.0.1 + +jobs: + + build-push-docker-image: + docker: + - image: cimg/base:stable + environment: + TAG: << pipeline.git.tag >> + steps: + - checkout + - add_ssh_keys: + fingerprints: + - "39:25:57:64:62:43:1f:98:b1:5e:75:53:87:d8:e7:71" + - run: cp $HOME/.ssh/id_rsa_3925576462431f98b15e755387d8e771 id_rsa + - setup_remote_docker: + version: 20.10.12 + docker_layer_caching: true + - run: docker login rg.fr-par.scw.cloud/lecoffre -u nologin -p $SCW_SECRET_KEY + - run: docker build --tag rg.fr-par.scw.cloud/lecoffre/front:$TAG . + - run: docker push rg.fr-par.scw.cloud/lecoffre/front:$TAG + + + deploy-docker-image: + docker: + - image: cimg/base:stable + environment: + TAG: << pipeline.git.tag >> + steps: + - checkout + - kubernetes/install-kubeconfig: + kubeconfig: KUBECONFIG_DATA + - helm/install-helm-client + - run: + name: Deploy + command: > + helm upgrade + lecoffre-front devops/ -i -f devops/values.yaml + -n lecoffre + --create-namespace + --set lecoffreFront.image.repository='rg.fr-par.scw.cloud/lecoffre/front' + --set lecoffreFront.image.tag=$TAG + + +workflows: + version: 2 + build-and-register: + jobs: + - build-push-docker-image: + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ + - deploy-docker-image: + requires: + - build-push-docker-image + context: + - staging + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ + diff --git a/Dockerfiles/Dockerfile.front b/Dockerfile similarity index 100% rename from Dockerfiles/Dockerfile.front rename to Dockerfile diff --git a/devops/.helmignore b/devops/.helmignore new file mode 100644 index 00000000..691fa13d --- /dev/null +++ b/devops/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/devops/Chart.yaml b/devops/Chart.yaml new file mode 100644 index 00000000..e9a6b889 --- /dev/null +++ b/devops/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +name: leCoffre-front +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +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: 0.0.1 + +# 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. +# It is recommended to use it with quotes. +appVersion: 0.1.9 + diff --git a/devops/templates/lecoffre-front.yaml b/devops/templates/lecoffre-front.yaml new file mode 100644 index 00000000..5f375de6 --- /dev/null +++ b/devops/templates/lecoffre-front.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: lecoffre-front + namespace: {{ .Values.namespace }} +{{if .Values.lecoffreFront.ingress.annotations}} + annotations: +{{toYaml .Values.lecoffreFront.ingress.annotations | indent 4 }} +{{end}} +spec: + tls: + - hosts: {{ .Values.lecoffreFront.ingress.tls.hosts }} + secretName: {{ .Values.lecoffreFront.ingress.tls.secretName }} + rules: + - host: {{ .Values.lecoffreFront.ingress.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: lecoffre-front-svc + port: + number: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: lecoffre-front-svc + namespace: {{ .Values.namespace }} + labels: +spec: + ports: + - port: 80 + name: http + targetPort: 3000 + selector: + app: lecoffre-front +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: lecoffre-front + namespace: {{ .Values.namespace }} + labels: + app: lecoffre-front +spec: + replicas: 1 + selector: + matchLabels: + app: lecoffre-front + template: + metadata: + annotations: +{{toYaml .Values.lecoffreFront.vault.annotations | indent 8 }} + labels: + app: lecoffre-front + spec: + serviceAccountName: {{ .Values.lecoffreFront.serviceAccountName }} + imagePullSecrets: + - name: docker-pull-secret + containers: + - name: lecoffre-front + image: "{{ .Values.lecoffreFront.image.repository }}:v{{ .Chart.AppVersion }}" +{{if .Values.lecoffreFront.resources}} + resources: +{{toYaml .Values.lecoffreFront.resources | indent 10}} +{{end}} + imagePullPolicy: {{ .Values.lecoffreFront.image.pullPolicy }} + command: [{{ .Values.lecoffreFront.command }}] \ No newline at end of file diff --git a/devops/templates/service-account.yaml b/devops/templates/service-account.yaml new file mode 100644 index 00000000..161dde69 --- /dev/null +++ b/devops/templates/service-account.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.lecoffreFront.serviceAccountName }} + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.lecoffreFront.serviceAccountName }}-token + annotations: + kubernetes.io/service-account.name: {{ .Values.lecoffreFront.serviceAccountName }} +type: kubernetes.io/service-account-token \ No newline at end of file diff --git a/devops/values.yaml b/devops/values.yaml new file mode 100644 index 00000000..c7a9480c --- /dev/null +++ b/devops/values.yaml @@ -0,0 +1,44 @@ +dockerPullSecret: secret/data/lecoffre-front-stg/config/dockerpullsecret + +namespace: lecoffre + +lecoffreFront: + serviceAccountName: lecoffre-front-sa + command: "'sh', '-c', '. /vault/secrets/envs && npm run start'" + vault: + role : custom_lecoffre-front_injector_rol + server: https://vault-stg.smart-chain.fr + annotations: + vault.hashicorp.com/agent-pre-populate-only: "true" + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/agent-inject-secret-envs: secret/data/lecoffre-front-stg/config/envs + vault.hashicorp.com/role: custom_lecoffre-front_injector_rol + vault.hashicorp.com/agent-inject-template-envs: | + {{ with secret "secret/data/lecoffre-front-stg/config/envs" }} + {{ range $k, $v := .Data.data }} + export {{ $k }}="{{ $v }}" + {{ end }} + {{ end }} + imagePullSecrets: + - name: docker-pull-secret + image: + pullPolicy: Always + repository: "rg.fr-par.scw.cloud/lecoffre/front" + resources: + requests: + cpu: 200m + memory: 1Gi + limits: + memory: 2Gi + ingress: + host: app.stg.lecoffre.smart-chain.fr + tls: + hosts: + - app.stg.lecoffre.smart-chain.fr + secretName: app-tls + annotations: + kubernetes.io/ingress.class: nginx + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/from-to-www-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + diff --git a/package.json b/package.json index 3ce29d6c..181ad805 100644 --- a/package.json +++ b/package.json @@ -31,3 +31,5 @@ "typescript": "4.9.5" } } + + diff --git a/src/front/Assets/icons/burger.svg b/src/front/Assets/Icons/burger.svg similarity index 100% rename from src/front/Assets/icons/burger.svg rename to src/front/Assets/Icons/burger.svg diff --git a/src/front/Assets/icons/check-valid.svg b/src/front/Assets/Icons/check-valid.svg similarity index 100% rename from src/front/Assets/icons/check-valid.svg rename to src/front/Assets/Icons/check-valid.svg diff --git a/src/front/Assets/icons/check.svg b/src/front/Assets/Icons/check.svg similarity index 100% rename from src/front/Assets/icons/check.svg rename to src/front/Assets/Icons/check.svg diff --git a/src/front/Assets/icons/chevron.svg b/src/front/Assets/Icons/chevron.svg similarity index 100% rename from src/front/Assets/icons/chevron.svg rename to src/front/Assets/Icons/chevron.svg diff --git a/src/front/Assets/icons/coffre.svg b/src/front/Assets/Icons/coffre.svg similarity index 100% rename from src/front/Assets/icons/coffre.svg rename to src/front/Assets/Icons/coffre.svg diff --git a/src/front/Assets/icons/cross.svg b/src/front/Assets/Icons/cross.svg similarity index 100% rename from src/front/Assets/icons/cross.svg rename to src/front/Assets/Icons/cross.svg diff --git a/src/front/Assets/icons/disconnect.svg b/src/front/Assets/Icons/disconnect.svg similarity index 100% rename from src/front/Assets/icons/disconnect.svg rename to src/front/Assets/Icons/disconnect.svg diff --git a/src/front/Assets/icons/info.svg b/src/front/Assets/Icons/info.svg similarity index 100% rename from src/front/Assets/icons/info.svg rename to src/front/Assets/Icons/info.svg diff --git a/src/front/Assets/icons/notification.svg b/src/front/Assets/Icons/notification.svg similarity index 100% rename from src/front/Assets/icons/notification.svg rename to src/front/Assets/Icons/notification.svg diff --git a/src/front/Assets/icons/pen.svg b/src/front/Assets/Icons/pen.svg similarity index 100% rename from src/front/Assets/icons/pen.svg rename to src/front/Assets/Icons/pen.svg diff --git a/src/front/Assets/icons/plus.svg b/src/front/Assets/Icons/plus.svg similarity index 100% rename from src/front/Assets/icons/plus.svg rename to src/front/Assets/Icons/plus.svg diff --git a/src/front/Assets/icons/tool-tip.svg b/src/front/Assets/Icons/tool-tip.svg similarity index 100% rename from src/front/Assets/icons/tool-tip.svg rename to src/front/Assets/Icons/tool-tip.svg diff --git a/src/front/Assets/icons/trash.svg b/src/front/Assets/Icons/trash.svg similarity index 100% rename from src/front/Assets/icons/trash.svg rename to src/front/Assets/Icons/trash.svg diff --git a/src/front/Assets/icons/user.svg b/src/front/Assets/Icons/user.svg similarity index 100% rename from src/front/Assets/icons/user.svg rename to src/front/Assets/Icons/user.svg diff --git a/src/front/Assets/icons/warning.svg b/src/front/Assets/Icons/warning.svg similarity index 100% rename from src/front/Assets/icons/warning.svg rename to src/front/Assets/Icons/warning.svg diff --git a/temp.yaml b/temp.yaml new file mode 100644 index 00000000..6db74af0 --- /dev/null +++ b/temp.yaml @@ -0,0 +1,126 @@ +--- +# Source: leCoffre-front/templates/service-account.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: lecoffre-front-sa +--- +# Source: leCoffre-front/templates/service-account.yaml +apiVersion: v1 +kind: Secret +metadata: + name: lecoffre-front-sa-token + annotations: + kubernetes.io/service-account.name: lecoffre-front-sa +type: kubernetes.io/service-account-token +--- +# Source: leCoffre-front/templates/lecoffre-front.yaml +apiVersion: v1 +kind: Service +metadata: + name: lecoffre-front-svc + namespace: lecoffre + labels: +spec: + ports: + - port: 80 + name: http + targetPort: 3000 + selector: + app: lecoffre-front +--- +# Source: leCoffre-front/templates/lecoffre-front.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: lecoffre-front + namespace: lecoffre + labels: + app: lecoffre-front +spec: + replicas: 1 + selector: + matchLabels: + app: lecoffre-front + template: + metadata: + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/agent-inject-secret-envs: secret/data/lecoffre-front-stg/config/envs + vault.hashicorp.com/agent-inject-template-envs: | + {{ with secret "secret/data/lecoffre-front-stg/config/envs" }} + {{ range $k, $v := .Data.data }} + export {{ $k }}="{{ $v }}" + {{ end }} + {{ end }} + vault.hashicorp.com/agent-pre-populate-only: "true" + vault.hashicorp.com/role: custom_lecoffre-front_injector_rol + labels: + app: lecoffre-front + spec: + serviceAccountName: lecoffre-front-sa + imagePullSecrets: + - name: docker-pull-secret + containers: + - name: lecoffre-front + image: "rg.fr-par.scw.cloud/lecoffre/front:v0.1.9" + + resources: + limits: + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + + imagePullPolicy: Always + command: ['sh', '-c', '. /vault/secrets/envs && npm run start'] +--- +# Source: leCoffre-front/templates/lecoffre-front.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: lecoffre-front + namespace: lecoffre + + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + nginx.ingress.kubernetes.io/from-to-www-redirect: "true" + +spec: + tls: + - hosts: [app.stg.lecoffre.smart-chain.fr] + secretName: app-tls + rules: + - host: app.stg.lecoffre.smart-chain.fr + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: lecoffre-front-svc + port: + number: 80 +--- +# Source: leCoffre-front/templates/docker-pull-secret.yaml +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: docker-pull-secret +spec: + refreshInterval: 1h + secretStoreRef: + name: dockerpullsecret-vault-cluster-secret-store + kind: ClusterSecretStore + target: + template: + type: kubernetes.io/dockerconfigjson + name: docker-pull-secret + creationPolicy: Owner + data: + - secretKey: .dockerconfigjson + remoteRef: + key: secret/data/lecoffre-front-stg/config/dockerpullsecret + property: .dockerconfigjson