chore(git): code staging
Signed-off-by: zhenyus <zhenyus@mathmast.com>
This commit is contained in:
parent
0e256f8708
commit
f34f9838a5
@ -0,0 +1,33 @@
|
||||
package com.freeleaps.devops
|
||||
|
||||
class ArgoApplicationVersionUpdater {
|
||||
def steps
|
||||
def workspace
|
||||
|
||||
ArgoApplicationVersionUpdater(steps) {
|
||||
this.steps = steps
|
||||
}
|
||||
|
||||
def update(environmentSlug, component) {
|
||||
steps.log.info("ArgoApplicationVersionUpdater", "[${environmentSlug}] Update Argo application image version for ${component.name}...")
|
||||
def valuesFile = "${workspace}/../helm/${component.name}/values-${environmentSlug}.yaml"
|
||||
def data = steps.readYaml (file: valuesFile)
|
||||
data.${component.name}.image.registry = steps.env.BUILD_IMAGE_REGISTRY
|
||||
data.${component.name}.image.repository = steps.env.BUILD_IMAGE_REPOSITORY
|
||||
data.${component.name}.image.tag = steps.env.BUILD_IMAGE_VERSION
|
||||
data.${component.name}.image.name = steps.env.BUILD_IMAGE_NAME
|
||||
steps.writeFile file: valuesFile, data: data, overwrite: true
|
||||
|
||||
steps.withCredentials([steps.usernamePassword(credentialsId: 'freeleaps-ops-credentials', passwordVariable: 'OPS_GIT_PASSWORD', usernameVariable: 'OPS_GIT_USERNAME')]) {
|
||||
steps.sh """
|
||||
git config user.name "freeleaps-gitops-bot"
|
||||
git config user.email "gitops@mathmast.com"
|
||||
git remote add ci_origin https://${OPS_GIT_USERNAME}:${OPS_GIT_PASSWORD}@dev.azure.com/freeleaps/freeleaps-ops/_git/freeleaps-ops
|
||||
git add ${valuesFile}
|
||||
git commit -m "ci(bump): bump ${component.name} image version for ${environmentSlug} to ${steps.env.BUILD_IMAGE_VERSION}"
|
||||
git push ci_origin HEAD:master
|
||||
"""
|
||||
steps.log.info("ArgoApplicationVersionUpdater", "[${environmentSlug}] ${component.name} image version bump to ${steps.env.BUILD_IMAGE_VERSION}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,6 +114,10 @@ class ImageBuilder {
|
||||
steps.log.info("ImageBuilder", "Set builder timeout to 10min...")
|
||||
steps.env.BUILDKIT_TIMEOUT = "1800s"
|
||||
steps.sh "docker buildx build --builder ${buildxBuilderName} --platform ${architectures.join(",")} -t ${registry}/${repository}/${name}:${version} -f ${dockerfile} --push ${contextRoot}"
|
||||
steps.env.BUILD_IMAGE_REGISTRY = "${registry}"
|
||||
steps.env.BUILD_IMAGE_REPO = "${repository}"
|
||||
steps.env.BUILD_IMAGE_NAME = "${name}"
|
||||
steps.env.BUILD_IMAGE_VERSION = "${version}"
|
||||
} else {
|
||||
architectures.each { architecture ->
|
||||
def archTag = architecture.split("/")[1]
|
||||
@ -121,6 +125,10 @@ class ImageBuilder {
|
||||
steps.sh "docker build -t ${registry}/${repository}/${name}:${version}-${archTag} --platform ${architecture} -f ${dockerfile} ${contextRoot}"
|
||||
steps.sh "docker push ${registry}/${repository}/${name}:${version}-${archTag}"
|
||||
}
|
||||
steps.env.BUILD_IMAGE_REGISTRY = "${registry}"
|
||||
steps.env.BUILD_IMAGE_REPO = "${repository}"
|
||||
steps.env.BUILD_IMAGE_NAME = "${name}"
|
||||
steps.env.BUILD_IMAGE_VERSION = "${version}-linux-amd64"
|
||||
}
|
||||
}
|
||||
break
|
||||
@ -131,6 +139,10 @@ class ImageBuilder {
|
||||
steps.log.info("ImageBuilder", "Building image ${registry}/${repository}/${name} with architectures: ${architectures}, tag sets to ${version}-${archTag}")
|
||||
steps.sh "/kaniko/executor --log-format text --context ${contextRoot} --dockerfile ${dockerfile} --destination ${registry}/${repository}/${name}:${version}-${archTag} --custom-platform ${architecture}"
|
||||
}
|
||||
steps.env.BUILD_IMAGE_REGISTRY = "${registry}"
|
||||
steps.env.BUILD_IMAGE_REPO = "${repository}"
|
||||
steps.env.BUILD_IMAGE_NAME = "${name}"
|
||||
steps.env.BUILD_IMAGE_VERSION = "${version}-linux-amd64"
|
||||
}
|
||||
break
|
||||
default:
|
||||
|
||||
@ -378,8 +378,9 @@ def generateComponentStages(component, configurations) {
|
||||
}
|
||||
}
|
||||
}},
|
||||
// Image Building & Publishing
|
||||
{stage("${component.name} :: Image Building & Publishing") {
|
||||
{
|
||||
// Image Building & Publishing
|
||||
stage("${component.name} :: Image Building & Publishing") {
|
||||
podTemplate(
|
||||
label: "image-builder-${component.name}",
|
||||
containers: [
|
||||
@ -448,7 +449,18 @@ def generateComponentStages(component, configurations) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
},
|
||||
{
|
||||
stage("${component.name} :: Argo Application Version Updating") {
|
||||
script {
|
||||
if (env.executeMode == "fully" || env.changedComponents.contains(component.name)) {
|
||||
def argoApplicationVersionUpdater = new ArgoApplicationVersionUpdater(this)
|
||||
argoApplicationVersionUpdater.update(configurations.environmentSlug, component)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
])
|
||||
return {
|
||||
stages.each { stageClosure ->
|
||||
|
||||
193
magicleaps/alpha/ci/Jenkinsfile
vendored
193
magicleaps/alpha/ci/Jenkinsfile
vendored
@ -1,141 +1,56 @@
|
||||
def REGISTRY_URL = 'docker.io'
|
||||
def REPO_NAME = 'zhenyus'
|
||||
def IMAGE_NAME = 'magicleaps'
|
||||
def APP_NAME = 'magicleaps'
|
||||
def TAG_PREFIX = 'snapshot'
|
||||
def DOCKER_REGISTRY_SECRET = 'kaniko-secret'
|
||||
library 'first-class-pipeline'
|
||||
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
git credentialsId: 'freeleaps-azure-dev', url: 'https://freeleaps@dev.azure.com/freeleaps/magicleaps/_git/magicleaps'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Set Commit Hash') {
|
||||
steps {
|
||||
script {
|
||||
def commitHash = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
|
||||
def shortCommitHash = commitHash.take(7)
|
||||
env.COMMIT_HASH = shortCommitHash
|
||||
echo "Commit Hash: ${env.COMMIT_HASH}"
|
||||
env.TRIGGERED_BRANCH = "${GIT_BRANCH}"
|
||||
echo "Triggered Branch: ${env.TRIGGERED_BRANCH}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build Docker Images For Each Components') {
|
||||
matrix {
|
||||
axes {
|
||||
axis {
|
||||
name 'COMPONENT'
|
||||
values 'backend', 'frontend'
|
||||
}
|
||||
axis {
|
||||
name 'ARCH'
|
||||
values 'linux/amd64'
|
||||
}
|
||||
}
|
||||
|
||||
agent {
|
||||
kubernetes {
|
||||
defaultContainer 'kaniko'
|
||||
yaml """
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
freeleaps-devops-job: magicleaps-app-build
|
||||
freeleaps-devops-app: magicleaps
|
||||
spec:
|
||||
containers:
|
||||
- name: kaniko
|
||||
image: gcr.io/kaniko-project/executor:debug
|
||||
command:
|
||||
- cat
|
||||
tty: true
|
||||
volumeMounts:
|
||||
- name: kaniko-secret
|
||||
mountPath: /kaniko/.docker/config.json
|
||||
subPath: .dockerconfigjson
|
||||
- name: workspace
|
||||
mountPath: /workspace
|
||||
volumes:
|
||||
- name: kaniko-secret
|
||||
secret:
|
||||
secretName: kaniko-secret
|
||||
- name: workspace
|
||||
emptyDir: {}
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Image Building') {
|
||||
steps {
|
||||
script {
|
||||
def dockerfilePath = "${COMPONENT}/Dockerfile"
|
||||
def arch = "${ARCH}"
|
||||
def archTag = arch.replace('/', '-')
|
||||
def targetImage = "${REGISTRY_URL}/${REPO_NAME}/${IMAGE_NAME}:${COMPONENT}-${TAG_PREFIX}-${COMMIT_HASH}-${archTag}"
|
||||
echo "Building Docker image ${targetImage}..."
|
||||
|
||||
sh """
|
||||
/kaniko/executor \
|
||||
--dockerfile=${dockerfilePath} \
|
||||
--context=${COMPONENT} \
|
||||
--destination=${targetImage} \
|
||||
--custom-platform=${ARCH} \
|
||||
--skip-tls-verify=true \
|
||||
--ignore-path=/product_uuid
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy with Argo CD') {
|
||||
stages {
|
||||
stage('Clone GitOps Manifests Repo') {
|
||||
steps {
|
||||
git credentialsId: 'freeleaps-azure-dev', url: 'https://freeleaps@dev.azure.com/freeleaps/freeleaps-ops/_git/freeleaps-ops'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Automate Update Application Image Tag') {
|
||||
steps {
|
||||
script {
|
||||
def triggeredBranch = "${TRIGGERED_BRANCH}"
|
||||
if (triggeredBranch == 'origin/master') {
|
||||
echo "Triggered branch is master, deploying to alpha..."
|
||||
def valuesFile = APP_NAME + '/helm-pkg/' + APP_NAME + '/values.alpha.yaml'
|
||||
def data = readYaml (file: valuesFile)
|
||||
data.backend.image.tag = "backend-${TAG_PREFIX}-${env.COMMIT_HASH}-linux-amd64"
|
||||
data.frontend.image.tag = "frontend-${TAG_PREFIX}-${env.COMMIT_HASH}-linux-amd64"
|
||||
writeYaml file: valuesFile, data: data, overwrite: true
|
||||
// git push
|
||||
withCredentials([string(credentialsId: 'freeleaps-azure-dev-token-only', variable: 'GIT_CREDENTIALS')]) {
|
||||
sh """
|
||||
git config user.name "zhenyus"
|
||||
git config user.email "zhenyus@mathmast.com"
|
||||
git remote add ci_origin https://zhenyus:${GIT_CREDENTIALS}@dev.azure.com/freeleaps/freeleaps-ops/_git/freeleaps-ops
|
||||
git add ${valuesFile}
|
||||
git commit -m "ci(bot-auto-bump): bump ${APP_NAME} image tags for alpha to ${TAG_PREFIX}-${env.COMMIT_HASH}-linux-amd64"
|
||||
git push ci_origin HEAD:master
|
||||
"""
|
||||
}
|
||||
echo "Update ${APP_NAME} image tags for alpha to ${TAG_PREFIX}-${env.COMMIT_HASH}-linux-amd64."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
executeFreeleapsPipeline {
|
||||
serviceName = 'magicleaps'
|
||||
environmentSlug = 'alpha'
|
||||
serviceGitBranch = 'master'
|
||||
serviceGitRepo = "https://freeleaps@dev.azure.com/freeleaps/magicleaps/_git/magicleaps"
|
||||
serviceGitRepoType = 'monorepo'
|
||||
serviceGitCredentialsId = 'magicleaps-azure-devops-credentials'
|
||||
executeMode = 'fully'
|
||||
commitMessageLintEnabled = true
|
||||
components = [
|
||||
[
|
||||
name: 'frontend',
|
||||
root: 'frontend',
|
||||
language: 'javascript',
|
||||
dependenciesManager: 'npm',
|
||||
npmPackageJsonFile: 'package.json',
|
||||
buildCacheEnabled: true,
|
||||
buildAgentImage: 'node:lts',
|
||||
buildCommand: 'npm run build',
|
||||
buildArtifacts: ['dist'],
|
||||
lintEnabled: false,
|
||||
sastEnabled: false,
|
||||
imageRegistry: 'docker.io',
|
||||
imageRepository: 'sunzhenyucn',
|
||||
imageName: 'magicleaps-frontend',
|
||||
imageBuilder: 'dind',
|
||||
dockerfilePath: 'Dockerfile',
|
||||
imageBuildRoot: '.',
|
||||
imageReleaseArchitectures: ['linux/amd64', 'linux/arm64/v8'],
|
||||
registryCredentialsId: 'magicleaps-dockerhub-credentials',
|
||||
semanticReleaseEnabled: true
|
||||
],
|
||||
[
|
||||
name: 'backend',
|
||||
root: 'backend',
|
||||
language: 'python',
|
||||
dependenciesManager: 'pip',
|
||||
buildAgentImage: 'python:3.8-slim-buster',
|
||||
buildArtifacts: ['.'],
|
||||
buildCacheEnabled: true,
|
||||
lintEnabled: false,
|
||||
sastEnabled: false,
|
||||
imageRegistry: 'docker.io',
|
||||
imageRepository: 'sunzhenyucn',
|
||||
imageName: 'magicleaps-backend',
|
||||
imageBuilder: 'dind',
|
||||
dockerfilePath: 'Dockerfile',
|
||||
imageBuildRoot: '.',
|
||||
imageReleaseArchitectures: ['linux/amd64', 'linux/arm64/v8'],
|
||||
registryCredentialsId: 'magicleaps-dockerhub-credentials',
|
||||
semanticReleaseEnabled: true
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
# 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/
|
||||
@ -1,6 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: magicleaps
|
||||
description: A Helm chart for Magic Leaps application.
|
||||
description: A Helm Chart of magicleaps, powered by Freeleaps.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "0.1.0"
|
||||
version: 0.0.1
|
||||
appVersion: "0.0.1"
|
||||
@ -1,107 +0,0 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "magicleaps.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Expand the name of the frontend.
|
||||
*/}}
|
||||
{{- define "magicleaps.frontend.name" -}}
|
||||
{{- default .Values.frontend.name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Expand the name of the backend.
|
||||
*/}}
|
||||
{{- define "magicleaps.backend.name" -}}
|
||||
{{- default .Values.backend.name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "magicleaps.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "magicleaps.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Backend labels
|
||||
*/}}
|
||||
{{- define "magicleaps.backend.labels" -}}
|
||||
helm.sh/chart: {{ include "magicleaps.chart" . }}
|
||||
{{ include "magicleaps.backend.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Backend Selector labels
|
||||
*/}}
|
||||
{{- define "magicleaps.backend.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "magicleaps.backend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Frontend labels
|
||||
*/}}
|
||||
{{- define "magicleaps.frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "magicleaps.chart" . }}
|
||||
{{ include "magicleaps.frontend.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Frontend Selector labels
|
||||
*/}}
|
||||
{{- define "magicleaps.frontend.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "magicleaps.frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Return the appropriate apiVersion for deployment.
|
||||
*/}}
|
||||
{{- define "magicleaps.deployment.apiVersion" -}}
|
||||
{{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- else if semverCompare "^1.9-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
{{- print "apps/v1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Define the magicleaps.namespace template if set with forceNamespace or .Release.Namespace is set
|
||||
*/}}
|
||||
{{- define "magicleaps.namespace" -}}
|
||||
{{- if .Values.forceNamespace -}}
|
||||
{{ printf "namespace: %s" .Values.forceNamespace }}
|
||||
{{- else -}}
|
||||
{{ printf "namespace: %s" .Release.Namespace }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@ -0,0 +1,98 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/name: "backend"
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
name: "backend"
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: "backend"
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
replicas: {{ .Values.backend.replicas }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/name: "backend"
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
spec:
|
||||
containers:
|
||||
- name: "backend"
|
||||
image: "{{ coalesce .Values.backend.image.registry .Values.global.registry "docker.io"}}/{{ coalesce .Values.backend.image.repository .Values.global.repository }}/{{ .Values.backend.image.name }}:{{ .Values.backend.image.tag | default "latest" }}"
|
||||
imagePullPolicy: {{ .Values.backend.image.imagePullPolicy | default "IfNotPresent" }}
|
||||
ports:
|
||||
{{- range $port := .Values.backend.ports }}
|
||||
- containerPort: {{ $port.containerPort }}
|
||||
name: {{ $port.name }}
|
||||
protocol: {{ $port.protocol }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.resources }}
|
||||
resources:
|
||||
{{- toYaml .Values.backend.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes }}
|
||||
{{- if and (.Values.backend.probes.liveness) (eq .Values.backend.probes.liveness.type "httpGet") }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.backend.probes.liveness.config.path }}
|
||||
port: {{ .Values.backend.probes.liveness.config.port }}
|
||||
{{- if .Values.backend.probes.liveness.config.initialDelaySeconds }}
|
||||
initialDelaySeconds: {{ .Values.backend.probes.liveness.config.initialDelaySeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.liveness.config.periodSeconds }}
|
||||
periodSeconds: {{ .Values.backend.probes.liveness.config.periodSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.liveness.config.timeoutSeconds }}
|
||||
timeoutSeconds: {{ .Values.backend.probes.liveness.config.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.liveness.config.successThreshold }}
|
||||
successThreshold: {{ .Values.backend.probes.liveness.config.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.liveness.config.failureThreshold }}
|
||||
failureThreshold: {{ .Values.backend.probes.liveness.config.failureThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.liveness.config.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.backend.probes.liveness.config.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and (.Values.backend.probes.readiness) (eq .Values.backend.probes.readiness.type "httpGet") }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.backend.probes.readiness.config.path }}
|
||||
port: {{ .Values.backend.probes.readiness.config.port }}
|
||||
{{- if .Values.backend.probes.readiness.config.initialDelaySeconds }}
|
||||
initialDelaySeconds: {{ .Values.backend.probes.readiness.config.initialDelaySeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.readiness.config.periodSeconds }}
|
||||
periodSeconds: {{ .Values.backend.probes.readiness.config.periodSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.readiness.config.timeoutSeconds }}
|
||||
timeoutSeconds: {{ .Values.backend.probes.readiness.config.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.readiness.config.successThreshold }}
|
||||
successThreshold: {{ .Values.backend.probes.readiness.config.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.readiness.config.failureThreshold }}
|
||||
failureThreshold: {{ .Values.backend.probes.readiness.config.failureThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.probes.readiness.config.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.backend.probes.readiness.config.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
env:
|
||||
{{- range $key, $value := .Values.backend.configs }}
|
||||
- name: {{ $key | snakecase | upper }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: magicleaps-backend-config
|
||||
key: {{ $key | snakecase | upper }}
|
||||
{{- end }}
|
||||
@ -0,0 +1,22 @@
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: magicleaps-backend-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
type: Opaque
|
||||
data:
|
||||
TZ: {{ .Values.backend.configs.tz | b64enc | quote }}
|
||||
MONGODB_HOST: {{ .Values.backend.configs.mongodbHost | b64enc | quote }}
|
||||
MONGODB_PORT: {{ .Values.backend.configs.mongodbPort | b64enc | quote }}
|
||||
MONGODB_NAME: {{ .Values.backend.configs.mongodbName | b64enc | quote }}
|
||||
EMAIL_USER: {{ .Values.backend.configs.emailUser | b64enc | quote }}
|
||||
EMAIL_PASSWORD: {{ .Values.backend.configs.emailPassword | b64enc | quote }}
|
||||
SUPER_ADMIN: {{ .Values.backend.configs.superAdmin | b64enc | quote }}
|
||||
TWILIO_ACCOUNT_SID: {{ .Values.backend.configs.twilioAccountSid | b64enc | quote }}
|
||||
TWILIO_AUTH_TOKEN: {{ .Values.backend.configs.twilioAuthToken | b64enc | quote }}
|
||||
EVELUATION_TASK_FOLDER_BASE: {{ .Values.backend.configs.eveluationTaskFolderBase | b64enc | quote }}
|
||||
LOG_DIR: {{ .Values.backend.configs.logDir | b64enc | quote }}
|
||||
APP_LOG_FILE: {{ .Values.backend.configs.appLogFile | b64enc | quote }}
|
||||
APP_LOG_LEVEL: {{ .Values.backend.configs.appLogLevel | b64enc | quote }}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
{{ $namespace := .Release.Namespace }}
|
||||
{{ $appVersion := .Chart.AppVersion | quote }}
|
||||
{{ $releaseService := .Release.Service }}
|
||||
{{ $releaseName := .Release.Name }}
|
||||
{{- range $service := .Values.backend.services }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $service.name }}
|
||||
namespace: {{ $namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ $appVersion }}
|
||||
app.kubernetes.io/name: {{ $service.name | quote }}
|
||||
app.kubernetes.io/managed-by: {{ $releaseService }}
|
||||
app.kubernetes.io/instance: {{ $releaseName }}
|
||||
spec:
|
||||
ports:
|
||||
- port: {{ $service.port }}
|
||||
targetPort: {{ $service.targetPort }}
|
||||
selector:
|
||||
app.kubernetes.io/version: {{ $appVersion }}
|
||||
app.kubernetes.io/name: "backend"
|
||||
app.kubernetes.io/managed-by: {{ $releaseService }}
|
||||
app.kubernetes.io/instance: {{ $releaseName }}
|
||||
{{- end }}
|
||||
@ -1,87 +0,0 @@
|
||||
{{- if .Values.backend.enabled -}}
|
||||
apiVersion: {{ template "magicleaps.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "magicleaps.backend.labels" . | nindent 4 }}
|
||||
name: {{ .Values.backend.name }}
|
||||
{{ include "magicleaps.namespace" . | indent 2 }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "magicleaps.backend.labels" . | nindent 6 }}
|
||||
replicas: {{ .Values.backend.replicaCount }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "magicleaps.backend.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- if .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml .Values.imagePullSecrets | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Values.backend.name }}
|
||||
image: "{{ .Values.backend.image.repository }}/{{ .Values.backend.image.name }}{{ if .Values.backend.image.tag }}:{{ .Values.backend.image.tag }}{{ end }}"
|
||||
imagePullPolicy: {{ .Values.backend.image.imagePullPolicy }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.backend.port }}
|
||||
{{- if .Values.backend.extraEnv }}
|
||||
env:
|
||||
{{- toYaml .Values.backend.extraEnv | nindent 12 }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.backend.livenessProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.backend.readinessProbe | nindent 12 }}
|
||||
{{- if .Values.backend.resources }}
|
||||
resources:
|
||||
{{- toYaml .Values.backend.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
env:
|
||||
- name: MONGO_DB
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: MONGO_DB
|
||||
- name: MONGO_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: MONGO_HOST
|
||||
- name: MONGO_PORT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: MONGO_PORT
|
||||
- name: EMAIL_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: EMAIL_USER
|
||||
- name: EMAIL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: EMAIL_PASSWORD
|
||||
- name: SUPER_ADMIN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: SUPER_ADMIN
|
||||
- name: TWILIO_ACCOUNT_SID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: TWILIO_ACCOUNT_SID
|
||||
- name: TWILIO_AUTH_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: TWILIO_AUTH_TOKEN
|
||||
- name: LOG_LEVEL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: backend-secrets
|
||||
key: LOG_LEVEL
|
||||
{{- end -}}
|
||||
@ -1,41 +0,0 @@
|
||||
{{- if .Values.frontend.enabled }}
|
||||
apiVersion: {{ template "magicleaps.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "magicleaps.frontend.labels" . | nindent 4 }}
|
||||
name: {{ .Values.frontend.name }}
|
||||
{{ include "magicleaps.namespace" . | indent 2 }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "magicleaps.frontend.labels" . | nindent 6 }}
|
||||
replicas: {{ .Values.frontend.replicaCount }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "magicleaps.frontend.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- if .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml .Values.imagePullSecrets | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Values.frontend.name }}
|
||||
image: "{{ .Values.frontend.image.repository }}/{{ .Values.frontend.image.name }}{{ if .Values.frontend.image.tag }}:{{ .Values.frontend.image.tag }}{{ end }}"
|
||||
imagePullPolicy: {{ .Values.frontend.image.imagePullPolicy }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.frontend.port }}
|
||||
{{- if .Values.frontend.extraEnv }}
|
||||
env:
|
||||
{{- toYaml .Values.frontend.extraEnv | nindent 12 }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.frontend.livenessProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.frontend.readinessProbe | nindent 12 }}
|
||||
{{- if .Values.frontend.resources }}
|
||||
resources:
|
||||
{{- toYaml .Values.frontend.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@ -0,0 +1,27 @@
|
||||
{{ $namespace := .Release.Namespace }}
|
||||
{{ $appVersion := .Chart.AppVersion | quote }}
|
||||
{{ $releaseCertificate := .Release.Certificate }}
|
||||
{{ $releaseName := .Release.Name }}
|
||||
{{- range $ingress := .Values.frontend.ingresses }}
|
||||
{{- if not $ingress.tls.exists }}
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: {{ $ingress.name }}
|
||||
namespace: {{ $namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ $appVersion }}
|
||||
app.kubernetes.io/name: {{ $ingress.name | quote }}
|
||||
app.kubernetes.io/managed-by: {{ $releaseCertificate }}
|
||||
app.kubernetes.io/instance: {{ $releaseName }}
|
||||
spec:
|
||||
commonName: {{ $ingress.host }}
|
||||
dnsNames:
|
||||
- {{ $ingress.host }}
|
||||
issuerRef:
|
||||
name: {{ $ingress.tls.issuerRef.name }}
|
||||
kind: {{ $ingress.tls.issuerRef.kind }}
|
||||
secretName: {{ $ingress.tls.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@ -0,0 +1,98 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/name: "frontend"
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
name: "frontend"
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: "frontend"
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
replicas: {{ .Values.frontend.replicas }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/name: "frontend"
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
spec:
|
||||
containers:
|
||||
- name: "frontend"
|
||||
image: "{{ coalesce .Values.frontend.image.registry .Values.global.registry "docker.io"}}/{{ coalesce .Values.frontend.image.repository .Values.global.repository }}/{{ .Values.frontend.image.name }}:{{ .Values.frontend.image.tag | default "latest" }}"
|
||||
imagePullPolicy: {{ .Values.frontend.image.imagePullPolicy | default "IfNotPresent" }}
|
||||
ports:
|
||||
{{- range $port := .Values.frontend.ports }}
|
||||
- containerPort: {{ $port.containerPort }}
|
||||
name: {{ $port.name }}
|
||||
protocol: {{ $port.protocol }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.resources }}
|
||||
resources:
|
||||
{{- toYaml .Values.frontend.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes }}
|
||||
{{- if and (.Values.frontend.probes.liveness) (eq .Values.frontend.probes.liveness.type "httpGet") }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.frontend.probes.liveness.config.path }}
|
||||
port: {{ .Values.frontend.probes.liveness.config.port }}
|
||||
{{- if .Values.frontend.probes.liveness.config.initialDelaySeconds }}
|
||||
initialDelaySeconds: {{ .Values.frontend.probes.liveness.config.initialDelaySeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.liveness.config.periodSeconds }}
|
||||
periodSeconds: {{ .Values.frontend.probes.liveness.config.periodSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.liveness.config.timeoutSeconds }}
|
||||
timeoutSeconds: {{ .Values.frontend.probes.liveness.config.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.liveness.config.successThreshold }}
|
||||
successThreshold: {{ .Values.frontend.probes.liveness.config.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.liveness.config.failureThreshold }}
|
||||
failureThreshold: {{ .Values.frontend.probes.liveness.config.failureThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.liveness.config.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.frontend.probes.liveness.config.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and (.Values.frontend.probes.readiness) (eq .Values.frontend.probes.readiness.type "httpGet") }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.frontend.probes.readiness.config.path }}
|
||||
port: {{ .Values.frontend.probes.readiness.config.port }}
|
||||
{{- if .Values.frontend.probes.readiness.config.initialDelaySeconds }}
|
||||
initialDelaySeconds: {{ .Values.frontend.probes.readiness.config.initialDelaySeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.readiness.config.periodSeconds }}
|
||||
periodSeconds: {{ .Values.frontend.probes.readiness.config.periodSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.readiness.config.timeoutSeconds }}
|
||||
timeoutSeconds: {{ .Values.frontend.probes.readiness.config.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.readiness.config.successThreshold }}
|
||||
successThreshold: {{ .Values.frontend.probes.readiness.config.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.readiness.config.failureThreshold }}
|
||||
failureThreshold: {{ .Values.frontend.probes.readiness.config.failureThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.probes.readiness.config.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.frontend.probes.readiness.config.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
env:
|
||||
{{- range $key, $value := .Values.frontend.configs }}
|
||||
- name: {{ $key | snakecase | upper }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: magicleaps-frontend-config
|
||||
key: {{ $key | snakecase | upper }}
|
||||
{{- end }}
|
||||
@ -0,0 +1,38 @@
|
||||
{{ $namespace := .Release.Namespace }}
|
||||
{{ $appVersion := .Chart.AppVersion | quote }}
|
||||
{{ $releaseIngress := .Release.Ingress }}
|
||||
{{ $releaseName := .Release.Name }}
|
||||
{{- range $ingress := .Values.frontend.ingresses }}
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $ingress.name }}
|
||||
namespace: {{ $namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ $appVersion }}
|
||||
app.kubernetes.io/name: {{ $ingress.name | quote }}
|
||||
app.kubernetes.io/managed-by: {{ $releaseIngress }}
|
||||
app.kubernetes.io/instance: {{ $releaseName }}
|
||||
spec:
|
||||
{{- if $ingress.class }}
|
||||
ingressClassName: {{ $ingress.class }}
|
||||
{{- end }}
|
||||
{{- if $ingress.tls }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ $ingress.host }}
|
||||
{{- if $ingress.tls.exists }}
|
||||
secretName: {{ $ingress.tls.secretRef.name }}
|
||||
{{- else }}
|
||||
secretName: {{ $ingress.tls.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ $ingress.host }}
|
||||
http:
|
||||
paths:
|
||||
{{- range $path := $ingress.rules }}
|
||||
{{ toYaml $path | indent 10 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@ -0,0 +1,10 @@
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: magicleaps-frontend-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
type: Opaque
|
||||
data:
|
||||
TZ: {{ .Values.frontend.configs.tz | b64enc | quote }}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
{{ $namespace := .Release.Namespace }}
|
||||
{{ $appVersion := .Chart.AppVersion | quote }}
|
||||
{{ $releaseService := .Release.Service }}
|
||||
{{ $releaseName := .Release.Name }}
|
||||
{{- range $service := .Values.frontend.services }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $service.name }}
|
||||
namespace: {{ $namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/version: {{ $appVersion }}
|
||||
app.kubernetes.io/name: {{ $service.name | quote }}
|
||||
app.kubernetes.io/managed-by: {{ $releaseService }}
|
||||
app.kubernetes.io/instance: {{ $releaseName }}
|
||||
spec:
|
||||
ports:
|
||||
- port: {{ $service.port }}
|
||||
targetPort: {{ $service.targetPort }}
|
||||
selector:
|
||||
app.kubernetes.io/version: {{ $appVersion }}
|
||||
app.kubernetes.io/name: "frontend"
|
||||
app.kubernetes.io/managed-by: {{ $releaseService }}
|
||||
app.kubernetes.io/instance: {{ $releaseName }}
|
||||
{{- end }}
|
||||
@ -1,24 +0,0 @@
|
||||
{{- if and .Values.backend.enabled .Values.backend.ingress.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Values.backend.name }}-ingress
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
{{- if .Values.backend.ingress.annotations }}
|
||||
{{ .Values.backend.ingress.annotations | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{ include "magicleaps.namespace" . | indent 2 }}
|
||||
spec:
|
||||
rules:
|
||||
- host: {{ .Values.backend.ingress.host }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Values.backend.name }}-svc
|
||||
port:
|
||||
number: {{ .Values.backend.service.port }}
|
||||
{{- end -}}
|
||||
@ -1,24 +0,0 @@
|
||||
{{- if .Values.frontend.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Values.frontend.name }}-ingress
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
{{- if .Values.frontend.ingress.annotations }}
|
||||
{{ .Values.frontend.ingress.annotations | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{ include "magicleaps.namespace" . | indent 2 }}
|
||||
spec:
|
||||
rules:
|
||||
- host: {{ .Values.frontend.ingress.host }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Values.frontend.name }}-svc
|
||||
port:
|
||||
number: {{ .Values.frontend.service.port }}
|
||||
{{- end -}}
|
||||
@ -1,16 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: backend-secrets
|
||||
namespace: magicleaps-alpha
|
||||
type: Opaque
|
||||
data:
|
||||
MONGO_DB: {{ .Values.backend.config.mongo.db | b64enc | quote }}
|
||||
MONGO_HOST: {{ .Values.backend.config.mongo.host | b64enc | quote }}
|
||||
MONGO_PORT: {{ .Values.backend.config.mongo.port | toString | b64enc | quote }}
|
||||
EMAIL_USER: {{ .Values.backend.config.email.user | b64enc | quote }}
|
||||
EMAIL_PASSWORD: {{ .Values.backend.config.email.password | b64enc | quote }}
|
||||
SUPER_ADMIN: {{ .Values.backend.config.superAdmin | b64enc | quote }}
|
||||
TWILIO_ACCOUNT_SID: {{ .Values.backend.config.twilio.accountSid | b64enc | quote }}
|
||||
TWILIO_AUTH_TOKEN: {{ .Values.backend.config.twilio.authToken | b64enc | quote }}
|
||||
LOG_LEVEL: {{ .Values.backend.config.log.level | b64enc | quote }}
|
||||
@ -1,17 +0,0 @@
|
||||
{{- if .Values.backend.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "magicleaps.backend.labels" . | nindent 4 }}
|
||||
name: {{ .Values.backend.name }}-svc
|
||||
{{ include "magicleaps.namespace" . | indent 2 }}
|
||||
spec:
|
||||
ports:
|
||||
- port: {{ .Values.backend.service.port }}
|
||||
targetPort: 8081
|
||||
selector:
|
||||
{{- include "magicleaps.backend.selectorLabels" . | nindent 4 }}
|
||||
sessionAffinity: {{ .Values.backend.service.sessionAffinity }}
|
||||
type: {{ .Values.backend.service.type }}
|
||||
{{- end -}}
|
||||
@ -1,17 +0,0 @@
|
||||
{{- if .Values.frontend.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "magicleaps.frontend.labels" . | nindent 4 }}
|
||||
name: {{ .Values.frontend.name }}-svc
|
||||
{{ include "magicleaps.namespace" . | indent 2 }}
|
||||
spec:
|
||||
ports:
|
||||
- port: {{ .Values.frontend.service.port }}
|
||||
targetPort: 80
|
||||
selector:
|
||||
{{- include "magicleaps.frontend.selectorLabels" . | nindent 4 }}
|
||||
sessionAffinity: {{ .Values.frontend.service.sessionAffinity }}
|
||||
type: {{ .Values.frontend.service.type }}
|
||||
{{- end -}}
|
||||
@ -1,76 +1,110 @@
|
||||
imagePullSecrets:
|
||||
- name: docker-secret
|
||||
backend:
|
||||
enabled: true
|
||||
name: magicleaps-backend
|
||||
image:
|
||||
repository: docker.io/zhenyus
|
||||
name: magicleaps
|
||||
imagePullPolicy: IfNotPresent
|
||||
tag: backend-snapshot-ce69a02-linux-amd64
|
||||
extraEnv: {}
|
||||
port: 8081
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
host: ''
|
||||
replicaCount: 1
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8081
|
||||
sessionAffinity: None
|
||||
resources: {}
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /api/_/probe/liveness
|
||||
port: 8081
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /api/_/probe/readiness
|
||||
port: 8081
|
||||
config:
|
||||
mongo:
|
||||
db: magicleaps_alpha
|
||||
host: mongo-mongodb.magicleaps-alpha.svc.cluster.local
|
||||
port: 27017
|
||||
email:
|
||||
user: your@freeleaps.com
|
||||
password: your-password
|
||||
superAdmin: your@email.com
|
||||
twilio:
|
||||
accountSid: ''
|
||||
authToken: ''
|
||||
log:
|
||||
level: INFO
|
||||
frontend:
|
||||
enabled: true
|
||||
name: magicleaps-frontend
|
||||
image:
|
||||
repository: docker.io/zhenyus
|
||||
name: magicleaps
|
||||
imagePullPolicy: IfNotPresent
|
||||
tag: frontend-snapshot-ce69a02-linux-amd64
|
||||
extraEnv: {}
|
||||
port: 80
|
||||
ingress:
|
||||
annotations: {}
|
||||
host: magicleaps-alpha.wearelsp.com
|
||||
|
||||
global:
|
||||
registry: docker.io
|
||||
repository: sunzhenyucn
|
||||
nodeSelector: {}
|
||||
affinity: {}
|
||||
replicaCount: 1
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
sessionAffinity: None
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /
|
||||
frontend:
|
||||
replicas: 1
|
||||
image:
|
||||
registry:
|
||||
repository: sunzhenyucn
|
||||
name: magicleaps-frontend
|
||||
tag: 1.0.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
resources:
|
||||
requests:
|
||||
cpu: "50m"
|
||||
memory: "128Mi"
|
||||
limits:
|
||||
cpu: "100m"
|
||||
memory: "256Mi"
|
||||
probes:
|
||||
liveness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /
|
||||
port: 8080
|
||||
readiness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /
|
||||
port: 8080
|
||||
services:
|
||||
- name: magicleaps-frontend-service
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
ingresses:
|
||||
- name: magicleaps-frontend-ingress
|
||||
host: alpha.magicleaps.mathmast.com
|
||||
class: nginx
|
||||
rules:
|
||||
- path: /*
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: magicleaps-frontend-service
|
||||
port:
|
||||
number: 80
|
||||
tls:
|
||||
exists: false
|
||||
issuerRef:
|
||||
name: mathmast-dot-com
|
||||
kind: ClusterIssuer
|
||||
name: magicleaps-alpha-frontend-ingress-tls
|
||||
configs:
|
||||
tz: "America/Settle"
|
||||
backend:
|
||||
replicas: 1
|
||||
image:
|
||||
registry:
|
||||
repository: sunzhenyucn
|
||||
name: magicleaps-backend
|
||||
tag: 1.0.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8081
|
||||
protocol: TCP
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "256Mi"
|
||||
limits:
|
||||
cpu: "200m"
|
||||
memory: "512Mi"
|
||||
probes:
|
||||
liveness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /api/_/probe/liveness
|
||||
port: 8081
|
||||
readiness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /api/_/probe/readiness
|
||||
port: 8081
|
||||
services:
|
||||
- name: magicleaps-backend-service
|
||||
type: ClusterIP
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
ingresses:
|
||||
configs:
|
||||
tz: "America/Settle"
|
||||
mongodbHost: "mongodb.magicleaps-alpha.svc.cluster.local"
|
||||
mongodbPort: "27017"
|
||||
mongodbName: "interview"
|
||||
emailUser: "your@freeleaps.com"
|
||||
emailPassword: "your-password"
|
||||
superAdmin: "your@email.com"
|
||||
twilioAccountSid: ""
|
||||
twilioAuthToken: ""
|
||||
eveluationTaskFolderBase: "temp/interview/eveluation_task/"
|
||||
logDir: "logs"
|
||||
appLogFile: "app.log"
|
||||
appLogLevel: "INFO"
|
||||
@ -1,74 +1,110 @@
|
||||
imagePullSecrets:
|
||||
- name: docker-secret
|
||||
backend:
|
||||
enabled: true
|
||||
name: magicleaps-backend
|
||||
image:
|
||||
repository: docker.io/magicleaps
|
||||
name: magicleaps
|
||||
imagePullPolicy: IfNotPresent
|
||||
tag: "backend-snapshot-5e9dea2-linux-amd64"
|
||||
extraEnv: {}
|
||||
port: 8081
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
host: ''
|
||||
replicaCount: 1
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8081
|
||||
sessionAffinity: None
|
||||
resources: {}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/_/probe/liveness
|
||||
port: 8081
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/_/probe/readiness
|
||||
port: 8081
|
||||
config:
|
||||
mongo:
|
||||
db: magicleaps_alpha
|
||||
host: ''
|
||||
port: 27017
|
||||
email:
|
||||
user: ''
|
||||
password: ''
|
||||
superAdmin: ''
|
||||
twilio:
|
||||
accountSid: ''
|
||||
authToken: ''
|
||||
log:
|
||||
level: 'INFO'
|
||||
|
||||
|
||||
frontend:
|
||||
enabled: true
|
||||
name: magicleaps-frontend
|
||||
image:
|
||||
repository: docker.io/magicleaps
|
||||
name: magicleaps
|
||||
imagePullPolicy: IfNotPresent
|
||||
tag: "frontend-snapshot-5e9dea2-linux-amd64"
|
||||
extraEnv: {}
|
||||
port: 80
|
||||
ingress:
|
||||
annotations: {}
|
||||
host: ''
|
||||
global:
|
||||
registry: docker.io
|
||||
repository: sunzhenyucn
|
||||
nodeSelector: {}
|
||||
affinity: {}
|
||||
replicaCount: 1
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
sessionAffinity: None
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
frontend:
|
||||
replicas: 1
|
||||
image:
|
||||
registry:
|
||||
repository: sunzhenyucn
|
||||
name: magicleaps-frontend
|
||||
tag: 1.0.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
resources:
|
||||
requests:
|
||||
cpu: "50m"
|
||||
memory: "128Mi"
|
||||
limits:
|
||||
cpu: "100m"
|
||||
memory: "256Mi"
|
||||
probes:
|
||||
liveness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /
|
||||
port: 8080
|
||||
readiness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /
|
||||
port: 8080
|
||||
services:
|
||||
- name: magicleaps-frontend-service
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
ingresses:
|
||||
- name: magicleaps-frontend-ingress
|
||||
host: alpha.magicleaps.mathmast.com
|
||||
class: nginx
|
||||
rules:
|
||||
- path: /*
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: magicleaps-frontend-service
|
||||
port:
|
||||
number: 80
|
||||
tls:
|
||||
exists: false
|
||||
issuerRef:
|
||||
name: mathmast-dot-com
|
||||
kind: ClusterIssuer
|
||||
name: magicleaps-alpha-frontend-ingress-tls
|
||||
configs:
|
||||
tz: "America/Settle"
|
||||
backend:
|
||||
replicas: 1
|
||||
image:
|
||||
registry:
|
||||
repository: sunzhenyucn
|
||||
name: magicleaps-backend
|
||||
tag: 1.0.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8081
|
||||
protocol: TCP
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "256Mi"
|
||||
limits:
|
||||
cpu: "200m"
|
||||
memory: "512Mi"
|
||||
probes:
|
||||
liveness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /api/_/probe/liveness
|
||||
port: 8081
|
||||
readiness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /api/_/probe/readiness
|
||||
port: 8081
|
||||
services:
|
||||
- name: magicleaps-backend-service
|
||||
type: ClusterIP
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
ingresses:
|
||||
configs:
|
||||
tz: "America/Settle"
|
||||
mongodbHost: "localhost"
|
||||
mongodbPort: "27017"
|
||||
mongodbName: "interview"
|
||||
emailUser: "your@freeleaps.com"
|
||||
emailPassword: "your-password"
|
||||
superAdmin: "your@email.com"
|
||||
twilioAccountSid: ""
|
||||
twilioAuthToken: ""
|
||||
eveluationTaskFolderBase: "temp/interview/eveluation_task/"
|
||||
logDir: "logs"
|
||||
appLogFile: "app.log"
|
||||
appLogLevel: "INFO"
|
||||
@ -102,6 +102,8 @@ type RepositorySpec struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
// Type defines the type of the Git repository
|
||||
Type RepositoryType `json:"type,omitempty"`
|
||||
// Branch defines the branch of the Git repository
|
||||
Branch string `json:"branch,omitempty"`
|
||||
// HookRegister defines the Git repository hook registration
|
||||
HookRegister RepositoryHookRegisterSpec `json:"hookRegister,omitempty"`
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"os"
|
||||
@ -38,6 +39,7 @@ import (
|
||||
|
||||
gitopsv1alpha1 "freeleaps.com/gitops/initializer/api/v1alpha1"
|
||||
"freeleaps.com/gitops/initializer/internal/controller"
|
||||
"freeleaps.com/gitops/initializer/internal/repo"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
@ -145,10 +147,48 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// read configurations from the environment
|
||||
gitopsRepoName := os.Getenv("FREELEAPS_GITOPS_REPO_NAME")
|
||||
gitopsProjectName := os.Getenv("FREELEAPS_GITOPS_PROJECT_NAME")
|
||||
gitopsBranchName := os.Getenv("FREELEAPS_GITOPS_BRANCH_NAME")
|
||||
gitopsRepoPAT := os.Getenv("FREELEAPS_GITOPS_REPO_PAT")
|
||||
gitopsOrganizationUrl := os.Getenv("FREELEAPS_GITOPS_ORGANIZATION_URL")
|
||||
|
||||
if gitopsRepoName == "" || gitopsProjectName == "" || gitopsBranchName == "" || gitopsRepoPAT == "" || gitopsOrganizationUrl == "" {
|
||||
setupLog.Error(nil, "missing environment variables")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// create repo manager
|
||||
repoMgr, ok := repo.GetPlugin("azure-devops")
|
||||
if !ok {
|
||||
setupLog.Error(nil, "repo plugin not found")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// create plugin config
|
||||
pluginConfig := repo.NewPluginConfig()
|
||||
pluginConfig.Set("pat", gitopsRepoPAT)
|
||||
pluginConfig.Set("organizationUrl", gitopsOrganizationUrl)
|
||||
|
||||
// initialize repo manager
|
||||
err = repoMgr.Initialize(context.Background(),
|
||||
repo.WithProject(gitopsProjectName),
|
||||
repo.WithName(gitopsRepoName),
|
||||
repo.WithBranch(gitopsBranchName),
|
||||
repo.WithAuthor("freeleaps-gitops-bot", "gitops@mathmast.com"),
|
||||
repo.WithPluginConfig(pluginConfig),
|
||||
)
|
||||
if err != nil {
|
||||
setupLog.Error(err, "failed to initialize repo manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = (&controller.ProjectInitializeReconciler{
|
||||
Log: ctrl.Log.WithName("controllers").WithName("ProjectInitialize"),
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("ProjectInitialize"),
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
GitOpsRepoManager: repoMgr,
|
||||
}).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "ProjectInitialize")
|
||||
os.Exit(1)
|
||||
|
||||
@ -12,7 +12,6 @@ spec:
|
||||
name: magicleaps-alpha
|
||||
project: magicleaps
|
||||
namespace: magicleaps-alpha
|
||||
branch: develop
|
||||
syncPolicy:
|
||||
automated: true
|
||||
prune: true
|
||||
@ -21,6 +20,7 @@ spec:
|
||||
plugins: azure-devops
|
||||
project: magicleaps
|
||||
name: magicleaps
|
||||
branch: develop
|
||||
pluginConfig:
|
||||
organizationUrl: https://dev.azure.com/freeleaps
|
||||
pat: 3E9J1v0si6HRvyc1RSRgT791W9ZvMi4kBmrznfcIXB8mq6Trj9VkJQQJ99BBACAAAAArj0WRAAASAZDO32n4
|
||||
|
||||
@ -31,14 +31,16 @@ import (
|
||||
gitopsv1alpha1 "freeleaps.com/gitops/initializer/api/v1alpha1"
|
||||
"freeleaps.com/gitops/initializer/internal/helm"
|
||||
"freeleaps.com/gitops/initializer/internal/metrics"
|
||||
"freeleaps.com/gitops/initializer/internal/repo"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
// ProjectInitializeReconciler reconciles a ProjectInitialize object
|
||||
type ProjectInitializeReconciler struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
Log logr.Logger
|
||||
Scheme *runtime.Scheme
|
||||
Log logr.Logger
|
||||
GitOpsRepoManager repo.RepoManager
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups=gitops.freeleaps.com,resources=projectinitializes,verbs=get;list;watch;create;update;patch;delete
|
||||
@ -107,6 +109,8 @@ func (r *ProjectInitializeReconciler) Reconcile(ctx context.Context, req ctrl.Re
|
||||
}
|
||||
}
|
||||
|
||||
// reconcile Jenkinsfile for the ProjectInitialize instance
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
@ -139,6 +143,31 @@ func (r *ProjectInitializeReconciler) reconcileHelmPackage(ctx context.Context,
|
||||
return err
|
||||
}
|
||||
|
||||
requests := make([]repo.ChangeRequest, 0)
|
||||
|
||||
// commit generated files to gitops repo
|
||||
err = generator.Walk(func(f *helm.HelmGeneratedFile) error {
|
||||
if blob, err := f.ReadAll(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
req := repo.ChangeRequest{
|
||||
Path: fmt.Sprintf("%s/helm-pkg/%s", cr.ObjectMeta.GetName(), f.QualifiedPath),
|
||||
Content: blob,
|
||||
Operation: repo.OpCreate,
|
||||
}
|
||||
requests = append(requests, req)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// apply changes to gitops repo
|
||||
if err := r.GitOpsRepoManager.ApplyChanges(ctx, requests, "chore(freeleaps-gitios-initializer): commit generated helm package"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"freeleaps.com/gitops/initializer/api/v1alpha1"
|
||||
@ -18,6 +19,7 @@ type HelmGenerator struct {
|
||||
io.Closer
|
||||
Instance *v1alpha1.ProjectInitialize
|
||||
workingDir string
|
||||
generated bool
|
||||
}
|
||||
|
||||
const leftDelim = "[["
|
||||
@ -205,9 +207,36 @@ func (hg *HelmGenerator) Generate() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
hg.generated = true
|
||||
return nil
|
||||
}
|
||||
|
||||
type HelmGeneratedFile struct {
|
||||
QualifiedPath string
|
||||
}
|
||||
|
||||
func (hgf *HelmGeneratedFile) ReadAll() ([]byte, error) {
|
||||
return os.ReadFile(hgf.QualifiedPath)
|
||||
}
|
||||
|
||||
type HelmGeneratedFileCallback func(f *HelmGeneratedFile) error
|
||||
|
||||
func (hg *HelmGenerator) Walk(cb HelmGeneratedFileCallback) error {
|
||||
if !hg.generated {
|
||||
return errors.New("helm package not generated")
|
||||
}
|
||||
|
||||
return filepath.Walk(hg.workingDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return cb(&HelmGeneratedFile{QualifiedPath: path})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (hg *HelmGenerator) Close() error {
|
||||
if hg.workingDir != "" {
|
||||
return os.RemoveAll(hg.workingDir)
|
||||
|
||||
@ -0,0 +1,261 @@
|
||||
package helm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"freeleaps.com/gitops/initializer/api/v1alpha1"
|
||||
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var pathType = networkingv1.PathTypeImplementationSpecific
|
||||
|
||||
var testCase = v1alpha1.ProjectInitialize{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "magicleaps-alpha",
|
||||
},
|
||||
Spec: v1alpha1.ProjectInitializeSpec{
|
||||
Repository: &v1alpha1.RepositorySpec{
|
||||
Plugin: "azure-devops",
|
||||
PluginConfig: map[string]string{
|
||||
"pat": "3E9J1v0si6HRvyc1RSRgT791W9ZvMi4kBmrznfcIXB8mq6Trj9VkJQQJ99BBACAAAAArj0WRAAASAZDO32n4",
|
||||
"organizationUrl": "https://dev.azure.com/freeleaps",
|
||||
},
|
||||
RegisterToArgo: true,
|
||||
Project: "magicleaps",
|
||||
Name: "magicleaps",
|
||||
Type: v1alpha1.Monorepo,
|
||||
Branch: "develop",
|
||||
},
|
||||
Helm: &v1alpha1.HelmSpec{
|
||||
Generate: true,
|
||||
Metadata: v1alpha1.HelmMetadataSpec{
|
||||
Name: "magicleaps",
|
||||
Description: "A Helm Chart of magicleaps, powered by Freeleaps.",
|
||||
},
|
||||
Global: v1alpha1.HelmGlobalValuesSpec{
|
||||
Registry: "docker.io",
|
||||
Repository: "sunzhenyucn",
|
||||
},
|
||||
Components: []v1alpha1.HelmComponentSpec{
|
||||
{
|
||||
Name: "frontend",
|
||||
Ports: []corev1.ContainerPort{
|
||||
{
|
||||
Name: "http",
|
||||
ContainerPort: 8080,
|
||||
Protocol: corev1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
Replicas: 1,
|
||||
Resources: v1alpha1.HelmComponentResourceRequirementsSpec{
|
||||
Limits: v1alpha1.HelmComponentResourceSettingSpec{
|
||||
CPU: "100m",
|
||||
Memory: "256Mi",
|
||||
},
|
||||
Requests: v1alpha1.HelmComponentResourceSettingSpec{
|
||||
CPU: "50m",
|
||||
Memory: "128Mi",
|
||||
},
|
||||
},
|
||||
Image: v1alpha1.HelmComponentImageSpec{
|
||||
Repository: "sunzhenyucn",
|
||||
Name: "magicleaps-frontend",
|
||||
Tag: "1.0.0",
|
||||
ImagePullPolicy: corev1.PullIfNotPresent,
|
||||
},
|
||||
Probes: v1alpha1.HelmComponentProbesSpec{
|
||||
Liveness: v1alpha1.HelmComponentProbeSpec{
|
||||
Type: v1alpha1.HTTPGet,
|
||||
Config: v1alpha1.HelmComponentProbeConfigSpec{
|
||||
Path: "/",
|
||||
Port: 8080,
|
||||
},
|
||||
},
|
||||
Readiness: v1alpha1.HelmComponentProbeSpec{
|
||||
Type: v1alpha1.HTTPGet,
|
||||
Config: v1alpha1.HelmComponentProbeConfigSpec{
|
||||
Path: "/",
|
||||
Port: 8080,
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: []v1alpha1.HelmComponentServiceSpec{
|
||||
{
|
||||
Name: "magicleaps-frontend-service",
|
||||
Type: corev1.ServiceTypeClusterIP,
|
||||
Port: 80,
|
||||
TargetPort: 8080,
|
||||
},
|
||||
},
|
||||
Ingresses: []v1alpha1.HelmComponentIngressSpec{
|
||||
{
|
||||
Name: "magicleaps-frontend-ingress",
|
||||
Class: "nginx",
|
||||
Host: "alpha.magicleaps.mathmast.com",
|
||||
Rules: []networkingv1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/*",
|
||||
PathType: &pathType,
|
||||
Backend: networkingv1.IngressBackend{
|
||||
Service: &networkingv1.IngressServiceBackend{
|
||||
Name: "magicleaps-frontend-service",
|
||||
Port: networkingv1.ServiceBackendPort{
|
||||
Number: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: v1alpha1.HelmComponentIngressTLSSpec{
|
||||
Exists: false,
|
||||
Name: "magicleaps-alpha-frontend-ingress-tls",
|
||||
IssuerRef: &cmmeta.ObjectReference{
|
||||
Name: "mathmast-dot-com",
|
||||
Kind: "ClusterIssuer",
|
||||
Group: "cert-manager.io",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Configs: []v1alpha1.HelmComponentConfigSpec{
|
||||
{
|
||||
Name: "magicleaps-frontend-config",
|
||||
Type: v1alpha1.EnvironmentSecret,
|
||||
Data: []corev1.EnvVar{
|
||||
{
|
||||
Name: "TZ",
|
||||
Value: "America/Settle",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "backend",
|
||||
Ports: []corev1.ContainerPort{
|
||||
{
|
||||
Name: "http",
|
||||
ContainerPort: 8081,
|
||||
Protocol: corev1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
Replicas: 1,
|
||||
Resources: v1alpha1.HelmComponentResourceRequirementsSpec{
|
||||
Limits: v1alpha1.HelmComponentResourceSettingSpec{
|
||||
CPU: "200m",
|
||||
Memory: "512Mi",
|
||||
},
|
||||
Requests: v1alpha1.HelmComponentResourceSettingSpec{
|
||||
CPU: "100m",
|
||||
Memory: "256Mi",
|
||||
},
|
||||
},
|
||||
Image: v1alpha1.HelmComponentImageSpec{
|
||||
Repository: "sunzhenyucn",
|
||||
Name: "magicleaps-backend",
|
||||
Tag: "1.0.0",
|
||||
ImagePullPolicy: corev1.PullIfNotPresent,
|
||||
},
|
||||
Probes: v1alpha1.HelmComponentProbesSpec{
|
||||
Liveness: v1alpha1.HelmComponentProbeSpec{
|
||||
Type: v1alpha1.HTTPGet,
|
||||
Config: v1alpha1.HelmComponentProbeConfigSpec{
|
||||
Path: "/api/_/probe/liveness",
|
||||
Port: 8081,
|
||||
},
|
||||
},
|
||||
Readiness: v1alpha1.HelmComponentProbeSpec{
|
||||
Type: v1alpha1.HTTPGet,
|
||||
Config: v1alpha1.HelmComponentProbeConfigSpec{
|
||||
Path: "/api/_/probe/readiness",
|
||||
Port: 8081,
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: []v1alpha1.HelmComponentServiceSpec{
|
||||
{
|
||||
Name: "magicleaps-backend-service",
|
||||
Type: corev1.ServiceTypeClusterIP,
|
||||
Port: 8081,
|
||||
TargetPort: 8081,
|
||||
},
|
||||
},
|
||||
Ingresses: []v1alpha1.HelmComponentIngressSpec{},
|
||||
Configs: []v1alpha1.HelmComponentConfigSpec{
|
||||
{
|
||||
Name: "magicleaps-backend-config",
|
||||
Type: v1alpha1.EnvironmentSecret,
|
||||
Data: []corev1.EnvVar{
|
||||
{
|
||||
Name: "TZ",
|
||||
Value: "America/Settle",
|
||||
},
|
||||
{
|
||||
Name: "MONGODB_HOST",
|
||||
Value: "localhost",
|
||||
},
|
||||
{
|
||||
Name: "MONGODB_PORT",
|
||||
Value: "27017",
|
||||
},
|
||||
{
|
||||
Name: "MONGODB_NAME",
|
||||
Value: "interview",
|
||||
},
|
||||
{
|
||||
Name: "EMAIL_USER",
|
||||
Value: "your@freeleaps.com",
|
||||
},
|
||||
{
|
||||
Name: "EMAIL_PASSWORD",
|
||||
Value: "your-password",
|
||||
},
|
||||
{
|
||||
Name: "SUPER_ADMIN",
|
||||
Value: "your@email.com",
|
||||
},
|
||||
{
|
||||
Name: "TWILIO_ACCOUNT_SID",
|
||||
Value: "",
|
||||
},
|
||||
{
|
||||
Name: "TWILIO_AUTH_TOKEN",
|
||||
Value: "",
|
||||
},
|
||||
{
|
||||
Name: "EVELUATION_TASK_FOLDER_BASE",
|
||||
Value: "temp/interview/eveluation_task/",
|
||||
},
|
||||
{
|
||||
Name: "LOG_DIR",
|
||||
Value: "logs",
|
||||
},
|
||||
{
|
||||
Name: "APP_LOG_FILE",
|
||||
Value: "app.log",
|
||||
},
|
||||
{
|
||||
Name: "APP_LOG_LEVEL",
|
||||
Value: "INFO",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
gen := &HelmGenerator{
|
||||
Instance: &testCase,
|
||||
}
|
||||
if err := gen.Generate(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
@ -1,109 +0,0 @@
|
||||
global:
|
||||
registry: docker.io
|
||||
repository: test
|
||||
nodeSelector:
|
||||
beta.kubernetes.io/os: linux
|
||||
frontend:
|
||||
replicas: 1
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: test
|
||||
name: frontend
|
||||
tag: latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
limits:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
probes:
|
||||
liveness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
readiness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /readyz
|
||||
port: 8080
|
||||
services:
|
||||
- name: frontend
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
ingresses:
|
||||
- name: frontend
|
||||
host: test.com
|
||||
class: nginx
|
||||
rules:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: frontend
|
||||
port:
|
||||
number: 8080
|
||||
tls:
|
||||
exists: false
|
||||
issuerRef:
|
||||
name: test-issuer
|
||||
kind: ClusterIssuer
|
||||
name: test-cert
|
||||
configs:
|
||||
testEnvVar: "test"
|
||||
mongoDb: "mongodb"
|
||||
backend:
|
||||
replicas: 1
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: test
|
||||
name: backend
|
||||
tag: latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
limits:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
probes:
|
||||
liveness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
readiness:
|
||||
type: httpGet
|
||||
config:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
services:
|
||||
- name: backend
|
||||
type: ClusterIP
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
ingresses:
|
||||
- name: backend
|
||||
host: test.com
|
||||
class: nginx
|
||||
rules:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: backend
|
||||
port:
|
||||
number: 8080
|
||||
tls:
|
||||
exists: false
|
||||
issuerRef:
|
||||
name: test-issuer
|
||||
kind: ClusterIssuer
|
||||
name: test-cert
|
||||
configs:
|
||||
testEnvVar1: "test"
|
||||
mongoDb1: "mongodb"
|
||||
@ -0,0 +1,96 @@
|
||||
package jenkins
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"freeleaps.com/gitops/initializer/api/v1alpha1"
|
||||
)
|
||||
|
||||
//go:embed templates/*
|
||||
var embeddedTemplates embed.FS
|
||||
|
||||
type JenkinsfileGenerator struct {
|
||||
io.Closer
|
||||
Instance *v1alpha1.ProjectInitialize
|
||||
workingDir string
|
||||
generated bool
|
||||
}
|
||||
|
||||
const leftDelim = "[["
|
||||
const rightDelim = "]]"
|
||||
|
||||
func (jg *JenkinsfileGenerator) prepareWorkingDir() error {
|
||||
path, err := os.MkdirTemp("", fmt.Sprintf("jenkinsfile-gen-%s-*", jg.Instance.Name))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create jenkinsfile generator temp dir: %w", err)
|
||||
}
|
||||
jg.workingDir = path
|
||||
return nil
|
||||
}
|
||||
|
||||
func (jg *JenkinsfileGenerator) readTemplate(name string) (*template.Template, error) {
|
||||
tpl := template.New(name)
|
||||
templateBytes, err := embeddedTemplates.ReadFile(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read template %s: %w", name, err)
|
||||
}
|
||||
tpl, err = tpl.
|
||||
Delims(leftDelim, rightDelim).
|
||||
Parse(string(templateBytes))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse template %s: %w", name, err)
|
||||
}
|
||||
return tpl, nil
|
||||
}
|
||||
|
||||
func (jg *JenkinsfileGenerator) Generate() error {
|
||||
if jg.Instance == nil {
|
||||
return fmt.Errorf("instance is nil")
|
||||
}
|
||||
|
||||
if err := jg.prepareWorkingDir(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tpl, err := jg.readTemplate("templates/Jenkinsfile.tpl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jenkinsfileFd, err := os.Create(jg.workingDir + "/Jenkinsfile")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Jenkinsfile: %w", err)
|
||||
}
|
||||
defer jenkinsfileFd.Close()
|
||||
|
||||
if err := tpl.Execute(jenkinsfileFd, jg.Instance.Spec); err != nil {
|
||||
return fmt.Errorf("failed to render Jenkinsfile with template: %w", err)
|
||||
}
|
||||
jg.generated = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (jg *JenkinsfileGenerator) Close() error {
|
||||
if jg.workingDir != "" {
|
||||
return os.RemoveAll(jg.workingDir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (jg *JenkinsfileGenerator) ReadGeneratedJenkinsfile() ([]byte, error) {
|
||||
if !jg.generated {
|
||||
return nil, fmt.Errorf("jenkinsfile not generated")
|
||||
}
|
||||
|
||||
jenkinsfileBytes, err := os.ReadFile(jg.workingDir + "/Jenkinsfile")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read generated Jenkinsfile: %w", err)
|
||||
}
|
||||
|
||||
return jenkinsfileBytes, nil
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
library 'first-class-pipeline'
|
||||
|
||||
executeFreeleapsPipeline {
|
||||
serviceName = [[ .ServiceName | quote ]]
|
||||
environmentSlug = [[ .EnvironmentSlug | quote ]]
|
||||
serviceGitBranch = [[ .Spec.Repository.Branch | quote ]]
|
||||
serviceGitRepo = [[ .GitRepoURL | quote ]]
|
||||
serviceGitRepoType = [[ .Spec.Repository.Type | quote ]]
|
||||
serviceGitCredentialsId = [[ .JenkinsGitCredentialsId | quote ]]
|
||||
executeMode = [[ .Spec.ContinuousIntegrationSpec.ExecuteMode | quote ]]
|
||||
commitMessageLintEnabled = [[ .Spec.ContinuousIntegrationSpec.CommitMessageLintEnabled ]]
|
||||
components = [
|
||||
[[- range $component := .Spec.ContinuousIntegrationSpec.Components ]]
|
||||
[
|
||||
name: [[ $component.Name | quote ]],
|
||||
root: [[ $component.Root | quote ]],
|
||||
language: [[ $component.Language | quote ]],
|
||||
dependenciesManager: [[ $component.DependenciesManager | quote ]],
|
||||
[[- if and (eq $component.DependenciesManager "npm") ($component.NPMPackageJsonFile) ]]
|
||||
npmPackageJsonFile: [[ $component.NPMPackageJsonFile | quote ]],
|
||||
[[- end ]]
|
||||
[[- if $component.BuildCacheEnabled ]]
|
||||
buildCacheEnabled: [[ $component.BuildCacheEnabled ]],
|
||||
[[- end ]]
|
||||
]
|
||||
[[- end ]]
|
||||
]
|
||||
}
|
||||
@ -7,9 +7,11 @@ import (
|
||||
|
||||
var (
|
||||
pluginsMu sync.RWMutex
|
||||
plugins = make(map[string]RepoManager)
|
||||
plugins = make(map[string]PluginCreateFunc)
|
||||
)
|
||||
|
||||
type PluginCreateFunc func() RepoManager
|
||||
|
||||
type PluginConfig interface {
|
||||
Get(key string) (any, error)
|
||||
Set(key string, value any)
|
||||
@ -37,25 +39,25 @@ func NewPluginConfig() PluginConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterPlugin(name string, plugin RepoManager) {
|
||||
func RegisterPlugin(name string, fun PluginCreateFunc) {
|
||||
pluginsMu.Lock()
|
||||
defer pluginsMu.Unlock()
|
||||
|
||||
if plugin == nil {
|
||||
panic("plugin cannot be nil")
|
||||
if fun == nil {
|
||||
panic("plugin create func cannot be nil")
|
||||
}
|
||||
|
||||
if old, exists := plugins[name]; exists {
|
||||
fmt.Printf("WARNING: plugin '%s' already registered (%T), overwriting\n", name, old)
|
||||
}
|
||||
|
||||
plugins[name] = plugin
|
||||
plugins[name] = fun
|
||||
}
|
||||
|
||||
func GetPlugin(name string) (RepoManager, bool) {
|
||||
pluginsMu.RLock()
|
||||
defer pluginsMu.RUnlock()
|
||||
|
||||
plugin, exists := plugins[name]
|
||||
return plugin, exists
|
||||
fun, exists := plugins[name]
|
||||
return fun(), exists
|
||||
}
|
||||
|
||||
@ -19,7 +19,9 @@ type AzureDevOpsRepoManager struct {
|
||||
var _ repo.RepoManager = &AzureDevOpsRepoManager{}
|
||||
|
||||
func init() {
|
||||
repo.RegisterPlugin("azure-devops", &AzureDevOpsRepoManager{})
|
||||
repo.RegisterPlugin("azure-devops", func() repo.RepoManager {
|
||||
return &AzureDevOpsRepoManager{}
|
||||
})
|
||||
}
|
||||
|
||||
// Initialize implements repo.RepoManager.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user