mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-24 23:19:39 -05:00
Document exported funcs,types,interfaces and enable check. (#475)
* Include EXC0014 and fix issues. * Include EXC0012 and fix issues. Signed-off-by: Fabian Kammel <fk@edgeless.systems> Co-authored-by: Otto Bittner <cobittner@posteo.net>
This commit is contained in:
parent
c9873f2bfb
commit
0d12e37c96
@ -35,6 +35,9 @@ linters:
|
|||||||
issues:
|
issues:
|
||||||
max-issues-per-linter: 0
|
max-issues-per-linter: 0
|
||||||
max-same-issues: 20
|
max-same-issues: 20
|
||||||
|
include:
|
||||||
|
- EXC0012
|
||||||
|
- EXC0014
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
errcheck:
|
errcheck:
|
||||||
|
@ -10,6 +10,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Cleaner can be used to stop a list of services gracefully.
|
||||||
|
// To register an arbitrary amount of stoppers either use New or With.
|
||||||
|
// Start needs to be called to ready the Cleaner, then Clean will activate it.
|
||||||
|
// Done can be used to wait for Cleaner to run all registered stoppers.
|
||||||
type Cleaner struct {
|
type Cleaner struct {
|
||||||
stoppers []stopper
|
stoppers []stopper
|
||||||
stopC chan struct{}
|
stopC chan struct{}
|
||||||
|
@ -172,12 +172,15 @@ func (s *Server) setupDisk(masterSecret, salt []byte) error {
|
|||||||
return s.disk.UpdatePassphrase(string(diskKey))
|
return s.disk.UpdatePassphrase(string(diskKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IssuerWrapper adds VM type context to an issuer to distinguish between
|
||||||
|
// confidential and trusted launch VMs.
|
||||||
type IssuerWrapper struct {
|
type IssuerWrapper struct {
|
||||||
atls.Issuer
|
atls.Issuer
|
||||||
vmType vmtype.VMType
|
vmType vmtype.VMType
|
||||||
idkeydigest []byte
|
idkeydigest []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewIssuerWrapper creates a new issuer with VM type context.
|
||||||
func NewIssuerWrapper(issuer atls.Issuer, vmType vmtype.VMType, idkeydigest []byte) IssuerWrapper {
|
func NewIssuerWrapper(issuer atls.Issuer, vmType vmtype.VMType, idkeydigest []byte) IssuerWrapper {
|
||||||
return IssuerWrapper{
|
return IssuerWrapper{
|
||||||
Issuer: issuer,
|
Issuer: issuer,
|
||||||
@ -186,10 +189,12 @@ func NewIssuerWrapper(issuer atls.Issuer, vmType vmtype.VMType, idkeydigest []by
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VMType returns the VM type.
|
||||||
func (i *IssuerWrapper) VMType() vmtype.VMType {
|
func (i *IssuerWrapper) VMType() vmtype.VMType {
|
||||||
return i.vmType
|
return i.vmType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IDKeyDigest returns the ID key digest.
|
||||||
func (i *IssuerWrapper) IDKeyDigest() []byte {
|
func (i *IssuerWrapper) IDKeyDigest() []byte {
|
||||||
return i.idkeydigest
|
return i.idkeydigest
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,13 @@ import (
|
|||||||
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseJoinCommand(joinCommand string) (*kubeadm.BootstrapTokenDiscovery, error) {
|
// ParseJoinCommand parses API server endpoint, token and CA cert hash from
|
||||||
// Format:
|
// provided kubeadm join shell command, and returns it as a BootstrapTokenDiscovery.
|
||||||
|
//
|
||||||
|
// Expected format:
|
||||||
// kubeadm join [API_SERVER_ENDPOINT] --token [TOKEN] --discovery-token-ca-cert-hash [DISCOVERY_TOKEN_CA_CERT_HASH] --control-plane
|
// kubeadm join [API_SERVER_ENDPOINT] --token [TOKEN] --discovery-token-ca-cert-hash [DISCOVERY_TOKEN_CA_CERT_HASH] --control-plane
|
||||||
|
// .
|
||||||
|
func ParseJoinCommand(joinCommand string) (*kubeadm.BootstrapTokenDiscovery, error) {
|
||||||
// split and verify that this is a kubeadm join command
|
// split and verify that this is a kubeadm join command
|
||||||
argv, err := shlex.Split(joinCommand)
|
argv, err := shlex.Split(joinCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -112,6 +112,7 @@ func (k *KubernetesUtil) InstallComponents(ctx context.Context, version versions
|
|||||||
return enableSystemdUnit(ctx, kubeletServicePath)
|
return enableSystemdUnit(ctx, kubeletServicePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitCluster instruments kubeadm to initialize the K8s cluster.
|
||||||
func (k *KubernetesUtil) InitCluster(
|
func (k *KubernetesUtil) InitCluster(
|
||||||
ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger,
|
ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger,
|
||||||
) error {
|
) error {
|
||||||
@ -242,10 +243,12 @@ func (k *KubernetesUtil) prepareControlPlaneForKonnectivity(ctx context.Context,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupKonnectivity uses kubectl client to apply the provided konnectivity daemon set.
|
||||||
func (k *KubernetesUtil) SetupKonnectivity(kubectl Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error {
|
func (k *KubernetesUtil) SetupKonnectivity(kubectl Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error {
|
||||||
return kubectl.Apply(konnectivityAgentsDaemonSet, true)
|
return kubectl.Apply(konnectivityAgentsDaemonSet, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupPodNetworkInput holds all configuration options to setup the pod network.
|
||||||
type SetupPodNetworkInput struct {
|
type SetupPodNetworkInput struct {
|
||||||
CloudProvider string
|
CloudProvider string
|
||||||
NodeName string
|
NodeName string
|
||||||
@ -339,6 +342,7 @@ func (k *KubernetesUtil) SetupVerificationService(kubectl Client, verificationSe
|
|||||||
return kubectl.Apply(verificationServiceConfiguration, true)
|
return kubectl.Apply(verificationServiceConfiguration, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupOperatorLifecycleManager deploys operator lifecycle manager.
|
||||||
func (k *KubernetesUtil) SetupOperatorLifecycleManager(ctx context.Context, kubectl Client, olmCRDs, olmConfiguration kubernetes.Marshaler, crdNames []string) error {
|
func (k *KubernetesUtil) SetupOperatorLifecycleManager(ctx context.Context, kubectl Client, olmCRDs, olmConfiguration kubernetes.Marshaler, crdNames []string) error {
|
||||||
if err := kubectl.Apply(olmCRDs, true); err != nil {
|
if err := kubectl.Apply(olmCRDs, true); err != nil {
|
||||||
return fmt.Errorf("applying OLM CRDs: %w", err)
|
return fmt.Errorf("applying OLM CRDs: %w", err)
|
||||||
@ -351,10 +355,12 @@ func (k *KubernetesUtil) SetupOperatorLifecycleManager(ctx context.Context, kube
|
|||||||
return kubectl.Apply(olmConfiguration, true)
|
return kubectl.Apply(olmConfiguration, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupNodeMaintenanceOperator deploys node maintenance operator.
|
||||||
func (k *KubernetesUtil) SetupNodeMaintenanceOperator(kubectl Client, nodeMaintenanceOperatorConfiguration kubernetes.Marshaler) error {
|
func (k *KubernetesUtil) SetupNodeMaintenanceOperator(kubectl Client, nodeMaintenanceOperatorConfiguration kubernetes.Marshaler) error {
|
||||||
return kubectl.Apply(nodeMaintenanceOperatorConfiguration, true)
|
return kubectl.Apply(nodeMaintenanceOperatorConfiguration, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupNodeOperator deploys node operator.
|
||||||
func (k *KubernetesUtil) SetupNodeOperator(ctx context.Context, kubectl Client, nodeOperatorConfiguration kubernetes.Marshaler) error {
|
func (k *KubernetesUtil) SetupNodeOperator(ctx context.Context, kubectl Client, nodeOperatorConfiguration kubernetes.Marshaler) error {
|
||||||
return kubectl.Apply(nodeOperatorConfiguration, true)
|
return kubectl.Apply(nodeOperatorConfiguration, true)
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,10 @@ const (
|
|||||||
auditPolicyPath = "/etc/kubernetes/audit-policy.yaml"
|
auditPolicyPath = "/etc/kubernetes/audit-policy.yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// KubdeadmConfiguration is used to generate kubeadm configurations.
|
||||||
type KubdeadmConfiguration struct{}
|
type KubdeadmConfiguration struct{}
|
||||||
|
|
||||||
|
// InitConfiguration returns a new init configuration.
|
||||||
func (c *KubdeadmConfiguration) InitConfiguration(externalCloudProvider bool, k8sVersion versions.ValidK8sVersion) KubeadmInitYAML {
|
func (c *KubdeadmConfiguration) InitConfiguration(externalCloudProvider bool, k8sVersion versions.ValidK8sVersion) KubeadmInitYAML {
|
||||||
var cloudProvider string
|
var cloudProvider string
|
||||||
if externalCloudProvider {
|
if externalCloudProvider {
|
||||||
@ -171,6 +173,7 @@ func (c *KubdeadmConfiguration) InitConfiguration(externalCloudProvider bool, k8
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JoinConfiguration returns a new kubeadm join configuration.
|
||||||
func (c *KubdeadmConfiguration) JoinConfiguration(externalCloudProvider bool) KubeadmJoinYAML {
|
func (c *KubdeadmConfiguration) JoinConfiguration(externalCloudProvider bool) KubeadmJoinYAML {
|
||||||
var cloudProvider string
|
var cloudProvider string
|
||||||
if externalCloudProvider {
|
if externalCloudProvider {
|
||||||
@ -201,27 +204,33 @@ func (c *KubdeadmConfiguration) JoinConfiguration(externalCloudProvider bool) Ku
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KubeadmJoinYAML holds configuration for kubeadm join workflow.
|
||||||
type KubeadmJoinYAML struct {
|
type KubeadmJoinYAML struct {
|
||||||
JoinConfiguration kubeadm.JoinConfiguration
|
JoinConfiguration kubeadm.JoinConfiguration
|
||||||
KubeletConfiguration kubeletconf.KubeletConfiguration
|
KubeletConfiguration kubeletconf.KubeletConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNodeName sets the node name.
|
||||||
func (k *KubeadmJoinYAML) SetNodeName(nodeName string) {
|
func (k *KubeadmJoinYAML) SetNodeName(nodeName string) {
|
||||||
k.JoinConfiguration.NodeRegistration.Name = nodeName
|
k.JoinConfiguration.NodeRegistration.Name = nodeName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAPIServerEndpoint sets the api server endpoint.
|
||||||
func (k *KubeadmJoinYAML) SetAPIServerEndpoint(apiServerEndpoint string) {
|
func (k *KubeadmJoinYAML) SetAPIServerEndpoint(apiServerEndpoint string) {
|
||||||
k.JoinConfiguration.Discovery.BootstrapToken.APIServerEndpoint = apiServerEndpoint
|
k.JoinConfiguration.Discovery.BootstrapToken.APIServerEndpoint = apiServerEndpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetToken sets the boostrap token.
|
||||||
func (k *KubeadmJoinYAML) SetToken(token string) {
|
func (k *KubeadmJoinYAML) SetToken(token string) {
|
||||||
k.JoinConfiguration.Discovery.BootstrapToken.Token = token
|
k.JoinConfiguration.Discovery.BootstrapToken.Token = token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendDiscoveryTokenCaCertHash appends another trusted discovery token CA hash.
|
||||||
func (k *KubeadmJoinYAML) AppendDiscoveryTokenCaCertHash(discoveryTokenCaCertHash string) {
|
func (k *KubeadmJoinYAML) AppendDiscoveryTokenCaCertHash(discoveryTokenCaCertHash string) {
|
||||||
k.JoinConfiguration.Discovery.BootstrapToken.CACertHashes = append(k.JoinConfiguration.Discovery.BootstrapToken.CACertHashes, discoveryTokenCaCertHash)
|
k.JoinConfiguration.Discovery.BootstrapToken.CACertHashes = append(k.JoinConfiguration.Discovery.BootstrapToken.CACertHashes, discoveryTokenCaCertHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNodeIP sets the node IP.
|
||||||
func (k *KubeadmJoinYAML) SetNodeIP(nodeIP string) {
|
func (k *KubeadmJoinYAML) SetNodeIP(nodeIP string) {
|
||||||
if k.JoinConfiguration.NodeRegistration.KubeletExtraArgs == nil {
|
if k.JoinConfiguration.NodeRegistration.KubeletExtraArgs == nil {
|
||||||
k.JoinConfiguration.NodeRegistration.KubeletExtraArgs = map[string]string{"node-ip": nodeIP}
|
k.JoinConfiguration.NodeRegistration.KubeletExtraArgs = map[string]string{"node-ip": nodeIP}
|
||||||
@ -230,10 +239,12 @@ func (k *KubeadmJoinYAML) SetNodeIP(nodeIP string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderID sets the provider ID.
|
||||||
func (k *KubeadmJoinYAML) SetProviderID(providerID string) {
|
func (k *KubeadmJoinYAML) SetProviderID(providerID string) {
|
||||||
k.KubeletConfiguration.ProviderID = providerID
|
k.KubeletConfiguration.ProviderID = providerID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetControlPlane sets the control plane with the advertised address.
|
||||||
func (k *KubeadmJoinYAML) SetControlPlane(advertiseAddress string) {
|
func (k *KubeadmJoinYAML) SetControlPlane(advertiseAddress string) {
|
||||||
k.JoinConfiguration.ControlPlane = &kubeadm.JoinControlPlane{
|
k.JoinConfiguration.ControlPlane = &kubeadm.JoinControlPlane{
|
||||||
LocalAPIEndpoint: kubeadm.APIEndpoint{
|
LocalAPIEndpoint: kubeadm.APIEndpoint{
|
||||||
@ -244,21 +255,25 @@ func (k *KubeadmJoinYAML) SetControlPlane(advertiseAddress string) {
|
|||||||
k.JoinConfiguration.SkipPhases = []string{"control-plane-prepare/download-certs"}
|
k.JoinConfiguration.SkipPhases = []string{"control-plane-prepare/download-certs"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal into a k8s resource YAML.
|
||||||
func (k *KubeadmJoinYAML) Marshal() ([]byte, error) {
|
func (k *KubeadmJoinYAML) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(k)
|
return kubernetes.MarshalK8SResources(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal from a k8s resource YAML.
|
||||||
func (k *KubeadmJoinYAML) Unmarshal(yamlData []byte) (KubeadmJoinYAML, error) {
|
func (k *KubeadmJoinYAML) Unmarshal(yamlData []byte) (KubeadmJoinYAML, error) {
|
||||||
var tmp KubeadmJoinYAML
|
var tmp KubeadmJoinYAML
|
||||||
return tmp, kubernetes.UnmarshalK8SResources(yamlData, &tmp)
|
return tmp, kubernetes.UnmarshalK8SResources(yamlData, &tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KubeadmInitYAML holds configuration for kubeadm init workflow.
|
||||||
type KubeadmInitYAML struct {
|
type KubeadmInitYAML struct {
|
||||||
InitConfiguration kubeadm.InitConfiguration
|
InitConfiguration kubeadm.InitConfiguration
|
||||||
ClusterConfiguration kubeadm.ClusterConfiguration
|
ClusterConfiguration kubeadm.ClusterConfiguration
|
||||||
KubeletConfiguration kubeletconf.KubeletConfiguration
|
KubeletConfiguration kubeletconf.KubeletConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNodeName sets name of node.
|
||||||
func (k *KubeadmInitYAML) SetNodeName(nodeName string) {
|
func (k *KubeadmInitYAML) SetNodeName(nodeName string) {
|
||||||
k.InitConfiguration.NodeRegistration.Name = nodeName
|
k.InitConfiguration.NodeRegistration.Name = nodeName
|
||||||
}
|
}
|
||||||
@ -273,6 +288,7 @@ func (k *KubeadmInitYAML) SetCertSANs(certSANs []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAPIServerAdvertiseAddress sets the advertised API server address.
|
||||||
func (k *KubeadmInitYAML) SetAPIServerAdvertiseAddress(apiServerAdvertiseAddress string) {
|
func (k *KubeadmInitYAML) SetAPIServerAdvertiseAddress(apiServerAdvertiseAddress string) {
|
||||||
k.InitConfiguration.LocalAPIEndpoint.AdvertiseAddress = apiServerAdvertiseAddress
|
k.InitConfiguration.LocalAPIEndpoint.AdvertiseAddress = apiServerAdvertiseAddress
|
||||||
}
|
}
|
||||||
@ -284,18 +300,22 @@ func (k *KubeadmInitYAML) SetControlPlaneEndpoint(controlPlaneEndpoint string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetServiceCIDR sets the CIDR of service subnet.
|
||||||
func (k *KubeadmInitYAML) SetServiceCIDR(serviceCIDR string) {
|
func (k *KubeadmInitYAML) SetServiceCIDR(serviceCIDR string) {
|
||||||
k.ClusterConfiguration.Networking.ServiceSubnet = serviceCIDR
|
k.ClusterConfiguration.Networking.ServiceSubnet = serviceCIDR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPodNetworkCIDR sets the CIDR of pod subnet.
|
||||||
func (k *KubeadmInitYAML) SetPodNetworkCIDR(podNetworkCIDR string) {
|
func (k *KubeadmInitYAML) SetPodNetworkCIDR(podNetworkCIDR string) {
|
||||||
k.ClusterConfiguration.Networking.PodSubnet = podNetworkCIDR
|
k.ClusterConfiguration.Networking.PodSubnet = podNetworkCIDR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetServiceDNSDomain sets the dns domain.
|
||||||
func (k *KubeadmInitYAML) SetServiceDNSDomain(serviceDNSDomain string) {
|
func (k *KubeadmInitYAML) SetServiceDNSDomain(serviceDNSDomain string) {
|
||||||
k.ClusterConfiguration.Networking.DNSDomain = serviceDNSDomain
|
k.ClusterConfiguration.Networking.DNSDomain = serviceDNSDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNodeIP sets the node IP.
|
||||||
func (k *KubeadmInitYAML) SetNodeIP(nodeIP string) {
|
func (k *KubeadmInitYAML) SetNodeIP(nodeIP string) {
|
||||||
if k.InitConfiguration.NodeRegistration.KubeletExtraArgs == nil {
|
if k.InitConfiguration.NodeRegistration.KubeletExtraArgs == nil {
|
||||||
k.InitConfiguration.NodeRegistration.KubeletExtraArgs = map[string]string{"node-ip": nodeIP}
|
k.InitConfiguration.NodeRegistration.KubeletExtraArgs = map[string]string{"node-ip": nodeIP}
|
||||||
@ -304,6 +324,7 @@ func (k *KubeadmInitYAML) SetNodeIP(nodeIP string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProviderID sets the provider ID.
|
||||||
func (k *KubeadmInitYAML) SetProviderID(providerID string) {
|
func (k *KubeadmInitYAML) SetProviderID(providerID string) {
|
||||||
if k.InitConfiguration.NodeRegistration.KubeletExtraArgs == nil {
|
if k.InitConfiguration.NodeRegistration.KubeletExtraArgs == nil {
|
||||||
k.InitConfiguration.NodeRegistration.KubeletExtraArgs = map[string]string{"provider-id": providerID}
|
k.InitConfiguration.NodeRegistration.KubeletExtraArgs = map[string]string{"provider-id": providerID}
|
||||||
@ -312,10 +333,12 @@ func (k *KubeadmInitYAML) SetProviderID(providerID string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal into a k8s resource YAML.
|
||||||
func (k *KubeadmInitYAML) Marshal() ([]byte, error) {
|
func (k *KubeadmInitYAML) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(k)
|
return kubernetes.MarshalK8SResources(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal from a k8s resource YAML.
|
||||||
func (k *KubeadmInitYAML) Unmarshal(yamlData []byte) (KubeadmInitYAML, error) {
|
func (k *KubeadmInitYAML) Unmarshal(yamlData []byte) (KubeadmInitYAML, error) {
|
||||||
var tmp KubeadmInitYAML
|
var tmp KubeadmInitYAML
|
||||||
return tmp, kubernetes.UnmarshalK8SResources(yamlData, &tmp)
|
return tmp, kubernetes.UnmarshalK8SResources(yamlData, &tmp)
|
||||||
|
@ -121,6 +121,10 @@ func (c *Client) ListAllNamespaces(ctx context.Context) (*corev1.NamespaceList,
|
|||||||
return c.clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
|
return c.clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddTolerationsToDeployment adds [K8s tolerations] to the deployment, identified
|
||||||
|
// by name and namespace.
|
||||||
|
//
|
||||||
|
// [K8s tolerations]: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
|
||||||
func (c *Client) AddTolerationsToDeployment(ctx context.Context, tolerations []corev1.Toleration, name string, namespace string) error {
|
func (c *Client) AddTolerationsToDeployment(ctx context.Context, tolerations []corev1.Toleration, name string, namespace string) error {
|
||||||
deployments := c.clientset.AppsV1().Deployments(namespace)
|
deployments := c.clientset.AppsV1().Deployments(namespace)
|
||||||
|
|
||||||
@ -143,6 +147,10 @@ func (c *Client) AddTolerationsToDeployment(ctx context.Context, tolerations []c
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddNodeSelectorsToDeployment adds [K8s selectors] to the deployment, identified
|
||||||
|
// by name and namespace.
|
||||||
|
//
|
||||||
|
// [K8s selectors]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||||
func (c *Client) AddNodeSelectorsToDeployment(ctx context.Context, selectors map[string]string, name string, namespace string) error {
|
func (c *Client) AddNodeSelectorsToDeployment(ctx context.Context, selectors map[string]string, name string, namespace string) error {
|
||||||
deployments := c.clientset.AppsV1().Deployments(namespace)
|
deployments := c.clientset.AppsV1().Deployments(namespace)
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ func (k *Kubectl) SetKubeconfig(kubeconfig []byte) {
|
|||||||
k.kubeconfig = kubeconfig
|
k.kubeconfig = kubeconfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateConfigMap creates the provided configmap.
|
||||||
func (k *Kubectl) CreateConfigMap(ctx context.Context, configMap corev1.ConfigMap) error {
|
func (k *Kubectl) CreateConfigMap(ctx context.Context, configMap corev1.ConfigMap) error {
|
||||||
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -100,6 +101,10 @@ func (k *Kubectl) ListAllNamespaces(ctx context.Context) (*corev1.NamespaceList,
|
|||||||
return client.ListAllNamespaces(ctx)
|
return client.ListAllNamespaces(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddTolerationsToDeployment adds [K8s tolerations] to the deployment, identified
|
||||||
|
// by name and namespace.
|
||||||
|
//
|
||||||
|
// [K8s tolerations]: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
|
||||||
func (k *Kubectl) AddTolerationsToDeployment(ctx context.Context, tolerations []corev1.Toleration, name string, namespace string) error {
|
func (k *Kubectl) AddTolerationsToDeployment(ctx context.Context, tolerations []corev1.Toleration, name string, namespace string) error {
|
||||||
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -113,6 +118,10 @@ func (k *Kubectl) AddTolerationsToDeployment(ctx context.Context, tolerations []
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddNodeSelectorsToDeployment adds [K8s selectors] to the deployment, identified
|
||||||
|
// by name and namespace.
|
||||||
|
//
|
||||||
|
// [K8s selectors]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||||
func (k *Kubectl) AddNodeSelectorsToDeployment(ctx context.Context, selectors map[string]string, name string, namespace string) error {
|
func (k *Kubectl) AddNodeSelectorsToDeployment(ctx context.Context, selectors map[string]string, name string, namespace string) error {
|
||||||
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,7 +135,7 @@ func (k *Kubectl) AddNodeSelectorsToDeployment(ctx context.Context, selectors ma
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForCRD waits for a list of CRDs to be established.
|
// WaitForCRDs waits for a list of CRDs to be established.
|
||||||
func (k *Kubectl) WaitForCRDs(ctx context.Context, crds []string) error {
|
func (k *Kubectl) WaitForCRDs(ctx context.Context, crds []string) error {
|
||||||
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
client, err := k.clientGenerator.NewClient(k.kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -18,6 +18,7 @@ type AuditPolicy struct {
|
|||||||
Policy auditv1.Policy
|
Policy auditv1.Policy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDefaultAuditPolicy create a new default Constellation audit policty.
|
||||||
func NewDefaultAuditPolicy() *AuditPolicy {
|
func NewDefaultAuditPolicy() *AuditPolicy {
|
||||||
return &AuditPolicy{
|
return &AuditPolicy{
|
||||||
Policy: auditv1.Policy{
|
Policy: auditv1.Policy{
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GCPGuestAgentDaemonset is a GCP Guest Agent Daemonset.
|
||||||
type GCPGuestAgentDaemonset struct {
|
type GCPGuestAgentDaemonset struct {
|
||||||
DaemonSet apps.DaemonSet
|
DaemonSet apps.DaemonSet
|
||||||
}
|
}
|
||||||
|
@ -28,20 +28,24 @@ const (
|
|||||||
KonnectivityKeyFilename = "/etc/kubernetes/konnectivity.key"
|
KonnectivityKeyFilename = "/etc/kubernetes/konnectivity.key"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// KonnectivityAgents bundles all necessary agent deployments.
|
||||||
type KonnectivityAgents struct {
|
type KonnectivityAgents struct {
|
||||||
DaemonSet appsv1.DaemonSet
|
DaemonSet appsv1.DaemonSet
|
||||||
ClusterRoleBinding rbacv1.ClusterRoleBinding
|
ClusterRoleBinding rbacv1.ClusterRoleBinding
|
||||||
ServiceAccount corev1.ServiceAccount
|
ServiceAccount corev1.ServiceAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KonnectivityServerStaticPod deployment.
|
||||||
type KonnectivityServerStaticPod struct {
|
type KonnectivityServerStaticPod struct {
|
||||||
StaticPod corev1.Pod
|
StaticPod corev1.Pod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EgressSelectorConfiguration deployment.
|
||||||
type EgressSelectorConfiguration struct {
|
type EgressSelectorConfiguration struct {
|
||||||
EgressSelectorConfiguration apiserver.EgressSelectorConfiguration
|
EgressSelectorConfiguration apiserver.EgressSelectorConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewKonnectivityAgents create new KonnectivityAgents.
|
||||||
func NewKonnectivityAgents(konnectivityServerAddress string) *KonnectivityAgents {
|
func NewKonnectivityAgents(konnectivityServerAddress string) *KonnectivityAgents {
|
||||||
return &KonnectivityAgents{
|
return &KonnectivityAgents{
|
||||||
DaemonSet: appsv1.DaemonSet{
|
DaemonSet: appsv1.DaemonSet{
|
||||||
@ -213,6 +217,7 @@ func NewKonnectivityAgents(konnectivityServerAddress string) *KonnectivityAgents
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewKonnectivityServerStaticPod create a new KonnectivityServerStaticPod.
|
||||||
func NewKonnectivityServerStaticPod() *KonnectivityServerStaticPod {
|
func NewKonnectivityServerStaticPod() *KonnectivityServerStaticPod {
|
||||||
udsHostPathType := corev1.HostPathDirectoryOrCreate
|
udsHostPathType := corev1.HostPathDirectoryOrCreate
|
||||||
return &KonnectivityServerStaticPod{
|
return &KonnectivityServerStaticPod{
|
||||||
@ -333,6 +338,7 @@ func NewKonnectivityServerStaticPod() *KonnectivityServerStaticPod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewEgressSelectorConfiguration creates a new EgressSelectorConfiguration.
|
||||||
func NewEgressSelectorConfiguration() *EgressSelectorConfiguration {
|
func NewEgressSelectorConfiguration() *EgressSelectorConfiguration {
|
||||||
return &EgressSelectorConfiguration{
|
return &EgressSelectorConfiguration{
|
||||||
EgressSelectorConfiguration: apiserver.EgressSelectorConfiguration{
|
EgressSelectorConfiguration: apiserver.EgressSelectorConfiguration{
|
||||||
@ -357,19 +363,22 @@ func NewEgressSelectorConfiguration() *EgressSelectorConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal to Kubernetes YAML.
|
||||||
func (v *KonnectivityAgents) Marshal() ([]byte, error) {
|
func (v *KonnectivityAgents) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(v)
|
return kubernetes.MarshalK8SResources(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal to Kubernetes YAML.
|
||||||
func (v *KonnectivityServerStaticPod) Marshal() ([]byte, error) {
|
func (v *KonnectivityServerStaticPod) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(v)
|
return kubernetes.MarshalK8SResources(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal to Kubernetes YAML.
|
||||||
func (v *EgressSelectorConfiguration) Marshal() ([]byte, error) {
|
func (v *EgressSelectorConfiguration) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(v)
|
return kubernetes.MarshalK8SResources(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCertificateRequest returns a certificate request and matching private key for the konnectivity server.
|
// GetKonnectivityCertificateRequest returns a certificate request and matching private key for the konnectivity server.
|
||||||
func GetKonnectivityCertificateRequest() (certificateRequest []byte, privateKey []byte, err error) {
|
func GetKonnectivityCertificateRequest() (certificateRequest []byte, privateKey []byte, err error) {
|
||||||
csrTemplate := &x509.CertificateRequest{
|
csrTemplate := &x509.CertificateRequest{
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
|
@ -21,6 +21,7 @@ const (
|
|||||||
nodeMaintenanceOperatorCatalogNamespace = "olm"
|
nodeMaintenanceOperatorCatalogNamespace = "olm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NodeMaintenanceOperatorDeployment groups all deployments for node maintenance operator.
|
||||||
type NodeMaintenanceOperatorDeployment struct {
|
type NodeMaintenanceOperatorDeployment struct {
|
||||||
CatalogSource operatorsv1alpha1.CatalogSource
|
CatalogSource operatorsv1alpha1.CatalogSource
|
||||||
OperatorGroup operatorsv1.OperatorGroup
|
OperatorGroup operatorsv1.OperatorGroup
|
||||||
@ -80,6 +81,7 @@ func NewNodeMaintenanceOperatorDeployment() *NodeMaintenanceOperatorDeployment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal to Kubernetes YAML.
|
||||||
func (c *NodeMaintenanceOperatorDeployment) Marshal() ([]byte, error) {
|
func (c *NodeMaintenanceOperatorDeployment) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(c)
|
return kubernetes.MarshalK8SResources(c)
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ var NodeOperatorCRDNames = []string{
|
|||||||
"scalinggroups.update.edgeless.systems",
|
"scalinggroups.update.edgeless.systems",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeOperatorDeployment groups all deployments for node operator.
|
||||||
type NodeOperatorDeployment struct {
|
type NodeOperatorDeployment struct {
|
||||||
CatalogSource operatorsv1alpha1.CatalogSource
|
CatalogSource operatorsv1alpha1.CatalogSource
|
||||||
OperatorGroup operatorsv1.OperatorGroup
|
OperatorGroup operatorsv1.OperatorGroup
|
||||||
@ -93,6 +94,7 @@ func NewNodeOperatorDeployment(cloudProvider string, uid string) *NodeOperatorDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal to Kubernetes YAML.
|
||||||
func (c *NodeOperatorDeployment) Marshal() ([]byte, error) {
|
func (c *NodeOperatorDeployment) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(c)
|
return kubernetes.MarshalK8SResources(c)
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,14 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VerificationDaemonset groups all k8s resources for the verification service deployment.
|
||||||
type VerificationDaemonset struct {
|
type VerificationDaemonset struct {
|
||||||
DaemonSet apps.DaemonSet
|
DaemonSet apps.DaemonSet
|
||||||
Service k8s.Service
|
Service k8s.Service
|
||||||
LoadBalancer k8s.Service
|
LoadBalancer k8s.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewVerificationDaemonSet creates a new VerificationDaemonset.
|
||||||
func NewVerificationDaemonSet(csp, loadBalancerIP string) *VerificationDaemonset {
|
func NewVerificationDaemonSet(csp, loadBalancerIP string) *VerificationDaemonset {
|
||||||
var err error
|
var err error
|
||||||
if strings.Contains(loadBalancerIP, ":") {
|
if strings.Contains(loadBalancerIP, ":") {
|
||||||
@ -188,6 +190,7 @@ func NewVerificationDaemonSet(csp, loadBalancerIP string) *VerificationDaemonset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal to Kubernetes YAML.
|
||||||
func (v *VerificationDaemonset) Marshal() ([]byte, error) {
|
func (v *VerificationDaemonset) Marshal() ([]byte, error) {
|
||||||
return kubernetes.MarshalK8SResources(v)
|
return kubernetes.MarshalK8SResources(v)
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,13 @@ type CloudLogger interface {
|
|||||||
io.Closer
|
io.Closer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NopLogger implements CloudLogger interface, but does nothing.
|
||||||
type NopLogger struct{}
|
type NopLogger struct{}
|
||||||
|
|
||||||
|
// Disclose does nothing.
|
||||||
func (l *NopLogger) Disclose(msg string) {}
|
func (l *NopLogger) Disclose(msg string) {}
|
||||||
|
|
||||||
|
// Close does nothing.
|
||||||
func (l *NopLogger) Close() error {
|
func (l *NopLogger) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Validator validates Platform Configuration Registers (PCRs).
|
||||||
type Validator struct {
|
type Validator struct {
|
||||||
provider cloudprovider.Provider
|
provider cloudprovider.Provider
|
||||||
pcrs map[uint32][]byte
|
pcrs map[uint32][]byte
|
||||||
@ -35,6 +36,7 @@ type Validator struct {
|
|||||||
validator atls.Validator
|
validator atls.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewValidator creates a new Validator.
|
||||||
func NewValidator(provider cloudprovider.Provider, conf *config.Config) (*Validator, error) {
|
func NewValidator(provider cloudprovider.Provider, conf *config.Config) (*Validator, error) {
|
||||||
v := Validator{}
|
v := Validator{}
|
||||||
if provider == cloudprovider.Unknown {
|
if provider == cloudprovider.Unknown {
|
||||||
@ -60,6 +62,7 @@ func NewValidator(provider cloudprovider.Provider, conf *config.Config) (*Valida
|
|||||||
return &v, nil
|
return &v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateInitPCRs sets the owner and cluster PCR values.
|
||||||
func (v *Validator) UpdateInitPCRs(ownerID, clusterID string) error {
|
func (v *Validator) UpdateInitPCRs(ownerID, clusterID string) error {
|
||||||
if err := v.updatePCR(uint32(vtpm.PCRIndexOwnerID), ownerID); err != nil {
|
if err := v.updatePCR(uint32(vtpm.PCRIndexOwnerID), ownerID); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewConfigCmd creates a new config parent command. Config needs another
|
||||||
|
// verb, and does nothing on its own.
|
||||||
func NewConfigCmd() *cobra.Command {
|
func NewConfigCmd() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "config",
|
Use: "config",
|
||||||
|
@ -32,8 +32,9 @@ import (
|
|||||||
//go:generate ./generateCilium.sh
|
//go:generate ./generateCilium.sh
|
||||||
|
|
||||||
//go:embed all:charts/*
|
//go:embed all:charts/*
|
||||||
var HelmFS embed.FS
|
var helmFS embed.FS
|
||||||
|
|
||||||
|
// ChartLoader loads embedded helm charts.
|
||||||
type ChartLoader struct {
|
type ChartLoader struct {
|
||||||
joinServiceImage string
|
joinServiceImage string
|
||||||
kmsImage string
|
kmsImage string
|
||||||
@ -42,6 +43,7 @@ type ChartLoader struct {
|
|||||||
autoscalerImage string
|
autoscalerImage string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a new ChartLoader.
|
||||||
func New(csp cloudprovider.Provider, k8sVersion versions.ValidK8sVersion) *ChartLoader {
|
func New(csp cloudprovider.Provider, k8sVersion versions.ValidK8sVersion) *ChartLoader {
|
||||||
var ccmImage, cnmImage string
|
var ccmImage, cnmImage string
|
||||||
switch csp {
|
switch csp {
|
||||||
@ -63,6 +65,7 @@ func New(csp cloudprovider.Provider, k8sVersion versions.ValidK8sVersion) *Chart
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the embedded helm charts.
|
||||||
func (i *ChartLoader) Load(csp cloudprovider.Provider, conformanceMode bool, masterSecret []byte, salt []byte, enforcedPCRs []uint32, enforceIDKeyDigest bool) ([]byte, error) {
|
func (i *ChartLoader) Load(csp cloudprovider.Provider, conformanceMode bool, masterSecret []byte, salt []byte, enforcedPCRs []uint32, enforceIDKeyDigest bool) ([]byte, error) {
|
||||||
ciliumRelease, err := i.loadCilium(csp, conformanceMode)
|
ciliumRelease, err := i.loadCilium(csp, conformanceMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -83,7 +86,7 @@ func (i *ChartLoader) Load(csp cloudprovider.Provider, conformanceMode bool, mas
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *ChartLoader) loadCilium(csp cloudprovider.Provider, conformanceMode bool) (helm.Release, error) {
|
func (i *ChartLoader) loadCilium(csp cloudprovider.Provider, conformanceMode bool) (helm.Release, error) {
|
||||||
chart, err := loadChartsDir(HelmFS, "charts/cilium")
|
chart, err := loadChartsDir(helmFS, "charts/cilium")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return helm.Release{}, fmt.Errorf("loading cilium chart: %w", err)
|
return helm.Release{}, fmt.Errorf("loading cilium chart: %w", err)
|
||||||
}
|
}
|
||||||
@ -124,7 +127,7 @@ func (i *ChartLoader) loadConstellationServices(csp cloudprovider.Provider,
|
|||||||
masterSecret []byte, salt []byte, enforcedPCRs []uint32,
|
masterSecret []byte, salt []byte, enforcedPCRs []uint32,
|
||||||
enforceIDKeyDigest bool,
|
enforceIDKeyDigest bool,
|
||||||
) (helm.Release, error) {
|
) (helm.Release, error) {
|
||||||
chart, err := loadChartsDir(HelmFS, "charts/edgeless/constellation-services")
|
chart, err := loadChartsDir(helmFS, "charts/edgeless/constellation-services")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return helm.Release{}, fmt.Errorf("loading constellation-services chart: %w", err)
|
return helm.Release{}, fmt.Errorf("loading constellation-services chart: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ func (c *Client) CreateCluster(
|
|||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DestroyInstances destroys a Constellation cluster using Terraform.
|
// DestroyCluster destroys a Constellation cluster using Terraform.
|
||||||
func (c *Client) DestroyCluster(ctx context.Context) error {
|
func (c *Client) DestroyCluster(ctx context.Context) error {
|
||||||
return c.tf.Destroy(ctx)
|
return c.tf.Destroy(ctx)
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ func (v *CommonVariables) String() string {
|
|||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCPVariables is user configuration for creating a cluster with Terraform on GCP.
|
// AWSVariables is user configuration for creating a cluster with Terraform on GCP.
|
||||||
type AWSVariables struct {
|
type AWSVariables struct {
|
||||||
// CommonVariables contains common variables.
|
// CommonVariables contains common variables.
|
||||||
CommonVariables
|
CommonVariables
|
||||||
|
@ -8,6 +8,7 @@ package debugd
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
|
// Debugd internal constants.
|
||||||
const (
|
const (
|
||||||
DebugdMetadataFlag = "constellation-debugd"
|
DebugdMetadataFlag = "constellation-debugd"
|
||||||
GRPCTimeout = 5 * time.Minute
|
GRPCTimeout = 5 * time.Minute
|
||||||
|
@ -21,14 +21,21 @@ const (
|
|||||||
systemdUnitFolder = "/run/systemd/system"
|
systemdUnitFolder = "/run/systemd/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SystemdAction encodes the available actions.
|
||||||
|
//
|
||||||
//go:generate stringer -type=SystemdAction
|
//go:generate stringer -type=SystemdAction
|
||||||
type SystemdAction uint32
|
type SystemdAction uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Unknown is the default SystemdAction and does nothing.
|
||||||
Unknown SystemdAction = iota
|
Unknown SystemdAction = iota
|
||||||
|
// Start a systemd service.
|
||||||
Start
|
Start
|
||||||
|
// Stop a systemd service.
|
||||||
Stop
|
Stop
|
||||||
|
// Restart a systemd service.
|
||||||
Restart
|
Restart
|
||||||
|
// Reload a systemd service.
|
||||||
Reload
|
Reload
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,12 +30,14 @@ type Fetcher struct {
|
|||||||
metaAPI providerMetadata
|
metaAPI providerMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a new Fetcher.
|
||||||
func New(cloud providerMetadata) *Fetcher {
|
func New(cloud providerMetadata) *Fetcher {
|
||||||
return &Fetcher{
|
return &Fetcher{
|
||||||
metaAPI: cloud,
|
metaAPI: cloud,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Role returns node role via meta data API.
|
||||||
func (f *Fetcher) Role(ctx context.Context) (role.Role, error) {
|
func (f *Fetcher) Role(ctx context.Context) (role.Role, error) {
|
||||||
self, err := f.metaAPI.Self(ctx)
|
self, err := f.metaAPI.Self(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,6 +73,7 @@ func (f *Fetcher) DiscoverDebugdIPs(ctx context.Context) ([]string, error) {
|
|||||||
return ips, nil
|
return ips, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiscoverLoadbalancerIP gets load balancer IP from metadata API.
|
||||||
func (f *Fetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) {
|
func (f *Fetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) {
|
||||||
lbEndpoint, err := f.metaAPI.GetLoadBalancerEndpoint(ctx)
|
lbEndpoint, err := f.metaAPI.GetLoadBalancerEndpoint(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,22 +16,22 @@ import (
|
|||||||
// Fetcher implements metadata.Fetcher interface but does not actually fetch cloud provider metadata.
|
// Fetcher implements metadata.Fetcher interface but does not actually fetch cloud provider metadata.
|
||||||
type Fetcher struct{}
|
type Fetcher struct{}
|
||||||
|
|
||||||
|
// Role for fallback fetcher does not try to fetch role.
|
||||||
func (f Fetcher) Role(_ context.Context) (role.Role, error) {
|
func (f Fetcher) Role(_ context.Context) (role.Role, error) {
|
||||||
// Fallback fetcher does not try to fetch role
|
|
||||||
return role.Unknown, nil
|
return role.Unknown, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiscoverDebugdIPs for fallback fetcher does not try to discover debugd IPs.
|
||||||
func (f Fetcher) DiscoverDebugdIPs(ctx context.Context) ([]string, error) {
|
func (f Fetcher) DiscoverDebugdIPs(ctx context.Context) ([]string, error) {
|
||||||
// Fallback fetcher does not try to discover debugd IPs
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiscoverLoadbalancerIP for fallback fetcher does not try to discover loadbalancer IP.
|
||||||
func (f Fetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) {
|
func (f Fetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) {
|
||||||
// Fallback fetcher does not try to discover loadbalancer IP
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FetchSSHKeys for fallback fetcher does not try to fetch ssh keys.
|
||||||
func (f Fetcher) FetchSSHKeys(ctx context.Context) ([]ssh.UserKey, error) {
|
func (f Fetcher) FetchSSHKeys(ctx context.Context) ([]ssh.UserKey, error) {
|
||||||
// Fallback fetcher does not try to fetch ssh keys
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -160,14 +160,17 @@ func (s *Manager) saveConfiguration(passphrase []byte) error {
|
|||||||
return s.config.Generate(stateDiskMappedName, s.diskPath, filepath.Join(keyPath, keyFile), cryptsetupOptions)
|
return s.config.Generate(stateDiskMappedName, s.diskPath, filepath.Join(keyPath, keyFile), cryptsetupOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RecoveryServer interface serves a recovery server.
|
||||||
type RecoveryServer interface {
|
type RecoveryServer interface {
|
||||||
Serve(context.Context, net.Listener, string) (key, secret []byte, err error)
|
Serve(context.Context, net.Listener, string) (key, secret []byte, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RejoinClient interface starts a rejoin client.
|
||||||
type RejoinClient interface {
|
type RejoinClient interface {
|
||||||
Start(context.Context, string) (key, secret []byte)
|
Start(context.Context, string) (key, secret []byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeRecoverer bundles a RecoveryServer and RejoinClient.
|
||||||
type NodeRecoverer struct {
|
type NodeRecoverer struct {
|
||||||
recoveryServer RecoveryServer
|
recoveryServer RecoveryServer
|
||||||
rejoinClient RejoinClient
|
rejoinClient RejoinClient
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"gopkg.in/square/go-jose.v2/jwt"
|
"gopkg.in/square/go-jose.v2/jwt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// IsolationTEE describes an Azure SNP TEE.
|
||||||
type IsolationTEE struct {
|
type IsolationTEE struct {
|
||||||
IDKeyDigest string `json:"x-ms-sevsnpvm-idkeydigest"`
|
IDKeyDigest string `json:"x-ms-sevsnpvm-idkeydigest"`
|
||||||
TEESvn int `json:"x-ms-sevsnpvm-tee-svn"`
|
TEESvn int `json:"x-ms-sevsnpvm-tee-svn"`
|
||||||
@ -32,6 +33,7 @@ type IsolationTEE struct {
|
|||||||
GuestSvn int `json:"x-ms-sevsnpvm-guestsvn"`
|
GuestSvn int `json:"x-ms-sevsnpvm-guestsvn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrintSVNs prints the relevant Security Version Numbers (SVNs).
|
||||||
func (i *IsolationTEE) PrintSVNs() {
|
func (i *IsolationTEE) PrintSVNs() {
|
||||||
fmt.Println("\tTEE SVN:", i.TEESvn)
|
fmt.Println("\tTEE SVN:", i.TEESvn)
|
||||||
fmt.Println("\tSNP FW SVN:", i.SNPFwSvn)
|
fmt.Println("\tSNP FW SVN:", i.SNPFwSvn)
|
||||||
|
@ -17,12 +17,14 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Client for Azure Gallery API.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
opts Options
|
opts Options
|
||||||
versionClient *armcompute.GalleryImageVersionsClient
|
versionClient *armcompute.GalleryImageVersionsClient
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new Client.
|
||||||
func NewClient(log *logger.Logger, opts Options) *Client {
|
func NewClient(log *logger.Logger, opts Options) *Client {
|
||||||
log = log.Named("azure-client")
|
log = log.Named("azure-client")
|
||||||
|
|
||||||
@ -43,6 +45,7 @@ func NewClient(log *logger.Logger, opts Options) *Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FetchImages for the given client options.
|
||||||
func (c *Client) FetchImages(ctx context.Context) (map[string]string, error) {
|
func (c *Client) FetchImages(ctx context.Context) (map[string]string, error) {
|
||||||
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
|
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -13,11 +13,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// DefaultResourceGroupName to find Constellation images in.
|
||||||
DefaultResourceGroupName = "CONSTELLATION-IMAGES"
|
DefaultResourceGroupName = "CONSTELLATION-IMAGES"
|
||||||
|
// DefaultGalleryName to find Constellation images in.
|
||||||
DefaultGalleryName = "Constellation_CVM"
|
DefaultGalleryName = "Constellation_CVM"
|
||||||
|
// DefaultImageDefinition to find Constellation images in.
|
||||||
DefaultImageDefinition = "constellation"
|
DefaultImageDefinition = "constellation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Options for Azure Client to download image references.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
SubscriptionID string
|
SubscriptionID string
|
||||||
ResourceGroupName string
|
ResourceGroupName string
|
||||||
@ -25,6 +29,7 @@ type Options struct {
|
|||||||
ImageDefinition string
|
ImageDefinition string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultOptions creates an Options object with good defaults.
|
||||||
func DefaultOptions() Options {
|
func DefaultOptions() Options {
|
||||||
return Options{
|
return Options{
|
||||||
SubscriptionID: "",
|
SubscriptionID: "",
|
||||||
@ -34,6 +39,7 @@ func DefaultOptions() Options {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSubscription sets subscription from string. It expects a UUID conform value.
|
||||||
func (o *Options) SetSubscription(sub string) error {
|
func (o *Options) SetSubscription(sub string) error {
|
||||||
if _, err := uuid.Parse(sub); err != nil {
|
if _, err := uuid.Parse(sub); err != nil {
|
||||||
return fmt.Errorf("unable to set subscription: %w", err)
|
return fmt.Errorf("unable to set subscription: %w", err)
|
||||||
|
@ -16,12 +16,14 @@ import (
|
|||||||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Client for GCP Image API.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client *compute.ImagesClient
|
client *compute.ImagesClient
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
opts Options
|
opts Options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new Client.
|
||||||
func NewClient(ctx context.Context, log *logger.Logger, opts Options) *Client {
|
func NewClient(ctx context.Context, log *logger.Logger, opts Options) *Client {
|
||||||
client, err := compute.NewImagesRESTClient(ctx)
|
client, err := compute.NewImagesRESTClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,10 +37,12 @@ func NewClient(ctx context.Context, log *logger.Logger, opts Options) *Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close the GCP client.
|
||||||
func (c *Client) Close() error {
|
func (c *Client) Close() error {
|
||||||
return c.client.Close()
|
return c.client.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FetchImages for the given client options.
|
||||||
func (c *Client) FetchImages(ctx context.Context) (map[string]string, error) {
|
func (c *Client) FetchImages(ctx context.Context) (map[string]string, error) {
|
||||||
imgIterator := c.client.List(ctx, &computepb.ListImagesRequest{
|
imgIterator := c.client.List(ctx, &computepb.ListImagesRequest{
|
||||||
Project: c.opts.ProjectID,
|
Project: c.opts.ProjectID,
|
||||||
|
@ -13,16 +13,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// DefaultProjectID for Constellation images.
|
||||||
DefaultProjectID = "constellation-images"
|
DefaultProjectID = "constellation-images"
|
||||||
|
// DefaultImageFamily for Constellation images.
|
||||||
DefaultImageFamily = "constellation"
|
DefaultImageFamily = "constellation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Options for GCP image API client.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
ProjectID string
|
ProjectID string
|
||||||
ImageFamily string
|
ImageFamily string
|
||||||
Filter func(image string) (version string, err error)
|
Filter func(image string) (version string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultOptions creates an Options object with good defaults.
|
||||||
func DefaultOptions() Options {
|
func DefaultOptions() Options {
|
||||||
return Options{
|
return Options{
|
||||||
ProjectID: DefaultProjectID,
|
ProjectID: DefaultProjectID,
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// AzureSubscriptionIDEnv environment variable to provide Azure Subscription ID with.
|
||||||
AzureSubscriptionIDEnv = "AZURE_SUBSCRIPTION_ID"
|
AzureSubscriptionIDEnv = "AZURE_SUBSCRIPTION_ID"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ package main
|
|||||||
|
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
|
|
||||||
|
// Manifest contains all Constellation releases.
|
||||||
type Manifest struct {
|
type Manifest struct {
|
||||||
releases map[string]Images
|
releases map[string]Images
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Images for all supported cloud providers.
|
||||||
type Images struct {
|
type Images struct {
|
||||||
AzureOSImage string `json:"AzureOSImage"`
|
AzureOSImage string `json:"AzureOSImage"`
|
||||||
GCPOSImage string `json:"GCPOSImage"`
|
GCPOSImage string `json:"GCPOSImage"`
|
||||||
@ -50,10 +52,12 @@ func OldManifests() Manifest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON marshals releases to JSON.
|
||||||
func (m *Manifest) MarshalJSON() ([]byte, error) {
|
func (m *Manifest) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(m.releases)
|
return json.Marshal(m.releases)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAzureImage for a given version.
|
||||||
func (m *Manifest) SetAzureImage(version string, image string) {
|
func (m *Manifest) SetAzureImage(version string, image string) {
|
||||||
if release, ok := m.releases[version]; !ok {
|
if release, ok := m.releases[version]; !ok {
|
||||||
images := Images{AzureOSImage: image}
|
images := Images{AzureOSImage: image}
|
||||||
@ -64,6 +68,7 @@ func (m *Manifest) SetAzureImage(version string, image string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetGCPImage for a given version.
|
||||||
func (m *Manifest) SetGCPImage(version string, image string) {
|
func (m *Manifest) SetGCPImage(version string, image string) {
|
||||||
if release, ok := m.releases[version]; !ok {
|
if release, ok := m.releases[version]; !ok {
|
||||||
images := Images{GCPOSImage: image}
|
images := Images{GCPOSImage: image}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Server provides measurements.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
server http.Server
|
server http.Server
|
||||||
@ -23,6 +24,7 @@ type Server struct {
|
|||||||
done chan<- struct{}
|
done chan<- struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a new Server.
|
||||||
func New(log *logger.Logger, done chan<- struct{}) *Server {
|
func New(log *logger.Logger, done chan<- struct{}) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
log: log,
|
log: log,
|
||||||
@ -30,6 +32,7 @@ func New(log *logger.Logger, done chan<- struct{}) *Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListenAndServe on given port.
|
||||||
func (s *Server) ListenAndServe(port string) error {
|
func (s *Server) ListenAndServe(port string) error {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/pcrs", http.HandlerFunc(s.logPCRs))
|
mux.Handle("/pcrs", http.HandlerFunc(s.logPCRs))
|
||||||
@ -46,6 +49,7 @@ func (s *Server) ListenAndServe(port string) error {
|
|||||||
return s.server.Serve(lis)
|
return s.server.Serve(lis)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shutdown server.
|
||||||
func (s *Server) Shutdown() error {
|
func (s *Server) Shutdown() error {
|
||||||
return s.server.Shutdown(context.Background())
|
return s.server.Shutdown(context.Background())
|
||||||
}
|
}
|
||||||
@ -84,6 +88,7 @@ func (s *Server) logPCRs(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.done <- struct{}{}
|
s.done <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMeasurements returns the static measurements for QEMU environment.
|
||||||
func (s *Server) GetMeasurements() map[uint32][]byte {
|
func (s *Server) GetMeasurements() map[uint32][]byte {
|
||||||
return s.measurements
|
return s.measurements
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Measurements contains all PCR values.
|
||||||
type Measurements map[uint32][]byte
|
type Measurements map[uint32][]byte
|
||||||
|
|
||||||
var _ yaml.Marshaler = Measurements{}
|
var _ yaml.Marshaler = Measurements{}
|
||||||
|
@ -23,10 +23,12 @@ var (
|
|||||||
tagReference = regexp.MustCompile(`^refs/tags/([^/]+)$`)
|
tagReference = regexp.MustCompile(`^refs/tags/([^/]+)$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Git represents a git repository.
|
||||||
type Git struct {
|
type Git struct {
|
||||||
repo *git.Repository
|
repo *git.Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New opens the git repository in current directory.
|
||||||
func New() (*Git, error) {
|
func New() (*Git, error) {
|
||||||
repo, err := git.PlainOpenWithOptions("", &git.PlainOpenOptions{DetectDotGit: true})
|
repo, err := git.PlainOpenWithOptions("", &git.PlainOpenOptions{DetectDotGit: true})
|
||||||
return &Git{repo: repo}, err
|
return &Git{repo: repo}, err
|
||||||
@ -106,6 +108,7 @@ func (g *Git) ParsedBranchName() (string, error) {
|
|||||||
return strings.TrimSuffix(branch, "-"), nil
|
return strings.TrimSuffix(branch, "-"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BranchName of current HEAD.
|
||||||
func (g *Git) BranchName() (string, error) {
|
func (g *Git) BranchName() (string, error) {
|
||||||
commitRef, err := g.repo.Head()
|
commitRef, err := g.repo.Head()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,12 +21,14 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Server that provides QEMU metadata.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
virt virConnect
|
virt virConnect
|
||||||
network string
|
network string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a new Server.
|
||||||
func New(log *logger.Logger, network string, conn virConnect) *Server {
|
func New(log *logger.Logger, network string, conn virConnect) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
log: log,
|
log: log,
|
||||||
@ -35,6 +37,7 @@ func New(log *logger.Logger, network string, conn virConnect) *Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListenAndServe on a given port.
|
||||||
func (s *Server) ListenAndServe(port string) error {
|
func (s *Server) ListenAndServe(port string) error {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/self", http.HandlerFunc(s.listSelf))
|
mux.Handle("/self", http.HandlerFunc(s.listSelf))
|
||||||
|
@ -8,10 +8,12 @@ package virtwrapper
|
|||||||
|
|
||||||
import "libvirt.org/go/libvirt"
|
import "libvirt.org/go/libvirt"
|
||||||
|
|
||||||
|
// Connect wraps a libvirt connection.
|
||||||
type Connect struct {
|
type Connect struct {
|
||||||
Conn *libvirt.Connect
|
Conn *libvirt.Connect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LookupNetworkByName looks up a network by name.
|
||||||
func (c *Connect) LookupNetworkByName(name string) (*Network, error) {
|
func (c *Connect) LookupNetworkByName(name string) (*Network, error) {
|
||||||
net, err := c.Conn.LookupNetworkByName(name)
|
net, err := c.Conn.LookupNetworkByName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -20,14 +22,17 @@ func (c *Connect) LookupNetworkByName(name string) (*Network, error) {
|
|||||||
return &Network{Net: net}, nil
|
return &Network{Net: net}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Network wraps a libvirt network.
|
||||||
type Network struct {
|
type Network struct {
|
||||||
Net virNetwork
|
Net virNetwork
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDHCPLeases returns the underlying DHCP leases.
|
||||||
func (n *Network) GetDHCPLeases() ([]libvirt.NetworkDHCPLease, error) {
|
func (n *Network) GetDHCPLeases() ([]libvirt.NetworkDHCPLease, error) {
|
||||||
return n.Net.GetDHCPLeases()
|
return n.Net.GetDHCPLeases()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the network resource.
|
||||||
func (n *Network) Free() {
|
func (n *Network) Free() {
|
||||||
_ = n.Net.Free()
|
_ = n.Net.Free()
|
||||||
}
|
}
|
||||||
|
@ -69,11 +69,13 @@ func CreateAttestationClientTLSConfig(issuer Issuer, validators []Validator) (*t
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issuer issues an attestation document.
|
||||||
type Issuer interface {
|
type Issuer interface {
|
||||||
oid.Getter
|
oid.Getter
|
||||||
Issue(userData []byte, nonce []byte) (quote []byte, err error)
|
Issue(userData []byte, nonce []byte) (quote []byte, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validator is able to validate an attestation document.
|
||||||
type Validator interface {
|
type Validator interface {
|
||||||
oid.Getter
|
oid.Getter
|
||||||
Validate(attDoc []byte, nonce []byte) ([]byte, error)
|
Validate(attDoc []byte, nonce []byte) ([]byte, error)
|
||||||
|
@ -27,6 +27,7 @@ type Issuer struct {
|
|||||||
*vtpm.Issuer
|
*vtpm.Issuer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewIssuer creates a new OpenVTPM based issuer for AWS.
|
||||||
func NewIssuer() *Issuer {
|
func NewIssuer() *Issuer {
|
||||||
return &Issuer{
|
return &Issuer{
|
||||||
Issuer: vtpm.NewIssuer(
|
Issuer: vtpm.NewIssuer(
|
||||||
|
19
internal/attestation/azure/snp/README.md
Normal file
19
internal/attestation/azure/snp/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SNP
|
||||||
|
|
||||||
|
## Glosssary
|
||||||
|
|
||||||
|
This section explains abbreviations used in SNP implementation.
|
||||||
|
|
||||||
|
### Attestation Key (AK)
|
||||||
|
|
||||||
|
### AMD Root Key (ARK)
|
||||||
|
|
||||||
|
### AMD Signing Key (ASK)
|
||||||
|
|
||||||
|
### Versioned Chip Endorsement Key (VCEK)
|
||||||
|
|
||||||
|
For more information see [SNP WhitePaper](https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf)
|
||||||
|
|
||||||
|
### Host (Hardware?) Compatibility Layer (HCL)
|
||||||
|
|
||||||
|
No public information. Azure compute API has a field `isHostCompatibilityLayerVm`, with only a [single sentence of documentation](https://learn.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=windows).
|
@ -311,6 +311,9 @@ func (a *azureInstanceInfo) validateAk(runtimeDataRaw []byte, reportData []byte,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HCLAkValidator validates an attestation key issued by the Host Compatibility Layer (HCL).
|
||||||
|
// The HCL is written by Azure, and sits between the Hypervisor and CVM OS.
|
||||||
|
// The HCL runs in the protected context of the CVM.
|
||||||
type HCLAkValidator interface {
|
type HCLAkValidator interface {
|
||||||
validateAk(runtimeDataRaw []byte, reportData []byte, rsaParameters *tpm2.RSAParams) error
|
validateAk(runtimeDataRaw []byte, reportData []byte, rsaParameters *tpm2.RSAParams) error
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ import (
|
|||||||
"github.com/microsoft/ApplicationInsights-Go/appinsights"
|
"github.com/microsoft/ApplicationInsights-Go/appinsights"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Logger implements CloudLogger interface for Azure to Disclose early boot
|
||||||
|
// logs into Azure's App Insights service.
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
client appinsights.TelemetryClient
|
client appinsights.TelemetryClient
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,15 @@ import (
|
|||||||
type Provider uint32
|
type Provider uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Unknown is default value for Provider.
|
||||||
Unknown Provider = iota
|
Unknown Provider = iota
|
||||||
|
// AWS is Amazon Web Services.
|
||||||
AWS
|
AWS
|
||||||
|
// Azure cloud.
|
||||||
Azure
|
Azure
|
||||||
|
// GCP is Google Compute Platform.
|
||||||
GCP
|
GCP
|
||||||
|
// QEMU for a local emulated installation.
|
||||||
QEMU
|
QEMU
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"cloud.google.com/go/logging"
|
"cloud.google.com/go/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Logger logs to GCP cloud logging. Do not use to log sensitive information.
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
client *logging.Client
|
client *logging.Client
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
@ -25,6 +25,7 @@ type ServiceAccountKey struct {
|
|||||||
ClientX509CertURL string `json:"client_x509_cert_url"`
|
ClientX509CertURL string `json:"client_x509_cert_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceAccountKeyFromURI parses ServiceAccountKey from URI.
|
||||||
func ServiceAccountKeyFromURI(serviceAccountURI string) (ServiceAccountKey, error) {
|
func ServiceAccountKeyFromURI(serviceAccountURI string) (ServiceAccountKey, error) {
|
||||||
uri, err := url.Parse(serviceAccountURI)
|
uri, err := url.Parse(serviceAccountURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -35,11 +35,13 @@ type InstanceMetadata struct {
|
|||||||
AliasIPRanges []string
|
AliasIPRanges []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InstanceSelfer provide instance metadata about themselves.
|
||||||
type InstanceSelfer interface {
|
type InstanceSelfer interface {
|
||||||
// Self retrieves the current instance.
|
// Self retrieves the current instance.
|
||||||
Self(ctx context.Context) (InstanceMetadata, error)
|
Self(ctx context.Context) (InstanceMetadata, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InstanceLister list information about instance metadata.
|
||||||
type InstanceLister interface {
|
type InstanceLister interface {
|
||||||
// List retrieves all instances belonging to the current constellation.
|
// List retrieves all instances belonging to the current constellation.
|
||||||
List(ctx context.Context) ([]InstanceMetadata, error)
|
List(ctx context.Context) ([]InstanceMetadata, error)
|
||||||
|
@ -14,8 +14,11 @@ import "strings"
|
|||||||
type VMType uint32
|
type VMType uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Unknown is the default value for VMType and should not be used.
|
||||||
Unknown VMType = iota
|
Unknown VMType = iota
|
||||||
|
// AzureCVM is an Azure Confidential Virtual Machine (CVM).
|
||||||
AzureCVM
|
AzureCVM
|
||||||
|
// AzureTrustedLaunch is an Azure Trusted Launch VM.
|
||||||
AzureTrustedLaunch
|
AzureTrustedLaunch
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Version1 is the first version number for Constellation config file.
|
||||||
Version1 = "v1"
|
Version1 = "v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -217,6 +218,7 @@ type GCPConfig struct {
|
|||||||
EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"`
|
EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QEMUConfig holds config information for QEMU based Constellation deployments.
|
||||||
type QEMUConfig struct {
|
type QEMUConfig struct {
|
||||||
// description: |
|
// description: |
|
||||||
// Path to the image to use for the VMs.
|
// Path to the image to use for the VMs.
|
||||||
@ -538,6 +540,7 @@ func (c *Config) Image() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateMeasurements overwrites measurements in config with the provided ones.
|
||||||
func (c *Config) UpdateMeasurements(newMeasurements Measurements) {
|
func (c *Config) UpdateMeasurements(newMeasurements Measurements) {
|
||||||
if c.Provider.AWS != nil {
|
if c.Provider.AWS != nil {
|
||||||
c.Provider.AWS.Measurements.CopyFrom(newMeasurements)
|
c.Provider.AWS.Measurements.CopyFrom(newMeasurements)
|
||||||
@ -612,6 +615,7 @@ func (c *Config) IsAzureNonCVM() bool {
|
|||||||
return c.Provider.Azure != nil && c.Provider.Azure.ConfidentialVM != nil && !*c.Provider.Azure.ConfidentialVM
|
return c.Provider.Azure != nil && c.Provider.Azure.ConfidentialVM != nil && !*c.Provider.Azure.ConfidentialVM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnforcesIDKeyDigest checks whether ID Key Digest should be enforced for respective cloud provider.
|
||||||
func (c *Config) EnforcesIDKeyDigest() bool {
|
func (c *Config) EnforcesIDKeyDigest() bool {
|
||||||
return c.Provider.Azure != nil && c.Provider.Azure.EnforceIDKeyDigest != nil && *c.Provider.Azure.EnforceIDKeyDigest
|
return c.Provider.Azure != nil && c.Provider.Azure.EnforceIDKeyDigest != nil && *c.Provider.Azure.EnforceIDKeyDigest
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// DefaultImageAzure is not set for OSS build.
|
||||||
DefaultImageAzure = ""
|
DefaultImageAzure = ""
|
||||||
|
// DefaultImageGCP is not set for OSS build.
|
||||||
DefaultImageGCP = ""
|
DefaultImageGCP = ""
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
|
|
||||||
package instancetypes
|
package instancetypes
|
||||||
|
|
||||||
// Derived from: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enable-nitrotpm-prerequisites.html (Last updated: October 20th, 2022).
|
// AWSSupportedInstanceFamilies is derived from:
|
||||||
|
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enable-nitrotpm-prerequisites.html (Last updated: October 20th, 2022).
|
||||||
var AWSSupportedInstanceFamilies = []string{
|
var AWSSupportedInstanceFamilies = []string{
|
||||||
"C5",
|
"C5",
|
||||||
"C5a",
|
"C5a",
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Measurements are Platform Configuration Register (PCR) values.
|
||||||
type Measurements map[uint32][]byte
|
type Measurements map[uint32][]byte
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -36,36 +36,52 @@ const (
|
|||||||
JoinServicePort = 9090
|
JoinServicePort = 9090
|
||||||
// JoinServiceNodePort is the port for reaching the join service outside of Kubernetes.
|
// JoinServiceNodePort is the port for reaching the join service outside of Kubernetes.
|
||||||
JoinServiceNodePort = 30090
|
JoinServiceNodePort = 30090
|
||||||
|
// VerifyServicePortHTTP HTTP port for verification service.
|
||||||
VerifyServicePortHTTP = 8080
|
VerifyServicePortHTTP = 8080
|
||||||
|
// VerifyServicePortGRPC GRPC port for verification service.
|
||||||
VerifyServicePortGRPC = 9090
|
VerifyServicePortGRPC = 9090
|
||||||
|
// VerifyServiceNodePortHTTP HTTP node port for verification service.
|
||||||
VerifyServiceNodePortHTTP = 30080
|
VerifyServiceNodePortHTTP = 30080
|
||||||
|
// VerifyServiceNodePortGRPC GRPC node port for verification service.
|
||||||
VerifyServiceNodePortGRPC = 30081
|
VerifyServiceNodePortGRPC = 30081
|
||||||
// KMSPort is the port the KMS server listens on.
|
// KMSPort is the port the KMS server listens on.
|
||||||
KMSPort = 9000
|
KMSPort = 9000
|
||||||
|
// BootstrapperPort port of bootstrapper.
|
||||||
BootstrapperPort = 9000
|
BootstrapperPort = 9000
|
||||||
|
// KubernetesPort port for Kubernetes API.
|
||||||
KubernetesPort = 6443
|
KubernetesPort = 6443
|
||||||
|
// RecoveryPort port for Constellation recovery server.
|
||||||
RecoveryPort = 9999
|
RecoveryPort = 9999
|
||||||
EnclaveSSHPort = 2222
|
// SSHPort port for SSH access.
|
||||||
SSHPort = 22
|
SSHPort = 22
|
||||||
NVMEOverTCPPort = 8009
|
// DebugdPort port for debugd process.
|
||||||
DebugdPort = 4000
|
DebugdPort = 4000
|
||||||
|
// KonnectivityPort port for konnectivity k8s service.
|
||||||
KonnectivityPort = 8132
|
KonnectivityPort = 8132
|
||||||
// Default NodePort Range
|
// NodePortFrom start of range to use for K8s node port
|
||||||
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
||||||
NodePortFrom = 30000
|
NodePortFrom = 30000
|
||||||
|
// NodePortTo end of range to use for K8s node port
|
||||||
|
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
||||||
NodePortTo = 32767
|
NodePortTo = 32767
|
||||||
|
|
||||||
//
|
//
|
||||||
// Filenames.
|
// Filenames.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// ClusterIDsFileName filename that contains Constellation clusterID and IP.
|
||||||
ClusterIDsFileName = "constellation-id.json"
|
ClusterIDsFileName = "constellation-id.json"
|
||||||
|
// ConfigFilename filename of Constellation config file.
|
||||||
ConfigFilename = "constellation-conf.yaml"
|
ConfigFilename = "constellation-conf.yaml"
|
||||||
|
// LicenseFilename filename of Constellation license file.
|
||||||
LicenseFilename = "constellation.license"
|
LicenseFilename = "constellation.license"
|
||||||
DebugdConfigFilename = "cdbg-conf.yaml"
|
// AdminConfFilename filename of KubeConfig for admin access to Constellation.
|
||||||
AdminConfFilename = "constellation-admin.conf"
|
AdminConfFilename = "constellation-admin.conf"
|
||||||
|
// MasterSecretFilename filename of Constellation mastersecret.
|
||||||
MasterSecretFilename = "constellation-mastersecret.json"
|
MasterSecretFilename = "constellation-mastersecret.json"
|
||||||
|
// ControlPlaneAdminConfFilename filepath to control plane kubernetes admin config.
|
||||||
ControlPlaneAdminConfFilename = "/etc/kubernetes/admin.conf"
|
ControlPlaneAdminConfFilename = "/etc/kubernetes/admin.conf"
|
||||||
KubeadmCertificateDir = "/etc/kubernetes/pki"
|
// KubectlPath path to kubectl binary.
|
||||||
KubectlPath = "/run/state/bin/kubectl"
|
KubectlPath = "/run/state/bin/kubectl"
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -95,22 +111,29 @@ const (
|
|||||||
// CLI.
|
// CLI.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// MinControllerCount is the minimum number of control nodes.
|
||||||
MinControllerCount = 1
|
MinControllerCount = 1
|
||||||
|
// MinWorkerCount is the minimum number of worker nodes.
|
||||||
MinWorkerCount = 1
|
MinWorkerCount = 1
|
||||||
|
|
||||||
//
|
//
|
||||||
// Kubernetes.
|
// Kubernetes.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// KubernetesJoinTokenTTL time to live for Kubernetes join token.
|
||||||
KubernetesJoinTokenTTL = 15 * time.Minute
|
KubernetesJoinTokenTTL = 15 * time.Minute
|
||||||
|
// ConstellationNamespace namespace to deploy Constellation components into.
|
||||||
ConstellationNamespace = "kube-system"
|
ConstellationNamespace = "kube-system"
|
||||||
|
// JoinConfigMap k8s config map with node join config.
|
||||||
JoinConfigMap = "join-config"
|
JoinConfigMap = "join-config"
|
||||||
|
// InternalConfigMap k8s config map with internal Constellation config.
|
||||||
InternalConfigMap = "internal-config"
|
InternalConfigMap = "internal-config"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helm.
|
// Helm.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// HelmNamespace namespace for helm charts.
|
||||||
HelmNamespace = "kube-system"
|
HelmNamespace = "kube-system"
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -9,8 +9,16 @@ package crds
|
|||||||
import _ "embed"
|
import _ "embed"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// OLMCRDs contains olmCRDs.yaml from [OLM Release].
|
||||||
|
//
|
||||||
|
// [OLM Release]: https://github.com/operator-framework/operator-lifecycle-manager/releases
|
||||||
|
//
|
||||||
//go:embed olmCRDs.yaml
|
//go:embed olmCRDs.yaml
|
||||||
OLMCRDs []byte
|
OLMCRDs []byte
|
||||||
|
// OLM contains olm.yaml from [OLM Release].
|
||||||
|
//
|
||||||
|
// [OLM Release]: https://github.com/operator-framework/operator-lifecycle-manager/releases
|
||||||
|
//
|
||||||
//go:embed olmDeployment.yaml
|
//go:embed olmDeployment.yaml
|
||||||
OLM []byte
|
OLM []byte
|
||||||
)
|
)
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// StateDiskKeyLength is key length in bytes for node state disk.
|
||||||
StateDiskKeyLength = 32
|
StateDiskKeyLength = 32
|
||||||
// DerivedKeyLengthDefault is the default length in bytes for KMS derived keys.
|
// DerivedKeyLengthDefault is the default length in bytes for KMS derived keys.
|
||||||
DerivedKeyLengthDefault = 32
|
DerivedKeyLengthDefault = 32
|
||||||
|
@ -14,6 +14,7 @@ type Release struct {
|
|||||||
Wait bool
|
Wait bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Releases bundles all helm releases to be deployed to Constellation.
|
||||||
type Releases struct {
|
type Releases struct {
|
||||||
Cilium Release
|
Cilium Release
|
||||||
ConstellationServices Release
|
ConstellationServices Release
|
||||||
|
@ -49,8 +49,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// OptNone is a no-op.
|
||||||
OptNone = Option{optNone}
|
OptNone = Option{optNone}
|
||||||
|
// OptOverwrite overwrites an existing file.
|
||||||
OptOverwrite = Option{optOverwrite}
|
OptOverwrite = Option{optOverwrite}
|
||||||
|
// OptMkdirAll creates the path to the file.
|
||||||
OptMkdirAll = Option{optMkdirAll}
|
OptMkdirAll = Option{optMkdirAll}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,11 +15,13 @@ import (
|
|||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Credentials for attested TLS (ATLS).
|
||||||
type Credentials struct {
|
type Credentials struct {
|
||||||
issuer atls.Issuer
|
issuer atls.Issuer
|
||||||
validators []atls.Validator
|
validators []atls.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates new ATLS Credentials.
|
||||||
func New(issuer atls.Issuer, validators []atls.Validator) *Credentials {
|
func New(issuer atls.Issuer, validators []atls.Validator) *Credentials {
|
||||||
return &Credentials{
|
return &Credentials{
|
||||||
issuer: issuer,
|
issuer: issuer,
|
||||||
@ -27,6 +29,7 @@ func New(issuer atls.Issuer, validators []atls.Validator) *Credentials {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientHandshake performs the client handshake.
|
||||||
func (c *Credentials) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
func (c *Credentials) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||||
clientCfg, err := atls.CreateAttestationClientTLSConfig(c.issuer, c.validators)
|
clientCfg, err := atls.CreateAttestationClientTLSConfig(c.issuer, c.validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -36,6 +39,7 @@ func (c *Credentials) ClientHandshake(ctx context.Context, authority string, raw
|
|||||||
return credentials.NewTLS(clientCfg).ClientHandshake(ctx, authority, rawConn)
|
return credentials.NewTLS(clientCfg).ClientHandshake(ctx, authority, rawConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServerHandshake performs the server handshake.
|
||||||
func (c *Credentials) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
func (c *Credentials) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||||
serverCfg, err := atls.CreateAttestationServerTLSConfig(c.issuer, c.validators)
|
serverCfg, err := atls.CreateAttestationServerTLSConfig(c.issuer, c.validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -45,15 +49,18 @@ func (c *Credentials) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.A
|
|||||||
return credentials.NewTLS(serverCfg).ServerHandshake(rawConn)
|
return credentials.NewTLS(serverCfg).ServerHandshake(rawConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Info provides information about the protocol.
|
||||||
func (c *Credentials) Info() credentials.ProtocolInfo {
|
func (c *Credentials) Info() credentials.ProtocolInfo {
|
||||||
return credentials.NewTLS(nil).Info()
|
return credentials.NewTLS(nil).Info()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clone the credentials object.
|
||||||
func (c *Credentials) Clone() credentials.TransportCredentials {
|
func (c *Credentials) Clone() credentials.TransportCredentials {
|
||||||
cloned := *c
|
cloned := *c
|
||||||
return &cloned
|
return &cloned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OverrideServerName is not supported and will fail.
|
||||||
func (c *Credentials) OverrideServerName(s string) error {
|
func (c *Credentials) OverrideServerName(s string) error {
|
||||||
return errors.New("cannot override server name")
|
return errors.New("cannot override server name")
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,10 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Checker checks the Constellation license.
|
||||||
type Checker struct{}
|
type Checker struct{}
|
||||||
|
|
||||||
|
// NewChecker creates a new Checker.
|
||||||
func NewChecker(quotaChecker QuotaChecker, fileHandler file.Handler) *Checker {
|
func NewChecker(quotaChecker QuotaChecker, fileHandler file.Handler) *Checker {
|
||||||
return &Checker{}
|
return &Checker{}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// FromFile reads the license from fileHandler at path and returns it as a string.
|
||||||
func FromFile(fileHandler file.Handler, path string) (string, error) {
|
func FromFile(fileHandler file.Handler, path string) (string, error) {
|
||||||
readBytes, err := fileHandler.Read(path)
|
readBytes, err := fileHandler.Read(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -23,11 +23,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// Action performed by Constellation.
|
||||||
Action string
|
Action string
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Init action denotes the initialization of a Constellation cluster.
|
||||||
Init Action = "init"
|
Init Action = "init"
|
||||||
|
// test action is only to be used in testing.
|
||||||
test Action = "test"
|
test Action = "test"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -97,6 +100,7 @@ func licenseURL() *url.URL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuotaChecker checks the vCPU quota for a given license.
|
||||||
type QuotaChecker interface {
|
type QuotaChecker interface {
|
||||||
QuotaCheck(ctx context.Context, checkRequest QuotaCheckRequest) (QuotaCheckResponse, error)
|
QuotaCheck(ctx context.Context, checkRequest QuotaCheckRequest) (QuotaCheckResponse, error)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CmdLineVerbosityDescription explains numeric log levels.
|
||||||
const CmdLineVerbosityDescription = "log verbosity in zap logging levels. Use -1 for debug information, 0 for info, 1 for warn, 2 for error"
|
const CmdLineVerbosityDescription = "log verbosity in zap logging levels. Use -1 for debug information, 0 for info, 1 for warn, 2 for error"
|
||||||
|
|
||||||
// VerbosityFromInt converts a verbosity level from an integer to a zapcore.Level.
|
// VerbosityFromInt converts a verbosity level from an integer to a zapcore.Level.
|
||||||
|
@ -62,7 +62,7 @@ func (AzureSNP) OID() asn1.ObjectIdentifier {
|
|||||||
return asn1.ObjectIdentifier{1, 3, 9900, 4, 1}
|
return asn1.ObjectIdentifier{1, 3, 9900, 4, 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Azure holds the OID for Azure TrustedLaunch VMs.
|
// AzureTrustedLaunch holds the OID for Azure TrustedLaunch VMs.
|
||||||
type AzureTrustedLaunch struct{}
|
type AzureTrustedLaunch struct{}
|
||||||
|
|
||||||
// OID returns the struct's object identifier.
|
// OID returns the struct's object identifier.
|
||||||
|
@ -59,6 +59,7 @@ func (r *IntervalRetrier) Do(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doer does something and returns an error.
|
||||||
type Doer interface {
|
type Doer interface {
|
||||||
// Do performs an operation.
|
// Do performs an operation.
|
||||||
//
|
//
|
||||||
|
@ -17,10 +17,12 @@ import (
|
|||||||
type Role uint
|
type Role uint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Unknown is the default value for Role and should have no meaning.
|
||||||
Unknown Role = iota
|
Unknown Role = iota
|
||||||
|
// ControlPlane declares this node as a Kubernetes control plane node.
|
||||||
ControlPlane
|
ControlPlane
|
||||||
|
// Worker declares this node as a Kubernetes worker node.
|
||||||
Worker
|
Worker
|
||||||
Admin
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MarshalJSON marshals the Role to JSON string.
|
// MarshalJSON marshals the Role to JSON string.
|
||||||
@ -45,8 +47,6 @@ func FromString(s string) Role {
|
|||||||
return ControlPlane
|
return ControlPlane
|
||||||
case "worker":
|
case "worker":
|
||||||
return Worker
|
return Worker
|
||||||
case "admin":
|
|
||||||
return Admin
|
|
||||||
default:
|
default:
|
||||||
return Unknown
|
return Unknown
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,11 @@ func _() {
|
|||||||
_ = x[Unknown-0]
|
_ = x[Unknown-0]
|
||||||
_ = x[ControlPlane-1]
|
_ = x[ControlPlane-1]
|
||||||
_ = x[Worker-2]
|
_ = x[Worker-2]
|
||||||
_ = x[Admin-3]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Role_name = "UnknownControlPlaneWorkerAdmin"
|
const _Role_name = "UnknownControlPlaneWorker"
|
||||||
|
|
||||||
var _Role_index = [...]uint8{0, 7, 19, 25, 30}
|
var _Role_index = [...]uint8{0, 7, 19, 25}
|
||||||
|
|
||||||
func (i Role) String() string {
|
func (i Role) String() string {
|
||||||
if i >= Role(len(_Role_index)-1) {
|
if i >= Role(len(_Role_index)-1) {
|
||||||
|
@ -32,10 +32,6 @@ func TestMarshal(t *testing.T) {
|
|||||||
role: Worker,
|
role: Worker,
|
||||||
wantJSON: `"Worker"`,
|
wantJSON: `"Worker"`,
|
||||||
},
|
},
|
||||||
"admin role": {
|
|
||||||
role: Admin,
|
|
||||||
wantJSON: `"Admin"`,
|
|
||||||
},
|
|
||||||
"unknown role": {
|
"unknown role": {
|
||||||
role: Unknown,
|
role: Unknown,
|
||||||
wantJSON: `"Unknown"`,
|
wantJSON: `"Unknown"`,
|
||||||
@ -85,14 +81,6 @@ func TestUnmarshal(t *testing.T) {
|
|||||||
json: `"worker"`,
|
json: `"worker"`,
|
||||||
wantRole: Worker,
|
wantRole: Worker,
|
||||||
},
|
},
|
||||||
"Admin can be unmarshaled": {
|
|
||||||
json: `"Admin"`,
|
|
||||||
wantRole: Admin,
|
|
||||||
},
|
|
||||||
"lowercase admin can be unmarshaled": {
|
|
||||||
json: `"admin"`,
|
|
||||||
wantRole: Admin,
|
|
||||||
},
|
|
||||||
"other strings unmarshal to the unknown role": {
|
"other strings unmarshal to the unknown role": {
|
||||||
json: `"anything"`,
|
json: `"anything"`,
|
||||||
wantRole: Unknown,
|
wantRole: Unknown,
|
||||||
|
@ -42,22 +42,36 @@ func IsPreviewK8sVersion(version ValidK8sVersion) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
//
|
||||||
// Constellation images.
|
// Constellation images.
|
||||||
// These images are built in a way that they support all versions currently listed in VersionConfigs.
|
// These images are built in a way that they support all versions currently listed in VersionConfigs.
|
||||||
|
//
|
||||||
|
|
||||||
|
// KonnectivityAgentImage agent image for konnectivity service.
|
||||||
KonnectivityAgentImage = "us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent:v0.0.33@sha256:48f2a4ec3e10553a81b8dd1c6fa5fe4bcc9617f78e71c1ca89c6921335e2d7da" // renovate:container
|
KonnectivityAgentImage = "us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent:v0.0.33@sha256:48f2a4ec3e10553a81b8dd1c6fa5fe4bcc9617f78e71c1ca89c6921335e2d7da" // renovate:container
|
||||||
|
// KonnectivityServerImage server image for konnectivity service.
|
||||||
KonnectivityServerImage = "registry.k8s.io/kas-network-proxy/proxy-server:v0.0.33@sha256:2c111f004bec24888d8cfa2a812a38fb8341350abac67dcd0ac64e709dfe389c" // renovate:container
|
KonnectivityServerImage = "registry.k8s.io/kas-network-proxy/proxy-server:v0.0.33@sha256:2c111f004bec24888d8cfa2a812a38fb8341350abac67dcd0ac64e709dfe389c" // renovate:container
|
||||||
|
// JoinImage image of Constellation join service.
|
||||||
JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v2.2.0@sha256:8d2c4483e4bee8b2ed1eb32ad35298f51ad167e0aa074c9bc45c2a75ec0d1a22" // renovate:container
|
JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v2.2.0@sha256:8d2c4483e4bee8b2ed1eb32ad35298f51ad167e0aa074c9bc45c2a75ec0d1a22" // renovate:container
|
||||||
|
// AccessManagerImage image of Constellation access manager.
|
||||||
AccessManagerImage = "ghcr.io/edgelesssys/constellation/access-manager:v2.2.0@sha256:e6aa2ef3a65e7d4be25569ad9cbf6cee1dafa2c00734fa85aeb4e56a5943f88e" // renovate:container
|
AccessManagerImage = "ghcr.io/edgelesssys/constellation/access-manager:v2.2.0@sha256:e6aa2ef3a65e7d4be25569ad9cbf6cee1dafa2c00734fa85aeb4e56a5943f88e" // renovate:container
|
||||||
|
// KmsImage image of Constellation KMS server.
|
||||||
KmsImage = "ghcr.io/edgelesssys/constellation/kmsserver:v2.2.0@sha256:df72c9a8e75a848023a4b86faf3399efb8693b980e324eaa41823bc6d0a15006" // renovate:container
|
KmsImage = "ghcr.io/edgelesssys/constellation/kmsserver:v2.2.0@sha256:df72c9a8e75a848023a4b86faf3399efb8693b980e324eaa41823bc6d0a15006" // renovate:container
|
||||||
|
// VerificationImage image of Constellation verification service.
|
||||||
VerificationImage = "ghcr.io/edgelesssys/constellation/verification-service:v2.2.0@sha256:c928077e535507af7148c083bb1bde4d187eab8aee0e82be06f9b794aa2442e7" // renovate:container
|
VerificationImage = "ghcr.io/edgelesssys/constellation/verification-service:v2.2.0@sha256:c928077e535507af7148c083bb1bde4d187eab8aee0e82be06f9b794aa2442e7" // renovate:container
|
||||||
|
// GcpGuestImage image for GCP guest agent.
|
||||||
// Check for new versions at https://github.com/GoogleCloudPlatform/guest-agent/releases and update in /.github/workflows/build-gcp-guest-agent.yml.
|
// Check for new versions at https://github.com/GoogleCloudPlatform/guest-agent/releases and update in /.github/workflows/build-gcp-guest-agent.yml.
|
||||||
GcpGuestImage = "ghcr.io/edgelesssys/gcp-guest-agent:20220927.00@sha256:3dea1ae3f162d2353e6584b325f0e325a39cda5f380f41e5a0ee43c6641d3905" // renovate:container
|
GcpGuestImage = "ghcr.io/edgelesssys/gcp-guest-agent:20220927.00@sha256:3dea1ae3f162d2353e6584b325f0e325a39cda5f380f41e5a0ee43c6641d3905" // renovate:container
|
||||||
|
// NodeOperatorCatalogImage image of node operator catalog image.
|
||||||
NodeOperatorCatalogImage = "ghcr.io/edgelesssys/constellation/node-operator-catalog:v2.2.0@sha256:543ebc67183b580cfeda9e14ff3a0c5056813847ad3605719b54d72b22427a69" // renovate:container
|
NodeOperatorCatalogImage = "ghcr.io/edgelesssys/constellation/node-operator-catalog:v2.2.0@sha256:543ebc67183b580cfeda9e14ff3a0c5056813847ad3605719b54d72b22427a69" // renovate:container
|
||||||
|
// NodeMaintenanceOperatorCatalogImage image of node maintenance operator catalog.
|
||||||
// TODO: switch node maintenance operator catalog back to upstream quay.io/medik8s/node-maintenance-operator-catalog
|
// TODO: switch node maintenance operator catalog back to upstream quay.io/medik8s/node-maintenance-operator-catalog
|
||||||
// once https://github.com/medik8s/node-maintenance-operator/issues/49 is resolved.
|
// once https://github.com/medik8s/node-maintenance-operator/issues/49 is resolved.
|
||||||
NodeMaintenanceOperatorCatalogImage = "ghcr.io/edgelesssys/constellation/node-maintenance-operator-catalog:v0.13.1-alpha1@sha256:d382c3aaf9bc470cde6f6c05c2c6ff5c9dcfd90540d5b11f9cf69c4e1dd1ca9d" // renovate:container
|
NodeMaintenanceOperatorCatalogImage = "ghcr.io/edgelesssys/constellation/node-maintenance-operator-catalog:v0.13.1-alpha1@sha256:d382c3aaf9bc470cde6f6c05c2c6ff5c9dcfd90540d5b11f9cf69c4e1dd1ca9d" // renovate:container
|
||||||
|
|
||||||
|
// QEMUMetadataImage image of QEMU metadata api service.
|
||||||
QEMUMetadataImage = "ghcr.io/edgelesssys/constellation/qemu-metadata-api:v2.2.0@sha256:3c173639bbd258f56c7f4e97fa5dc7b7c63d7d45f96f7d7af5c43ed9eb2258ac" // renovate:container
|
QEMUMetadataImage = "ghcr.io/edgelesssys/constellation/qemu-metadata-api:v2.2.0@sha256:3c173639bbd258f56c7f4e97fa5dc7b7c63d7d45f96f7d7af5c43ed9eb2258ac" // renovate:container
|
||||||
|
// LibvirtImage image that provides libvirt.
|
||||||
LibvirtImage = "ghcr.io/edgelesssys/constellation/libvirt:v2.2.0@sha256:81ddc30cd679a95379e94e2f154861d9112bcabfffa96330c09a4917693f7cce" // renovate:container
|
LibvirtImage = "ghcr.io/edgelesssys/constellation/libvirt:v2.2.0@sha256:81ddc30cd679a95379e94e2f154861d9112bcabfffa96330c09a4917693f7cce" // renovate:container
|
||||||
|
|
||||||
// ConstellationQEMUImageURL is the artifact URL for QEMU qcow2 images.
|
// ConstellationQEMUImageURL is the artifact URL for QEMU qcow2 images.
|
||||||
@ -71,15 +85,18 @@ const (
|
|||||||
//nolint:revive
|
//nolint:revive
|
||||||
V1_25 ValidK8sVersion = "1.25"
|
V1_25 ValidK8sVersion = "1.25"
|
||||||
|
|
||||||
|
// Default k8s version deployed by Constellation.
|
||||||
Default ValidK8sVersion = V1_24
|
Default ValidK8sVersion = V1_24
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// NodeOperatorVersion version of node operator.
|
||||||
NodeOperatorVersion = versionFromDockerImage(NodeOperatorCatalogImage)
|
NodeOperatorVersion = versionFromDockerImage(NodeOperatorCatalogImage)
|
||||||
|
// NodeMaintenanceOperatorVersion version of node maintenance operator.
|
||||||
NodeMaintenanceOperatorVersion = versionFromDockerImage(NodeMaintenanceOperatorCatalogImage)
|
NodeMaintenanceOperatorVersion = versionFromDockerImage(NodeMaintenanceOperatorCatalogImage)
|
||||||
)
|
)
|
||||||
|
|
||||||
// versionConfigs holds download URLs for all required kubernetes components for every supported version.
|
// VersionConfigs holds download URLs for all required kubernetes components for every supported version.
|
||||||
var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{
|
var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{
|
||||||
V1_23: {
|
V1_23: {
|
||||||
PatchVersion: "v1.23.13", // renovate:kubernetes-release
|
PatchVersion: "v1.23.13", // renovate:kubernetes-release
|
||||||
|
@ -149,6 +149,7 @@ func (s *Server) IssueJoinTicket(ctx context.Context, req *joinproto.IssueJoinTi
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IssueRejoinTicket issues a ticket for nodes to rejoin cluster.
|
||||||
func (s *Server) IssueRejoinTicket(ctx context.Context, req *joinproto.IssueRejoinTicketRequest) (*joinproto.IssueRejoinTicketResponse, error) {
|
func (s *Server) IssueRejoinTicket(ctx context.Context, req *joinproto.IssueRejoinTicketRequest) (*joinproto.IssueRejoinTicketResponse, error) {
|
||||||
log := s.log.With(zap.String("peerAddress", grpclog.PeerAddrFromContext(ctx)))
|
log := s.log.With(zap.String("peerAddress", grpclog.PeerAddrFromContext(ctx)))
|
||||||
log.Infof("IssueRejoinTicket called")
|
log.Infof("IssueRejoinTicket called")
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/kms/kms/gcp"
|
"github.com/edgelesssys/constellation/v2/kms/kms/gcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Well known endpoints for KMS services.
|
||||||
const (
|
const (
|
||||||
AWSKMSURI = "kms://aws?keyPolicy=%s"
|
AWSKMSURI = "kms://aws?keyPolicy=%s"
|
||||||
AzureKMSURI = "kms://azure-kms?name=%s&type=%s"
|
AzureKMSURI = "kms://azure-kms?name=%s&type=%s"
|
||||||
@ -34,6 +35,7 @@ const (
|
|||||||
NoStoreURI = "storage://no-store"
|
NoStoreURI = "storage://no-store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// KMSInformation about an existing KMS.
|
||||||
type KMSInformation struct {
|
type KMSInformation struct {
|
||||||
KMSURI string
|
KMSURI string
|
||||||
StorageURI string
|
StorageURI string
|
||||||
|
@ -73,7 +73,7 @@ func (c *Client) GetScalingGroupName(scalingGroupID string) (string, error) {
|
|||||||
return scaleSet, nil
|
return scaleSet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScalingGroupName retrieves the name of a scaling group as needed by the cluster-autoscaler.
|
// GetAutoscalingGroupName retrieves the name of a scaling group as needed by the cluster-autoscaler.
|
||||||
func (c *Client) GetAutoscalingGroupName(scalingGroupID string) (string, error) {
|
func (c *Client) GetAutoscalingGroupName(scalingGroupID string) (string, error) {
|
||||||
return c.GetScalingGroupName(scalingGroupID)
|
return c.GetScalingGroupName(scalingGroupID)
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
package constants
|
package constants
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// AutoscalingStrategyResourceName resource name used for AutoscalingStrategy.
|
||||||
AutoscalingStrategyResourceName = "autoscalingstrategy"
|
AutoscalingStrategyResourceName = "autoscalingstrategy"
|
||||||
|
// NodeImageResourceName resource name used for NodeImage.
|
||||||
NodeImageResourceName = "constellation-os"
|
NodeImageResourceName = "constellation-os"
|
||||||
|
// ControlPlaneScalingGroupResourceName resource name used for ControlPlaneScalingGroup.
|
||||||
ControlPlaneScalingGroupResourceName = "scalinggroup-controlplane"
|
ControlPlaneScalingGroupResourceName = "scalinggroup-controlplane"
|
||||||
|
// WorkerScalingGroupResourceName resource name used for WorkerScaling.
|
||||||
WorkerScalingGroupResourceName = "scalinggroup-worker"
|
WorkerScalingGroupResourceName = "scalinggroup-worker"
|
||||||
)
|
)
|
||||||
|
@ -56,12 +56,14 @@ type diskAPI interface {
|
|||||||
opts ...gax.CallOption) (*computepb.Disk, error)
|
opts ...gax.CallOption) (*computepb.Disk, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Operation describes a generic protobuf operation that can be waited for.
|
||||||
type Operation interface {
|
type Operation interface {
|
||||||
Proto() *computepb.Operation
|
Proto() *computepb.Operation
|
||||||
Done() bool
|
Done() bool
|
||||||
Wait(ctx context.Context, opts ...gax.CallOption) error
|
Wait(ctx context.Context, opts ...gax.CallOption) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InstanceGroupManagerScopedListIterator can list the Next InstanceGroupManagersScopedListPair.
|
||||||
type InstanceGroupManagerScopedListIterator interface {
|
type InstanceGroupManagerScopedListIterator interface {
|
||||||
Next() (compute.InstanceGroupManagersScopedListPair, error)
|
Next() (compute.InstanceGroupManagersScopedListPair, error)
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func (c *Client) GetScalingGroupName(scalingGroupID string) (string, error) {
|
|||||||
return instanceGroupName, nil
|
return instanceGroupName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScalingGroupName retrieves the name of a scaling group as needed by the cluster-autoscaler.
|
// GetAutoscalingGroupName retrieves the name of a scaling group as needed by the cluster-autoscaler.
|
||||||
func (c *Client) GetAutoscalingGroupName(scalingGroupID string) (string, error) {
|
func (c *Client) GetAutoscalingGroupName(scalingGroupID string) (string, error) {
|
||||||
project, zone, instanceGroupName, err := splitInstanceGroupID(scalingGroupID)
|
project, zone, instanceGroupName, err := splitInstanceGroupID(scalingGroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -166,6 +166,7 @@ func (s *Server) getAttestationHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AttestationIssuer issues an attestation document for the provided userData and nonce.
|
||||||
type AttestationIssuer interface {
|
type AttestationIssuer interface {
|
||||||
Issue(userData []byte, nonce []byte) (quote []byte, err error)
|
Issue(userData []byte, nonce []byte) (quote []byte, err error)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user