AB#2593: Deploy verification service via Helm (#594)

This commit is contained in:
Otto Bittner 2022-11-21 17:06:41 +01:00 committed by GitHub
parent 1f9b6ba90f
commit adc09a1ad1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 514 additions and 276 deletions

View file

@ -1,196 +0,0 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package resources
import (
"fmt"
"net"
"strings"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/kubernetes"
"github.com/edgelesssys/constellation/v2/internal/versions"
"google.golang.org/protobuf/proto"
apps "k8s.io/api/apps/v1"
k8s "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)
// VerificationDaemonset groups all k8s resources for the verification service deployment.
type VerificationDaemonset struct {
DaemonSet apps.DaemonSet
Service k8s.Service
LoadBalancer k8s.Service
}
// NewVerificationDaemonSet creates a new VerificationDaemonset.
func NewVerificationDaemonSet(csp, loadBalancerIP string) *VerificationDaemonset {
var err error
if strings.Contains(loadBalancerIP, ":") {
loadBalancerIP, _, err = net.SplitHostPort(loadBalancerIP)
if err != nil {
panic(err)
}
}
return &VerificationDaemonset{
DaemonSet: apps.DaemonSet{
TypeMeta: meta.TypeMeta{
APIVersion: "apps/v1",
Kind: "DaemonSet",
},
ObjectMeta: meta.ObjectMeta{
Name: "verification-service",
Namespace: "kube-system",
Labels: map[string]string{
"k8s-app": "verification-service",
"component": "verification-service",
},
},
Spec: apps.DaemonSetSpec{
Selector: &meta.LabelSelector{
MatchLabels: map[string]string{
"k8s-app": "verification-service",
},
},
Template: k8s.PodTemplateSpec{
ObjectMeta: meta.ObjectMeta{
Labels: map[string]string{
"k8s-app": "verification-service",
},
},
Spec: k8s.PodSpec{
Tolerations: []k8s.Toleration{
{
Key: "node-role.kubernetes.io/master",
Operator: k8s.TolerationOpEqual,
Value: "true",
Effect: k8s.TaintEffectNoSchedule,
},
{
Key: "node-role.kubernetes.io/control-plane",
Operator: k8s.TolerationOpExists,
Effect: k8s.TaintEffectNoSchedule,
},
{
Operator: k8s.TolerationOpExists,
Effect: k8s.TaintEffectNoExecute,
},
{
Operator: k8s.TolerationOpExists,
Effect: k8s.TaintEffectNoSchedule,
},
},
Containers: []k8s.Container{
{
Name: "verification-service",
Image: versions.VerificationImage,
Ports: []k8s.ContainerPort{
{
Name: "http",
ContainerPort: constants.VerifyServicePortHTTP,
},
{
Name: "grpc",
ContainerPort: constants.VerifyServicePortGRPC,
},
},
SecurityContext: &k8s.SecurityContext{
Privileged: func(b bool) *bool { return &b }(true),
},
Args: []string{
fmt.Sprintf("--cloud-provider=%s", csp),
},
VolumeMounts: []k8s.VolumeMount{
{
Name: "event-log",
ReadOnly: true,
MountPath: "/sys/kernel/security/",
},
},
},
},
Volumes: []k8s.Volume{
{
Name: "event-log",
VolumeSource: k8s.VolumeSource{
HostPath: &k8s.HostPathVolumeSource{
Path: "/sys/kernel/security/",
},
},
},
},
},
},
},
},
Service: k8s.Service{
TypeMeta: meta.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: meta.ObjectMeta{
Name: "verification-service",
Namespace: "kube-system",
},
Spec: k8s.ServiceSpec{
Type: k8s.ServiceTypeNodePort,
Ports: []k8s.ServicePort{
{
Name: "http",
Protocol: k8s.ProtocolTCP,
Port: constants.VerifyServicePortHTTP,
TargetPort: intstr.FromInt(constants.VerifyServicePortHTTP),
NodePort: constants.VerifyServiceNodePortHTTP,
},
{
Name: "grpc",
Protocol: k8s.ProtocolTCP,
Port: constants.VerifyServicePortGRPC,
TargetPort: intstr.FromInt(constants.VerifyServicePortGRPC),
NodePort: constants.VerifyServiceNodePortGRPC,
},
},
Selector: map[string]string{
"k8s-app": "verification-service",
},
},
},
LoadBalancer: k8s.Service{
TypeMeta: meta.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: meta.ObjectMeta{
Name: "verify",
Namespace: "kube-system",
},
Spec: k8s.ServiceSpec{
AllocateLoadBalancerNodePorts: proto.Bool(false),
Type: k8s.ServiceTypeLoadBalancer,
LoadBalancerClass: proto.String("constellation"),
ExternalIPs: []string{loadBalancerIP},
Ports: []k8s.ServicePort{
{
Name: "grpc",
Protocol: k8s.ProtocolTCP,
Port: constants.VerifyServiceNodePortGRPC,
TargetPort: intstr.FromInt(constants.VerifyServicePortGRPC),
},
},
Selector: map[string]string{
"k8s-app": "verification-service",
},
},
},
}
}
// Marshal to Kubernetes YAML.
func (v *VerificationDaemonset) Marshal() ([]byte, error) {
return kubernetes.MarshalK8SResources(v)
}

View file

@ -1,25 +0,0 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package resources
import (
"testing"
"github.com/edgelesssys/constellation/v2/internal/kubernetes"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewVerificationDaemonset(t *testing.T) {
deployment := NewVerificationDaemonSet("csp", "192.168.2.1")
deploymentYAML, err := deployment.Marshal()
require.NoError(t, err)
var recreated VerificationDaemonset
require.NoError(t, kubernetes.UnmarshalK8SResources(deploymentYAML, &recreated))
assert.Equal(t, deployment, &recreated)
}

View file

@ -23,7 +23,6 @@ type clusterUtil interface {
InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) error InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) error
JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error
SetupKonnectivity(kubectl k8sapi.Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error SetupKonnectivity(kubectl k8sapi.Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error
SetupVerificationService(kubectl k8sapi.Client, verificationServiceConfiguration kubernetes.Marshaler) error
SetupGCPGuestAgent(kubectl k8sapi.Client, gcpGuestAgentConfiguration kubernetes.Marshaler) error SetupGCPGuestAgent(kubectl k8sapi.Client, gcpGuestAgentConfiguration kubernetes.Marshaler) error
FixCilium(log *logger.Logger) FixCilium(log *logger.Logger)
StartKubelet() error StartKubelet() error

View file

@ -192,7 +192,15 @@ func (k *KubeWrapper) InitCluster(
return nil, fmt.Errorf("setting up konnectivity: %w", err) return nil, fmt.Errorf("setting up konnectivity: %w", err)
} }
extraVals, err := k.setupExtraVals(ctx, k.initialMeasurementsJSON, idKeyDigest, measurementSalt, subnetworkPodCIDR, cloudServiceAccountURI) loadBalancerIP := controlPlaneEndpoint
if strings.Contains(controlPlaneEndpoint, ":") {
loadBalancerIP, _, err = net.SplitHostPort(controlPlaneEndpoint)
if err != nil {
return nil, fmt.Errorf("splitting host port: %w", err)
}
}
serviceConfig := constellationServicesConfig{k.initialMeasurementsJSON, idKeyDigest, measurementSalt, subnetworkPodCIDR, cloudServiceAccountURI, loadBalancerIP}
extraVals, err := k.setupExtraVals(ctx, serviceConfig)
if err != nil { if err != nil {
return nil, fmt.Errorf("setting up extraVals: %w", err) return nil, fmt.Errorf("setting up extraVals: %w", err)
} }
@ -205,12 +213,6 @@ func (k *KubeWrapper) InitCluster(
return nil, fmt.Errorf("failed to setup internal ConfigMap: %w", err) return nil, fmt.Errorf("failed to setup internal ConfigMap: %w", err)
} }
if err := k.clusterUtil.SetupVerificationService(
k.client, resources.NewVerificationDaemonSet(k.cloudProvider, controlPlaneEndpoint),
); err != nil {
return nil, fmt.Errorf("failed to setup verification service: %w", err)
}
// cert-manager is necessary for our operator deployments. // cert-manager is necessary for our operator deployments.
// They are currently only deployed on GCP & Azure. This is why we deploy cert-manager only on GCP & Azure. // They are currently only deployed on GCP & Azure. This is why we deploy cert-manager only on GCP & Azure.
if k.cloudProvider == "gcp" || k.cloudProvider == "azure" { if k.cloudProvider == "gcp" || k.cloudProvider == "azure" {
@ -393,13 +395,16 @@ func getIPAddr() (string, error) {
// setupExtraVals create a helm values map for consumption by helm-install. // setupExtraVals create a helm values map for consumption by helm-install.
// Will move to a more dedicated place once that place becomes apparent. // Will move to a more dedicated place once that place becomes apparent.
func (k *KubeWrapper) setupExtraVals(ctx context.Context, initialMeasurementsJSON []byte, idkeydigest []byte, measurementSalt []byte, subnetworkPodCIDR string, cloudServiceAccountURI string) (map[string]any, error) { func (k *KubeWrapper) setupExtraVals(ctx context.Context, serviceConfig constellationServicesConfig) (map[string]any, error) {
extraVals := map[string]any{ extraVals := map[string]any{
"join-service": map[string]any{ "join-service": map[string]any{
"measurements": string(initialMeasurementsJSON), "measurements": string(serviceConfig.initialMeasurementsJSON),
"measurementSalt": base64.StdEncoding.EncodeToString(measurementSalt), "measurementSalt": base64.StdEncoding.EncodeToString(serviceConfig.measurementSalt),
}, },
"ccm": map[string]any{}, "ccm": map[string]any{},
"verification-service": map[string]any{
"loadBalancerIP": serviceConfig.loadBalancerIP,
},
} }
instance, err := k.providerMetadata.Self(ctx) instance, err := k.providerMetadata.Self(ctx)
@ -419,7 +424,7 @@ func (k *KubeWrapper) setupExtraVals(ctx context.Context, initialMeasurementsJSO
return nil, fmt.Errorf("splitting providerID: %w", err) return nil, fmt.Errorf("splitting providerID: %w", err)
} }
serviceAccountKey, err := gcpshared.ServiceAccountKeyFromURI(cloudServiceAccountURI) serviceAccountKey, err := gcpshared.ServiceAccountKeyFromURI(serviceConfig.cloudServiceAccountURI)
if err != nil { if err != nil {
return nil, fmt.Errorf("getting service account key: %w", err) return nil, fmt.Errorf("getting service account key: %w", err)
} }
@ -436,7 +441,7 @@ func (k *KubeWrapper) setupExtraVals(ctx context.Context, initialMeasurementsJSO
"projectID": projectID, "projectID": projectID,
"uid": uid, "uid": uid,
"secretData": string(rawKey), "secretData": string(rawKey),
"subnetworkPodCIDR": subnetworkPodCIDR, "subnetworkPodCIDR": serviceConfig.subnetworkPodCIDR,
} }
case cloudprovider.Azure: case cloudprovider.Azure:
@ -445,7 +450,7 @@ func (k *KubeWrapper) setupExtraVals(ctx context.Context, initialMeasurementsJSO
return nil, errors.New("invalid cloud provider metadata for Azure") return nil, errors.New("invalid cloud provider metadata for Azure")
} }
ccmConfig, err := ccmAzure.GetCCMConfig(ctx, instance.ProviderID, cloudServiceAccountURI) ccmConfig, err := ccmAzure.GetCCMConfig(ctx, instance.ProviderID, serviceConfig.cloudServiceAccountURI)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating ccm secret: %w", err) return nil, fmt.Errorf("creating ccm secret: %w", err)
} }
@ -456,20 +461,20 @@ func (k *KubeWrapper) setupExtraVals(ctx context.Context, initialMeasurementsJSO
} }
ccmVals["Azure"] = map[string]any{ ccmVals["Azure"] = map[string]any{
"azureConfig": string(ccmConfig), "azureConfig": string(ccmConfig),
"subnetworkPodCIDR": subnetworkPodCIDR, "subnetworkPodCIDR": serviceConfig.subnetworkPodCIDR,
} }
joinVals, ok := extraVals["join-service"].(map[string]any) joinVals, ok := extraVals["join-service"].(map[string]any)
if !ok { if !ok {
return nil, errors.New("invalid join-service values") return nil, errors.New("invalid join-service values")
} }
joinVals["idkeydigest"] = hex.EncodeToString(idkeydigest) joinVals["idkeydigest"] = hex.EncodeToString(serviceConfig.idkeydigest)
subscriptionID, resourceGroup, err := azureshared.BasicsFromProviderID(instance.ProviderID) subscriptionID, resourceGroup, err := azureshared.BasicsFromProviderID(instance.ProviderID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
creds, err := azureshared.ApplicationCredentialsFromURI(cloudServiceAccountURI) creds, err := azureshared.ApplicationCredentialsFromURI(serviceConfig.cloudServiceAccountURI)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -504,3 +509,12 @@ func (k *KubeWrapper) setupOperatorVals(ctx context.Context) (map[string]any, er
type ccmConfigGetter interface { type ccmConfigGetter interface {
GetCCMConfig(ctx context.Context, providerID, cloudServiceAccountURI string) ([]byte, error) GetCCMConfig(ctx context.Context, providerID, cloudServiceAccountURI string) ([]byte, error)
} }
type constellationServicesConfig struct {
initialMeasurementsJSON []byte
idkeydigest []byte
measurementSalt []byte
subnetworkPodCIDR string
cloudServiceAccountURI string
loadBalancerIP string
}

View file

@ -187,7 +187,8 @@ func TestInitCluster(t *testing.T) {
k8sVersion: versions.Default, k8sVersion: versions.Default,
}, },
"kubeadm init fails when setting up verification service": { "kubeadm init fails when setting up verification service": {
clusterUtil: stubClusterUtil{setupVerificationServiceErr: someErr}, clusterUtil: stubClusterUtil{},
helmClient: stubHelmClient{servicesError: someErr},
kubeconfigReader: &stubKubeconfigReader{ kubeconfigReader: &stubKubeconfigReader{
kubeconfig: []byte("someKubeconfig"), kubeconfig: []byte("someKubeconfig"),
}, },
@ -414,17 +415,16 @@ func TestK8sCompliantHostname(t *testing.T) {
} }
type stubClusterUtil struct { type stubClusterUtil struct {
installComponentsErr error installComponentsErr error
initClusterErr error initClusterErr error
setupAutoscalingError error setupAutoscalingError error
setupKonnectivityError error setupKonnectivityError error
setupVerificationServiceErr error setupGCPGuestAgentErr error
setupGCPGuestAgentErr error setupOLMErr error
setupOLMErr error setupNMOErr error
setupNMOErr error setupNodeOperatorErr error
setupNodeOperatorErr error joinClusterErr error
joinClusterErr error startKubeletErr error
startKubeletErr error
initConfigs [][]byte initConfigs [][]byte
joinConfigs [][]byte joinConfigs [][]byte
@ -451,10 +451,6 @@ func (s *stubClusterUtil) SetupGCPGuestAgent(kubectl k8sapi.Client, gcpGuestAgen
return s.setupGCPGuestAgentErr return s.setupGCPGuestAgentErr
} }
func (s *stubClusterUtil) SetupVerificationService(kubectl k8sapi.Client, verificationServiceConfiguration kubernetes.Marshaler) error {
return s.setupVerificationServiceErr
}
func (s *stubClusterUtil) SetupOperatorLifecycleManager(ctx context.Context, kubectl k8sapi.Client, olmCRDs, olmConfiguration kubernetes.Marshaler, crdNames []string) error { func (s *stubClusterUtil) SetupOperatorLifecycleManager(ctx context.Context, kubectl k8sapi.Client, olmCRDs, olmConfiguration kubernetes.Marshaler, crdNames []string) error {
return s.setupOLMErr return s.setupOLMErr
} }

View file

@ -2,39 +2,46 @@ apiVersion: v2
name: constellation-services name: constellation-services
description: A chart to deploy all microservices that are part of a valid constellation cluster description: A chart to deploy all microservices that are part of a valid constellation cluster
type: application type: application
version: 2.2.2 version: 2.3.0-pre
dependencies: dependencies:
- name: kms - name: kms
version: 2.2.2 version: 2.3.0-pre
tags: tags:
- Azure - Azure
- GCP - GCP
- AWS - AWS
- QEMU - QEMU
- name: join-service - name: join-service
version: 2.2.2 version: 2.3.0-pre
tags: tags:
- Azure - Azure
- GCP - GCP
- AWS - AWS
- QEMU - QEMU
- name: ccm - name: ccm
version: 2.2.2 version: 2.3.0-pre
tags: tags:
- Azure - Azure
- GCP - GCP
- AWS - AWS
- name: cnm - name: cnm
version: 2.2.2 version: 2.3.0-pre
tags: tags:
- Azure - Azure
- name: autoscaler - name: autoscaler
version: 2.2.2 version: 2.3.0-pre
tags: tags:
- Azure - Azure
- GCP - GCP
- AWS - AWS
- name: verification-service
version: 2.3.0-pre
tags:
- Azure
- GCP
- AWS
- QEMU
- name: gcp-compute-persistent-disk-csi-driver - name: gcp-compute-persistent-disk-csi-driver
version: 1.0.1 version: 1.0.1
condition: gcp.deployCSIDriver condition: gcp.deployCSIDriver

View file

@ -2,4 +2,4 @@ apiVersion: v2
name: autoscaler name: autoscaler
description: A Helm chart to deploy the cluster autoscaler. description: A Helm chart to deploy the cluster autoscaler.
type: application type: application
version: 2.2.2 version: 2.3.0-pre

View file

@ -2,4 +2,4 @@ apiVersion: v2
name: ccm name: ccm
description: A Helm chart to deploy the cloud controller manager. description: A Helm chart to deploy the cloud controller manager.
type: application type: application
version: 2.2.2 version: 2.3.0-pre

View file

@ -2,4 +2,4 @@ apiVersion: v2
name: cnm name: cnm
description: A chart to deploy cloud node manager for constellation description: A chart to deploy cloud node manager for constellation
type: application type: application
version: 2.2.2 version: 2.3.0-pre

View file

@ -2,4 +2,4 @@ apiVersion: v2
name: join-service name: join-service
description: A chart to deploy the Constellation join-service description: A chart to deploy the Constellation join-service
type: application type: application
version: 2.2.2 version: 2.3.0-pre

View file

@ -2,4 +2,4 @@ apiVersion: v2
name: kms name: kms
description: A Helm chart to deploy the Constellation Key Management Service description: A Helm chart to deploy the Constellation Key Management Service
type: application type: application
version: 2.2.2 version: 2.3.0-pre

View file

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View file

@ -0,0 +1,5 @@
apiVersion: v2
name: verification-service
description: A Helm chart for Kubernetes
type: application
version: 2.3.0-pre

View file

@ -0,0 +1,51 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
component: verification-service
k8s-app: verification-service
name: verification-service
namespace: {{ .Release.Namespace }}
spec:
selector:
matchLabels:
k8s-app: verification-service
template:
metadata:
labels:
k8s-app: verification-service
spec:
containers:
- args:
- --cloud-provider={{ .Values.csp }}
image: {{ .Values.image }}
name: verification-service
ports:
- containerPort: {{ .Values.httpContainerPort }}
name: http
- containerPort: {{ .Values.grpcContainerPort }}
name: grpc
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys/kernel/security/
name: event-log
readOnly: true
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Equal
value: "true"
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
- effect: NoExecute
operator: Exists
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /sys/kernel/security/
name: event-log
updateStrategy: {}

View file

@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: verify
namespace: {{ .Release.Namespace }}
spec:
allocateLoadBalancerNodePorts: false
externalIPs:
- {{ .Values.loadBalancerIP }}
loadBalancerClass: constellation
ports:
- name: grpc
port: {{ .Values.grpcNodePort }}
protocol: TCP
targetPort: {{ .Values.grpcContainerPort }}
selector:
k8s-app: verification-service
type: LoadBalancer

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: verification-service
namespace: {{ .Release.Namespace }}
spec:
ports:
- name: http
nodePort: {{ .Values.httpNodePort }}
port: {{ .Values.httpContainerPort }}
protocol: TCP
targetPort: {{ .Values.httpContainerPort }}
- name: grpc
nodePort: {{ .Values.grpcNodePort }}
port: {{ .Values.grpcContainerPort }}
protocol: TCP
targetPort: {{ .Values.grpcContainerPort }}
selector:
k8s-app: verification-service
type: NodePort

View file

@ -0,0 +1,25 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"csp": {
"description": "CSP to which the chart is deployed.",
"enum": ["Azure", "GCP", "AWS", "QEMU"]
},
"image": {
"description": "Container image to use for the spawned pods.",
"type": "string",
"examples": ["ghcr.io/edgelesssys/constellation/join-service:latest"]
},
"loadBalancerIP": {
"description": "IP of the k8s LB service",
"type": "string"
}
},
"required": [
"csp",
"image",
"loadBalancerIP"
],
"title": "Values",
"type": "object"
}

View file

@ -0,0 +1,4 @@
httpContainerPort: 8080
grpcContainerPort: 9090
httpNodePort: 30080
grpcNodePort: 30081

View file

@ -39,11 +39,19 @@ var helmFS embed.FS
// ChartLoader loads embedded helm charts. // ChartLoader loads embedded helm charts.
type ChartLoader struct { type ChartLoader struct {
joinServiceImage string joinServiceImage string
kmsImage string kmsImage string
ccmImage string ccmImage string
cnmImage string cnmImage string
autoscalerImage string autoscalerImage string
verificationServiceImage string
}
type LoadConfig struct {
Csp cloudprovider.Provider
ConformanceMode bool
MasterSecret []byte
Salt []byte
} }
// New creates a new ChartLoader. // New creates a new ChartLoader.
@ -60,11 +68,12 @@ func New(csp cloudprovider.Provider, k8sVersion versions.ValidK8sVersion) *Chart
} }
return &ChartLoader{ return &ChartLoader{
joinServiceImage: versions.JoinImage, joinServiceImage: versions.JoinImage,
kmsImage: versions.KmsImage, kmsImage: versions.KmsImage,
ccmImage: ccmImage, ccmImage: ccmImage,
cnmImage: cnmImage, cnmImage: cnmImage,
autoscalerImage: versions.VersionConfigs[k8sVersion].ClusterAutoscalerImage, autoscalerImage: versions.VersionConfigs[k8sVersion].ClusterAutoscalerImage,
verificationServiceImage: versions.VerificationImage,
} }
} }
@ -376,6 +385,10 @@ func (i *ChartLoader) loadConstellationServicesHelper(config *config.Config, mas
"csp": csp.String(), "csp": csp.String(),
"image": i.autoscalerImage, "image": i.autoscalerImage,
}, },
"verification-service": map[string]any{
"csp": csp.String(),
"image": i.verificationServiceImage,
},
} }
switch csp { switch csp {

View file

@ -88,7 +88,7 @@ func TestConstellationServices(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
require := require.New(t) require := require.New(t)
chartLoader := ChartLoader{joinServiceImage: "joinServiceImage", kmsImage: "kmsImage", ccmImage: tc.ccmImage, cnmImage: tc.cnmImage, autoscalerImage: "autoscalerImage"} chartLoader := ChartLoader{joinServiceImage: "joinServiceImage", kmsImage: "kmsImage", ccmImage: tc.ccmImage, cnmImage: tc.cnmImage, autoscalerImage: "autoscalerImage", verificationServiceImage: "verificationImage"}
chart, values, err := chartLoader.loadConstellationServicesHelper(tc.config, []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) chart, values, err := chartLoader.loadConstellationServicesHelper(tc.config, []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
require.NoError(err) require.NoError(err)
@ -248,6 +248,11 @@ func prepareGCPValues(values map[string]any) error {
}, },
} }
verificationVals, ok := values["verification-service"].(map[string]any)
if !ok {
return errors.New("missing 'verification-service' key")
}
verificationVals["loadBalancerIP"] = "127.0.0.1"
return nil return nil
} }
@ -278,6 +283,12 @@ func prepareAzureValues(values map[string]any) error {
"subscriptionID": "subscriptionID", "subscriptionID": "subscriptionID",
"tenantID": "TenantID", "tenantID": "TenantID",
} }
verificationVals, ok := values["verification-service"].(map[string]any)
if !ok {
return errors.New("missing 'verification-service' key")
}
verificationVals["loadBalancerIP"] = "127.0.0.1"
return nil return nil
} }
@ -289,5 +300,11 @@ func prepareQEMUValues(values map[string]any) error {
joinVals["measurements"] = "{'1':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA','15':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='}" joinVals["measurements"] = "{'1':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA','15':'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='}"
joinVals["measurementSalt"] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" joinVals["measurementSalt"] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
verificationVals, ok := values["verification-service"].(map[string]any)
if !ok {
return errors.New("missing 'verification-service' key")
}
verificationVals["loadBalancerIP"] = "127.0.0.1"
return nil return nil
} }

View file

@ -0,0 +1,51 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
component: verification-service
k8s-app: verification-service
name: verification-service
namespace: testNamespace
spec:
selector:
matchLabels:
k8s-app: verification-service
template:
metadata:
labels:
k8s-app: verification-service
spec:
containers:
- args:
- --cloud-provider=Azure
image: verificationImage
name: verification-service
ports:
- containerPort: 8080
name: http
- containerPort: 9090
name: grpc
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys/kernel/security/
name: event-log
readOnly: true
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Equal
value: "true"
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
- effect: NoExecute
operator: Exists
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /sys/kernel/security/
name: event-log
updateStrategy: {}

View file

@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: verify
namespace: testNamespace
spec:
allocateLoadBalancerNodePorts: false
externalIPs:
- 127.0.0.1
loadBalancerClass: constellation
ports:
- name: grpc
port: 30081
protocol: TCP
targetPort: 9090
selector:
k8s-app: verification-service
type: LoadBalancer

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: verification-service
namespace: testNamespace
spec:
ports:
- name: http
nodePort: 30080
port: 8080
protocol: TCP
targetPort: 8080
- name: grpc
nodePort: 30081
port: 9090
protocol: TCP
targetPort: 9090
selector:
k8s-app: verification-service
type: NodePort

View file

@ -0,0 +1,51 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
component: verification-service
k8s-app: verification-service
name: verification-service
namespace: testNamespace
spec:
selector:
matchLabels:
k8s-app: verification-service
template:
metadata:
labels:
k8s-app: verification-service
spec:
containers:
- args:
- --cloud-provider=GCP
image: verificationImage
name: verification-service
ports:
- containerPort: 8080
name: http
- containerPort: 9090
name: grpc
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys/kernel/security/
name: event-log
readOnly: true
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Equal
value: "true"
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
- effect: NoExecute
operator: Exists
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /sys/kernel/security/
name: event-log
updateStrategy: {}

View file

@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: verify
namespace: testNamespace
spec:
allocateLoadBalancerNodePorts: false
externalIPs:
- 127.0.0.1
loadBalancerClass: constellation
ports:
- name: grpc
port: 30081
protocol: TCP
targetPort: 9090
selector:
k8s-app: verification-service
type: LoadBalancer

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: verification-service
namespace: testNamespace
spec:
ports:
- name: http
nodePort: 30080
port: 8080
protocol: TCP
targetPort: 8080
- name: grpc
nodePort: 30081
port: 9090
protocol: TCP
targetPort: 9090
selector:
k8s-app: verification-service
type: NodePort

View file

@ -0,0 +1,51 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
component: verification-service
k8s-app: verification-service
name: verification-service
namespace: testNamespace
spec:
selector:
matchLabels:
k8s-app: verification-service
template:
metadata:
labels:
k8s-app: verification-service
spec:
containers:
- args:
- --cloud-provider=QEMU
image: verificationImage
name: verification-service
ports:
- containerPort: 8080
name: http
- containerPort: 9090
name: grpc
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys/kernel/security/
name: event-log
readOnly: true
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Equal
value: "true"
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
- effect: NoExecute
operator: Exists
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /sys/kernel/security/
name: event-log
updateStrategy: {}

View file

@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: verify
namespace: testNamespace
spec:
allocateLoadBalancerNodePorts: false
externalIPs:
- 127.0.0.1
loadBalancerClass: constellation
ports:
- name: grpc
port: 30081
protocol: TCP
targetPort: 9090
selector:
k8s-app: verification-service
type: LoadBalancer

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: verification-service
namespace: testNamespace
spec:
ports:
- name: http
nodePort: 30080
port: 8080
protocol: TCP
targetPort: 8080
- name: grpc
nodePort: 30081
port: 9090
protocol: TCP
targetPort: 9090
selector:
k8s-app: verification-service
type: NodePort