mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 16:54:58 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31d1086345 | ||
|
|
b737543c13 | ||
|
|
8e150ee0d7 | ||
|
|
117a2a886d | ||
|
|
79b41dfbf5 | ||
|
|
55562f9d83 | ||
|
|
e0a636f183 | ||
|
|
1fa74214cf | ||
|
|
e5851cac57 | ||
|
|
4a26662b92 | ||
|
|
6bc6888ffc | ||
|
|
dab1f305e1 | ||
|
|
fbe79dd0af | ||
|
|
6d6829b149 | ||
|
|
971a3fa280 | ||
|
|
7632344cd1 | ||
|
|
42067748ad | ||
|
|
340c3484e5 | ||
|
|
250238c286 | ||
|
|
a223e2b426 | ||
|
|
63a7da02e7 | ||
|
|
569f827e30 | ||
|
|
4a656db2ec | ||
|
|
77b0933961 | ||
|
|
3b796cfbbd |
@@ -19,7 +19,11 @@ let Kustomization = ks.#Kustomization & {
|
||||
// Kustomize the intermediate build plan resources.
|
||||
BuildPlanResources,
|
||||
// Mix-in external resources.
|
||||
"https://github.com/argoproj/argo-cd//manifests/crds/?ref=v\(#ArgoCD.Version)",
|
||||
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/application-crd.yaml",
|
||||
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/applicationset-crd.yaml",
|
||||
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/appproject-crd.yaml",
|
||||
// This method also works, but takes about 5 seconds longer each build.
|
||||
// "https://github.com/argoproj/argo-cd//manifests/crds/?ref=v\(#ArgoCD.Version)",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package holos
|
||||
|
||||
// Manage on workload clusters only
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
// Owned by the security team
|
||||
#Platform: Components: "\(Cluster.name)/bank-secrets": {
|
||||
path: "projects/bank-of-holos/security/components/bank-secrets"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
|
||||
// Owned by the frontend team
|
||||
#Platform: Components: "\(Cluster.name)/bank-frontend": {
|
||||
path: "projects/bank-of-holos/frontend/components/bank-frontend"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
|
||||
// Owned by the backend team
|
||||
#Platform: Components: "\(Cluster.name)/bank-backend-config": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-backend-config"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-accounts-db": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-accounts-db"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-userservice": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-userservice"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
|
||||
#Platform: Components: "\(Cluster.name)/bank-ledger-db": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-ledger-db"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-ledger-writer": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-ledger-writer"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-balance-reader": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-balance-reader"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-transaction-history": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-transaction-history"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-contacts": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-contacts"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package holos
|
||||
|
||||
// Platform wide definitions
|
||||
#BankOfHolos: {
|
||||
Name: "bank-of-holos"
|
||||
Frontend: Namespace: "bank-frontend"
|
||||
Backend: Namespace: "bank-backend"
|
||||
Security: Namespace: "bank-security"
|
||||
|
||||
// Resources to manage in each of the namespaces.
|
||||
Resources: #Resources
|
||||
}
|
||||
|
||||
// Register namespaces
|
||||
#Namespaces: (#BankOfHolos.Frontend.Namespace): _
|
||||
#Namespaces: (#BankOfHolos.Backend.Namespace): _
|
||||
#Namespaces: (#BankOfHolos.Security.Namespace): _
|
||||
|
||||
// Register projects
|
||||
#AppProjects: "bank-frontend": _
|
||||
#AppProjects: "bank-backend": _
|
||||
#AppProjects: "bank-security": _
|
||||
|
||||
// Register HTTPRoutes.
|
||||
// bank.example.com routes to Service frontend in the bank-frontend namespace.
|
||||
#HTTPRoutes: bank: _backendRefs: frontend: namespace: #BankOfHolos.Frontend.Namespace
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: AppProject: #AppProjects["bank-backend"].metadata.name
|
||||
@@ -0,0 +1,122 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "accounts"
|
||||
tier: "db"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-accounts-db"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/accounts-db.yaml
|
||||
Resources: {
|
||||
ConfigMap: "accounts-db-config": {
|
||||
apiVersion: "v1"
|
||||
data: {
|
||||
ACCOUNTS_DB_URI: "postgresql://accounts-admin:accounts-pwd@accounts-db:5432/accounts-db"
|
||||
POSTGRES_DB: "accounts-db"
|
||||
POSTGRES_PASSWORD: "accounts-pwd"
|
||||
POSTGRES_USER: "accounts-admin"
|
||||
}
|
||||
kind: "ConfigMap"
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
name: "accounts-db-config"
|
||||
}
|
||||
}
|
||||
|
||||
Service: "accounts-db": {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "accounts-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "tcp"
|
||||
port: 5432
|
||||
protocol: "TCP"
|
||||
targetPort: 5432
|
||||
}]
|
||||
selector: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
StatefulSet: "accounts-db": {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "StatefulSet"
|
||||
metadata: {
|
||||
name: "accounts-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
replicas: 1
|
||||
selector: matchLabels: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
serviceName: "accounts-db"
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "accounts-db-config"
|
||||
}, {
|
||||
configMapRef: name: "demo-data-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/accounts-db:v0.6.5@sha256:abb955756a82b115e0fd9c5fa1527ae1a744b398b357fd6d7a26348feccad181"
|
||||
name: "accounts-db"
|
||||
ports: [{containerPort: 5432}]
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/var/lib/postgresql/data"
|
||||
name: "postgresdb"
|
||||
subPath: "postgres"
|
||||
}]
|
||||
}]
|
||||
serviceAccount: BankName
|
||||
serviceAccountName: BankName
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "postgresdb"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-backend-config"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/userservice.yaml
|
||||
Resources: {
|
||||
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
|
||||
// in this namespace.
|
||||
ReferenceGrant: grant: #ReferenceGrant & {
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
|
||||
// Include shared resources
|
||||
#BankOfHolos.Resources
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-balance-reader"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: balancereader: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "balancereader"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "balancereader"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: balancereader: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: {
|
||||
name: "balancereader"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "balancereader"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "balancereader"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "ENABLE_METRICS"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "POLL_MS"
|
||||
value: "100"
|
||||
}, {
|
||||
name: "CACHE_SIZE"
|
||||
value: "1000000"
|
||||
}, {
|
||||
name: "JVM_OPTS"
|
||||
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "NAMESPACE"
|
||||
valueFrom: fieldRef: fieldPath: "metadata.namespace"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/balancereader:v0.6.5@sha256:de01f16554ae2d0b49ac85116e6307da8c0f8a35f50a0cf25e1e4a4fe18dca83"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 120
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
name: "balancereader"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
startupProbe: {
|
||||
failureThreshold: 30
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
periodSeconds: 10
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "accounts"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-contacts"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: contacts: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: name: "contacts"
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "contacts"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: contacts: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: name: "contacts"
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "contacts"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "contacts"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "accounts-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/contacts:v0.6.5@sha256:e451dcac7d34a7bde979c7f02d4c7ebd83a77aff373e1131ce3a2bba2f7fdc1a"
|
||||
name: "contacts"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "128Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "64Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "db"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-ledger-db"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
ConfigMap: "ledger-db-config": {
|
||||
apiVersion: "v1"
|
||||
metadata: {
|
||||
name: "ledger-db-config"
|
||||
labels: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
data: {
|
||||
POSTGRES_DB: "postgresdb"
|
||||
POSTGRES_PASSWORD: "password"
|
||||
POSTGRES_USER: "admin"
|
||||
SPRING_DATASOURCE_PASSWORD: "password"
|
||||
SPRING_DATASOURCE_URL: "jdbc:postgresql://ledger-db:5432/postgresdb"
|
||||
SPRING_DATASOURCE_USERNAME: "admin"
|
||||
}
|
||||
}
|
||||
|
||||
Service: "ledger-db": {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "ledger-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "tcp"
|
||||
port: 5432
|
||||
targetPort: 5432
|
||||
}]
|
||||
selector: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
StatefulSet: "ledger-db": {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "StatefulSet"
|
||||
metadata: {
|
||||
name: "ledger-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
replicas: 1
|
||||
selector: matchLabels: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
serviceName: "ledger-db"
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}, {
|
||||
configMapRef: name: "demo-data-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/ledger-db:v0.6.5@sha256:cc4fd25f301ab6d46b1312244d6931babc4c6cb66c5cb6d31d4a1adfa318a321"
|
||||
name: "postgres"
|
||||
ports: [{containerPort: 5432}]
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "1Gi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "512Mi"
|
||||
}
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/var/lib/postgresql/data"
|
||||
name: "postgresdb"
|
||||
subPath: "postgres"
|
||||
}]
|
||||
}]
|
||||
serviceAccountName: BankName
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "postgresdb"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-ledger-writer"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: ledgerwriter: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "ledgerwriter"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "ledgerwriter"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: ledgerwriter: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: {
|
||||
name: "ledgerwriter"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "ledgerwriter"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "ledgerwriter"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "ENABLE_METRICS"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "JVM_OPTS"
|
||||
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "NAMESPACE"
|
||||
valueFrom: fieldRef: fieldPath: "metadata.namespace"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "service-api-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/ledgerwriter:v0.6.5@sha256:5b66d6888b87993c8ebe260fe33005c4e4bc2bdae4b5682874e1a078d37ff3b2"
|
||||
name: "ledgerwriter"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
startupProbe: {
|
||||
failureThreshold: 30
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
periodSeconds: 10
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-transaction-history"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: transactionhistory: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
labels: CommonLabels
|
||||
name: "transactionhistory"
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "transactionhistory"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: transactionhistory: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: {
|
||||
name: "transactionhistory"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "transactionhistory"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "transactionhistory"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "ENABLE_METRICS"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "POLL_MS"
|
||||
value: "100"
|
||||
}, {
|
||||
name: "CACHE_SIZE"
|
||||
value: "1000"
|
||||
}, {
|
||||
name: "CACHE_MINUTES"
|
||||
value: "60"
|
||||
}, {
|
||||
name: "HISTORY_LIMIT"
|
||||
value: "100"
|
||||
}, {
|
||||
name: "JVM_OPTS"
|
||||
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "NAMESPACE"
|
||||
valueFrom: fieldRef: fieldPath: "metadata.namespace"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/transactionhistory:v0.6.5@sha256:54a2b0866df44a50832e71b130f3e069fe8bbce71309fb6cf390b19f64d92c09"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 120
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
name: "transactionhistory"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
startupProbe: {
|
||||
failureThreshold: 30
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
periodSeconds: 10
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "accounts"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-userservice"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/userservice.yaml
|
||||
Resources: {
|
||||
Service: userservice: {
|
||||
metadata: name: "userservice"
|
||||
metadata: labels: CommonLabels
|
||||
spec: {
|
||||
selector: {
|
||||
app: "userservice"
|
||||
CommonLabels
|
||||
}
|
||||
_ports: http: {
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: "TCP"
|
||||
}
|
||||
ports: [for x in _ports {x}]
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: userservice: {
|
||||
metadata: name: "userservice"
|
||||
metadata: labels: CommonLabels
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "userservice"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "userservice"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "TOKEN_EXPIRY_SECONDS"
|
||||
value: "3600"
|
||||
}, {
|
||||
name: "PRIV_KEY_PATH"
|
||||
value: "/tmp/.ssh/privatekey"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "accounts-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/userservice:v0.6.5@sha256:f91e0e5bd6cdb16f6b867b2e3e874b23dd01f11592de006776f1dfb136702941"
|
||||
name: "userservice"
|
||||
ports: [{
|
||||
containerPort: 8080
|
||||
name: "http-server"
|
||||
}]
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "260m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "128Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "keys"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "keys"
|
||||
secret: {
|
||||
secretName: "jwt-key"
|
||||
items: [
|
||||
{
|
||||
key: "jwtRS256.key"
|
||||
path: "privatekey"
|
||||
},
|
||||
{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
},
|
||||
]
|
||||
}
|
||||
}]
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
core "k8s.io/api/core/v1"
|
||||
es "external-secrets.io/externalsecret/v1beta1"
|
||||
ss "external-secrets.io/secretstore/v1beta1"
|
||||
)
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
#BankOfHolos: {
|
||||
// Resources to make available in each of the project namespaces.
|
||||
Resources: {
|
||||
ServiceAccount: (BankName): core.#ServiceAccount & {
|
||||
apiVersion: "v1"
|
||||
kind: "ServiceAccount"
|
||||
metadata: name: BankName
|
||||
}
|
||||
|
||||
// SecretStore to fetch secrets owned by the security team
|
||||
SecretStore: (BankName): ss.#SecretStore & {
|
||||
metadata: name: #BankOfHolos.Security.Namespace
|
||||
spec: provider: {
|
||||
kubernetes: {
|
||||
remoteNamespace: #BankOfHolos.Security.Namespace
|
||||
auth: serviceAccount: name: ServiceAccount[BankName].metadata.name
|
||||
server: {
|
||||
url: "https://kubernetes.default.svc"
|
||||
caProvider: {
|
||||
type: "ConfigMap"
|
||||
name: "kube-root-ca.crt"
|
||||
key: "ca.crt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We do not check the private key into version control.
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/tree/v0.6.5/extras/jwt
|
||||
ExternalSecret: "jwt-key": es.#ExternalSecret & {
|
||||
metadata: name: "jwt-key"
|
||||
spec: {
|
||||
target: name: metadata.name
|
||||
dataFrom: [{extract: {key: metadata.name}}]
|
||||
refreshInterval: "5s"
|
||||
secretStoreRef: kind: "SecretStore"
|
||||
secretStoreRef: name: SecretStore[BankName].metadata.name
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/config.yaml
|
||||
ConfigMap: "environment-config": core.#ConfigMap & {
|
||||
apiVersion: "v1"
|
||||
kind: "ConfigMap"
|
||||
metadata: name: "environment-config"
|
||||
data: {
|
||||
LOCAL_ROUTING_NUM: "883745000"
|
||||
PUB_KEY_PATH: "/tmp/.ssh/publickey"
|
||||
}
|
||||
}
|
||||
|
||||
ConfigMap: "service-api-config": core.#ConfigMap & {
|
||||
apiVersion: "v1"
|
||||
kind: "ConfigMap"
|
||||
metadata: name: "service-api-config"
|
||||
data: {
|
||||
TRANSACTIONS_API_ADDR: "ledgerwriter.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
BALANCES_API_ADDR: "balancereader.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
HISTORY_API_ADDR: "transactionhistory.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
CONTACTS_API_ADDR: "contacts.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
USERSERVICE_API_ADDR: "userservice.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
}
|
||||
}
|
||||
|
||||
ConfigMap: "demo-data-config": core.#ConfigMap & {
|
||||
apiVersion: "v1"
|
||||
kind: "ConfigMap"
|
||||
metadata: name: "demo-data-config"
|
||||
data: {
|
||||
USE_DEMO_DATA: "True"
|
||||
DEMO_LOGIN_USERNAME: "testuser"
|
||||
// All demo user accounts are hardcoded to use the login password 'bankofanthos'
|
||||
DEMO_LOGIN_PASSWORD: "bankofanthos"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-frontend"
|
||||
Namespace: #BankOfHolos.Frontend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/frontend.yaml
|
||||
Resources: {
|
||||
Service: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
_ports: http: {
|
||||
name: "http"
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: "TCP"
|
||||
}
|
||||
ports: [for x in _ports {x}]
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: "bank-of-holos"
|
||||
terminationGracePeriodSeconds: 5
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "BANK_NAME"
|
||||
value: "Bank of Holos"
|
||||
}, {
|
||||
name: "ENV_PLATFORM"
|
||||
value: "local"
|
||||
}, {
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "SCHEME"
|
||||
value: "https"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "DEFAULT_USERNAME"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_USERNAME"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "DEFAULT_PASSWORD"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_PASSWORD"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "REGISTERED_OAUTH_CLIENT_ID"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_CLIENT_ID"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}, {
|
||||
name: "ALLOWED_OAUTH_REDIRECT_URI"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_REDIRECT_URI"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "service-api-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/frontend:v0.6.5@sha256:d72050f70d12383e4434ad04d189b681dc625f696087ddf0b5df641645c9dafa"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 30
|
||||
}
|
||||
name: "front"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "64Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
volumes: [
|
||||
{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
},
|
||||
{
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{key: "jwtRS256.key.pub", path: "publickey"}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
|
||||
// in this namespace.
|
||||
ReferenceGrant: grant: #ReferenceGrant & {
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
|
||||
// Include shared resources
|
||||
#BankOfHolos.Resources
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: AppProject: #AppProjects["bank-frontend"].metadata.name
|
||||
@@ -0,0 +1,165 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
)
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
// This may be useful to copy and generate other secrets.
|
||||
let SecretName = "jwt-key"
|
||||
|
||||
// Roles for reading and writing secrets
|
||||
let Reader = "\(SecretName)-reader"
|
||||
let Writer = "\(SecretName)-writer"
|
||||
|
||||
// AllowedName represents the service account allowed to read the generated
|
||||
// secret.
|
||||
let AllowedName = #BankOfHolos.Name
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-secrets"
|
||||
Namespace: #BankOfHolos.Security.Namespace
|
||||
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [ID=string]: metadata: name: string | *ID
|
||||
|
||||
Resources: {
|
||||
// Kubernetes ServiceAccount used by the secret generator job.
|
||||
ServiceAccount: (Writer): corev1.#ServiceAccount
|
||||
// Role to allow the ServiceAccount to update secrets.
|
||||
Role: (Writer): rbacv1.#Role & {
|
||||
rules: [{
|
||||
apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["create", "update", "patch"]
|
||||
}]
|
||||
}
|
||||
// Bind the role to the service account.
|
||||
RoleBinding: (Writer): rbacv1.#RoleBinding & {
|
||||
roleRef: {
|
||||
apiGroup: "rbac.authorization.k8s.io"
|
||||
kind: "Role"
|
||||
name: Role[Writer].metadata.name
|
||||
}
|
||||
subjects: [{
|
||||
kind: "ServiceAccount"
|
||||
name: ServiceAccount[Writer].metadata.name
|
||||
namespace: Namespace
|
||||
}]
|
||||
}
|
||||
|
||||
let JobSpec = {
|
||||
serviceAccountName: Writer
|
||||
restartPolicy: "OnFailure"
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
runAsNonRoot: true
|
||||
runAsUser: 8192 // app
|
||||
}
|
||||
containers: [
|
||||
{
|
||||
name: "toolkit"
|
||||
image: "quay.io/holos-run/toolkit:2024-09-16"
|
||||
securityContext: {
|
||||
capabilities: drop: ["ALL"]
|
||||
allowPrivilegeEscalation: false
|
||||
}
|
||||
command: ["/bin/bash"]
|
||||
args: ["/config/entrypoint"]
|
||||
env: [{
|
||||
name: "HOME"
|
||||
value: "/tmp"
|
||||
}]
|
||||
volumeMounts: [{
|
||||
name: "config"
|
||||
mountPath: "/config"
|
||||
readOnly: true
|
||||
}]
|
||||
},
|
||||
]
|
||||
volumes: [{
|
||||
name: "config"
|
||||
configMap: name: Writer
|
||||
}]
|
||||
}
|
||||
|
||||
Job: (Writer): batchv1.#Job & {
|
||||
spec: template: spec: JobSpec
|
||||
}
|
||||
|
||||
ConfigMap: (Writer): corev1.#ConfigMap & {
|
||||
data: entrypoint: ENTRYPOINT
|
||||
}
|
||||
|
||||
// Allow the SecretStore in the frontend and backend namespaces to read the
|
||||
// secret.
|
||||
Role: (Reader): rbacv1.#Role & {
|
||||
rules: [{
|
||||
apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
resourceNames: [SecretName]
|
||||
verbs: ["get"]
|
||||
}]
|
||||
}
|
||||
|
||||
// Grant access to the bank-of-holos service account in the frontend and
|
||||
// backend namespaces.
|
||||
RoleBinding: (Reader): rbacv1.#RoleBinding & {
|
||||
roleRef: {
|
||||
apiGroup: "rbac.authorization.k8s.io"
|
||||
kind: "Role"
|
||||
name: Role[Reader].metadata.name
|
||||
}
|
||||
subjects: [{
|
||||
kind: "ServiceAccount"
|
||||
name: AllowedName
|
||||
namespace: #BankOfHolos.Frontend.Namespace
|
||||
}, {
|
||||
kind: "ServiceAccount"
|
||||
name: AllowedName
|
||||
namespace: #BankOfHolos.Backend.Namespace
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ENTRYPOINT = """
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
status=$?
|
||||
rm -rf "${tmpdir}"
|
||||
return $status
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd "$tmpdir"
|
||||
mkdir secret
|
||||
cd secret
|
||||
|
||||
echo "generating private key" >&2
|
||||
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key -q -N "" -C \(AllowedName)
|
||||
echo "generating public key" >&2
|
||||
ssh-keygen -e -m PKCS8 -f jwtRS256.key > jwtRS256.key.pub
|
||||
cd ..
|
||||
|
||||
echo "copying secret into kubernetes manifest secret.yaml" >&2
|
||||
kubectl create secret generic \(SecretName) --from-file=secret --dry-run=client -o yaml > secret.yaml
|
||||
|
||||
echo "applying secret.yaml" >&2
|
||||
kubectl apply --server-side=true -f secret.yaml
|
||||
|
||||
echo "cleaning up" >&2
|
||||
rm -rf secret secret.yaml
|
||||
|
||||
echo "ok done" >&2
|
||||
"""
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: AppProject: #AppProjects["bank-security"].metadata.name
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "bank-of-holos",
|
||||
"short": "demo bank composed of two projects",
|
||||
"long": "Bank of Holos is a sample HTTP-based web app that simulates a bank's payment processing network, allowing users to create artificial bank accounts and complete transactions."
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/external-secrets-crds": {
|
||||
path: "projects/platform/components/external-secrets-crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/external-secrets": {
|
||||
path: "projects/platform/components/external-secrets"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package holos
|
||||
|
||||
// Platform wide configuration
|
||||
#ExternalSecrets: {
|
||||
Version: "{{ .Version }}"
|
||||
Namespace: "external-secrets"
|
||||
}
|
||||
|
||||
// Register the namespace
|
||||
#Namespaces: (#ExternalSecrets.Namespace): _
|
||||
@@ -0,0 +1,33 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
(#Kubernetes & {Name: "external-secrets-crds"}).BuildPlan
|
||||
|
||||
// Holos stages BuildPlan resources as an intermediate step of the rendering
|
||||
// pipeline. The purpose is to provide the resources to kustomize for
|
||||
// post-processing.
|
||||
let BuildPlanResources = "build-plan-resources.yaml"
|
||||
|
||||
_Kustomization: ks.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
resources: [
|
||||
// Kustomize the intermediate build plan resources.
|
||||
BuildPlanResources,
|
||||
// Mix-in external resources.
|
||||
"https://raw.githubusercontent.com/external-secrets/external-secrets/v\(#ExternalSecrets.Version)/deploy/crds/bundle.yaml",
|
||||
]
|
||||
}
|
||||
|
||||
// Generate a kustomization.yaml directly from CUE so we can provide the correct
|
||||
// version.
|
||||
spec: components: kubernetesObjectsList: [{
|
||||
// intermediate build plan resources to kustomize. Necessary to activate the
|
||||
// kustomization post-rendering step in holos.
|
||||
kustomize: resourcesFile: BuildPlanResources
|
||||
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(_Kustomization)
|
||||
}]
|
||||
@@ -0,0 +1,50 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
// Patch the the build plan output.
|
||||
_Kustomization: patches: [for x in KustomizePatches {x}]
|
||||
|
||||
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
|
||||
let KustomizePatches = #KustomizePatches & {
|
||||
let Patch = [{
|
||||
op: "replace"
|
||||
path: "/spec/conversion/webhook/clientConfig/service/name"
|
||||
value: "external-secrets-webhook"
|
||||
}, {
|
||||
op: "replace"
|
||||
path: "/spec/conversion/webhook/clientConfig/service/namespace"
|
||||
value: "external-secrets"
|
||||
}]
|
||||
|
||||
clustersecretstores: {
|
||||
target: {
|
||||
group: "apiextensions.k8s.io"
|
||||
version: "v1"
|
||||
kind: "CustomResourceDefinition"
|
||||
name: "clustersecretstores.external-secrets.io"
|
||||
}
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
externalsecrets: {
|
||||
target: {
|
||||
group: "apiextensions.k8s.io"
|
||||
version: "v1"
|
||||
kind: "CustomResourceDefinition"
|
||||
name: "externalsecrets.external-secrets.io"
|
||||
}
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
secretstores: {
|
||||
target: {
|
||||
group: "apiextensions.k8s.io"
|
||||
version: "v1"
|
||||
kind: "CustomResourceDefinition"
|
||||
name: "secretstores.external-secrets.io"
|
||||
}
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
_Chart: {
|
||||
Name: "external-secrets"
|
||||
Version: "0.10.3"
|
||||
Namespace: "external-secrets"
|
||||
|
||||
Repo: name: "external-secrets"
|
||||
Repo: url: "https://charts.external-secrets.io"
|
||||
|
||||
Values: installCRDs: false
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & _Chart).BuildPlan
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "external-secrets",
|
||||
"short": "safer secret management",
|
||||
"long": "https://external-secrets.io",
|
||||
"version": "0.10.3"
|
||||
}
|
||||
@@ -4,7 +4,7 @@ package holos
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/gateway-api": {
|
||||
path: "components/gateway-api"
|
||||
path: "projects/platform/components/gateway-api"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: {
|
||||
Version: "1.23.1"
|
||||
System: Namespace: "istio-system"
|
||||
|
||||
// Constrain Helm values for safer, easier upgrades and consistency across
|
||||
// platform components.
|
||||
Values: global: istioNamespace: System.Namespace
|
||||
|
||||
// Configure ambient mode
|
||||
Values: profile: "ambient"
|
||||
}
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.System.Namespace): _
|
||||
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/istio-base": {
|
||||
path: "components/istio/base"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istiod": {
|
||||
path: "components/istio/istiod"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-cni": {
|
||||
path: "components/istio/cni"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-ztunnel": {
|
||||
path: "components/istio/ztunnel"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/istio-base": {
|
||||
path: "projects/platform/components/istio/base"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istiod": {
|
||||
path: "projects/platform/components/istio/istiod"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-cni": {
|
||||
path: "projects/platform/components/istio/cni"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-ztunnel": {
|
||||
path: "projects/platform/components/istio/ztunnel"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: {
|
||||
Version: "1.23.1"
|
||||
System: Namespace: "istio-system"
|
||||
|
||||
// Constrain Helm values for safer, easier upgrades and consistency across
|
||||
// platform components.
|
||||
Values: global: istioNamespace: System.Namespace
|
||||
|
||||
// Configure ambient mode
|
||||
Values: profile: "ambient"
|
||||
}
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.System.Namespace): _
|
||||
@@ -0,0 +1,48 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
// Holos stages BuildPlan resources as an intermediate step of the rendering
|
||||
// pipeline. The purpose is to provide the resources to kustomize for
|
||||
// post-processing.
|
||||
let BuildPlanOutputManifest = "build-plan-output-manifest.yaml"
|
||||
|
||||
// Patch istio so it's not constantly out of sync in ArgoCD
|
||||
let Kustomization = ks.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
// Kustomize the build plan output.
|
||||
resources: [BuildPlanOutputManifest]
|
||||
// Patch the the build plan output.
|
||||
patches: [for x in KustomizePatches {x}]
|
||||
}
|
||||
|
||||
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
|
||||
let KustomizePatches = #KustomizePatches & {
|
||||
validator: {
|
||||
target: {
|
||||
group: "admissionregistration.k8s.io"
|
||||
version: "v1"
|
||||
kind: "ValidatingWebhookConfiguration"
|
||||
name: "istiod-default-validator"
|
||||
}
|
||||
let Patch = [{
|
||||
op: "replace"
|
||||
path: "/webhooks/0/failurePolicy"
|
||||
value: "Fail"
|
||||
}]
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a kustomization.yaml directly from CUE so we can provide the correct
|
||||
// version.
|
||||
spec: components: helmChartList: [{
|
||||
// intermediate build plan resources to kustomize. Necessary to activate the
|
||||
// kustomization post-rendering step in holos.
|
||||
kustomize: resourcesFile: BuildPlanOutputManifest
|
||||
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
|
||||
}]
|
||||
@@ -0,0 +1,61 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "istio-gateway"
|
||||
Namespace: #Istio.Gateway.Namespace
|
||||
|
||||
Resources: {
|
||||
// The default gateway with all listeners attached to tls certs.
|
||||
Gateway: default: {
|
||||
metadata: namespace: Namespace
|
||||
|
||||
let Listeners = {
|
||||
http: {
|
||||
name: "http"
|
||||
protocol: "HTTP"
|
||||
port: 80
|
||||
allowedRoutes: namespaces: from: "Same"
|
||||
}
|
||||
https: {
|
||||
name: "https"
|
||||
protocol: "HTTPS"
|
||||
port: 443
|
||||
allowedRoutes: namespaces: from: "Same"
|
||||
tls: mode: "Terminate"
|
||||
tls: certificateRefs: [{
|
||||
kind: "Secret"
|
||||
name: "gateway-cert"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
spec: listeners: [for x in Listeners {x}]
|
||||
}
|
||||
|
||||
// Manage a simple cert for example.com and *.example.com
|
||||
Certificate: "gateway-cert": {
|
||||
metadata: name: "gateway-cert"
|
||||
metadata: namespace: Namespace
|
||||
spec: commonName: #Platform.Domain
|
||||
spec: dnsNames: [spec.commonName, "*.\(spec.commonName)"]
|
||||
spec: secretName: metadata.name
|
||||
spec: issuerRef: {
|
||||
kind: "ClusterIssuer"
|
||||
name: "local-ca"
|
||||
}
|
||||
}
|
||||
|
||||
// Manage a service account to prevent ArgoCD from pruning it.
|
||||
ServiceAccount: "default-istio": {
|
||||
metadata: namespace: Namespace
|
||||
metadata: labels: {
|
||||
"gateway.istio.io/managed": "istio.io-gateway-controller"
|
||||
"gateway.networking.k8s.io/gateway-name": "default"
|
||||
"istio.io/gateway-name": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Gateway API
|
||||
|
||||
This component uses the [Gateway API][1] to manage an istio Gateway. This will
|
||||
become the default method in upstream istio so it is the preferred method in
|
||||
Holos.
|
||||
|
||||
[1]: https://gateway-api.sigs.k8s.io/
|
||||
@@ -0,0 +1,48 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
// Holos stages BuildPlan resources as an intermediate step of the rendering
|
||||
// pipeline. The purpose is to provide the resources to kustomize for
|
||||
// post-processing.
|
||||
let BuildPlanOutputManifest = "build-plan-output-manifest.yaml"
|
||||
|
||||
// Patch istio so it's not constantly out of sync in ArgoCD
|
||||
let Kustomization = ks.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
// Kustomize the build plan output.
|
||||
resources: [BuildPlanOutputManifest]
|
||||
// Patch the the build plan output.
|
||||
patches: [for x in KustomizePatches {x}]
|
||||
}
|
||||
|
||||
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
|
||||
let KustomizePatches = #KustomizePatches & {
|
||||
validator: {
|
||||
target: {
|
||||
group: "admissionregistration.k8s.io"
|
||||
version: "v1"
|
||||
kind: "ValidatingWebhookConfiguration"
|
||||
name: "istio-validator-istio-system"
|
||||
}
|
||||
let Patch = [{
|
||||
op: "replace"
|
||||
path: "/webhooks/0/failurePolicy"
|
||||
value: "Fail"
|
||||
}]
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a kustomization.yaml directly from CUE so we can provide the correct
|
||||
// version.
|
||||
spec: components: helmChartList: [{
|
||||
// intermediate build plan resources to kustomize. Necessary to activate the
|
||||
// kustomization post-rendering step in holos.
|
||||
kustomize: resourcesFile: BuildPlanOutputManifest
|
||||
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
|
||||
}]
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
hrv1 "gateway.networking.k8s.io/httproute/v1"
|
||||
gwv1 "gateway.networking.k8s.io/gateway/v1"
|
||||
ap "argoproj.io/appproject/v1alpha1"
|
||||
es "external-secrets.io/externalsecret/v1beta1"
|
||||
ss "external-secrets.io/secretstore/v1beta1"
|
||||
)
|
||||
|
||||
#Resources: {
|
||||
@@ -28,12 +30,15 @@ import (
|
||||
ConfigMap: [_]: corev1.#ConfigMap
|
||||
CronJob: [_]: batchv1.#CronJob
|
||||
Deployment: [_]: appsv1.#Deployment
|
||||
ExternalSecret: [_]: es.#ExternalSecret
|
||||
HTTPRoute: [_]: hrv1.#HTTPRoute
|
||||
Job: [_]: batchv1.#Job
|
||||
Namespace: [_]: corev1.#Namespace
|
||||
ReferenceGrant: [_]: rgv1.#ReferenceGrant
|
||||
Role: [_]: rbacv1.#Role
|
||||
RoleBinding: [_]: rbacv1.#RoleBinding
|
||||
Secret: [_]: corev1.#Secret
|
||||
SecretStore: [_]: ss.#SecretStore
|
||||
Service: [_]: corev1.#Service
|
||||
ServiceAccount: [_]: corev1.#ServiceAccount
|
||||
StatefulSet: [_]: appsv1.#StatefulSet
|
||||
|
||||
@@ -5,8 +5,11 @@ import (
|
||||
dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
|
||||
)
|
||||
|
||||
// Note, tags should have a reasonable default value to easily use cue eval and
|
||||
// cue export without needing to make a bunch of decisions about tag values.
|
||||
|
||||
// _ClusterName is the --cluster-name flag value provided by the holos cli.
|
||||
_ClusterName: string @tag(cluster, type=string)
|
||||
_ClusterName: string | *"no-name" @tag(cluster, type=string)
|
||||
|
||||
// _PlatformConfig represents all of the data passed from holos to cue, used to
|
||||
// carry the platform and project models.
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
core "github.com/holos-run/holos/api/core/v1alpha2"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func Platform(ctx context.Context, concurrency int, pf *core.Platform, stderr io.Writer) error {
|
||||
parentStart := time.Now()
|
||||
total := len(pf.Spec.Components)
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
@@ -49,7 +51,7 @@ func Platform(ctx context.Context, concurrency int, pf *core.Platform, stderr io
|
||||
}
|
||||
|
||||
duration := time.Since(start)
|
||||
msg := fmt.Sprintf("rendered %s for cluster %s in %s", component.Path, component.Cluster, duration)
|
||||
msg := fmt.Sprintf("rendered %s for cluster %s in %s", filepath.Base(component.Path), component.Cluster, duration)
|
||||
log.InfoContext(ctx, msg, "duration", duration)
|
||||
return nil
|
||||
}
|
||||
@@ -60,5 +62,12 @@ func Platform(ctx context.Context, concurrency int, pf *core.Platform, stderr io
|
||||
})
|
||||
|
||||
// Wait for completion and return the first error (if any)
|
||||
return g.Wait()
|
||||
if err := g.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
duration := time.Since(parentStart)
|
||||
msg := fmt.Sprintf("rendered platform in %s", duration)
|
||||
logger.FromContext(ctx).InfoContext(ctx, msg, "duration", duration)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
94
|
||||
95
|
||||
|
||||
@@ -1 +1 @@
|
||||
0
|
||||
1
|
||||
|
||||
Reference in New Issue
Block a user