2022-09-05 03:06:08 -04:00
/ *
Copyright ( c ) Edgeless Systems GmbH
SPDX - License - Identifier : AGPL - 3.0 - only
* /
2022-05-16 12:54:25 -04:00
// This binary can be build from siderolabs/talos projects. Located at:
// https://github.com/siderolabs/talos/tree/master/hack/docgen
2022-08-05 09:30:23 -04:00
//
//go:generate docgen ./config.go ./config_doc.go Configuration
2022-03-22 11:03:15 -04:00
package config
import (
2022-05-13 05:56:43 -04:00
"errors"
2022-03-22 11:03:15 -04:00
"fmt"
2022-05-13 05:56:43 -04:00
"io/fs"
2022-08-16 09:53:54 -04:00
"regexp"
2022-09-07 05:53:44 -04:00
"strings"
2022-03-22 11:03:15 -04:00
2022-09-21 07:47:57 -04:00
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config/instancetypes"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/versions"
2022-05-23 09:01:39 -04:00
"github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
en_translations "github.com/go-playground/validator/v10/translations/en"
2022-03-22 11:03:15 -04:00
)
2022-05-18 12:10:57 -04:00
const (
Version1 = "v1"
)
2022-05-16 12:54:25 -04:00
// Config defines configuration used by CLI.
type Config struct {
2022-05-18 12:10:57 -04:00
// description: |
// Schema version of this configuration file.
2022-05-23 09:01:39 -04:00
Version string ` yaml:"version" validate:"eq=v1" `
2022-05-16 12:54:25 -04:00
// description: |
2022-05-24 05:57:48 -04:00
// Size (in GB) of a node's disk to store the non-volatile state.
StateDiskSizeGB int ` yaml:"stateDiskSizeGB" validate:"min=0" `
2022-05-16 12:54:25 -04:00
// description: |
2022-09-11 10:09:05 -04:00
// Kubernetes version to be installed in the cluster.
KubernetesVersion string ` yaml:"kubernetesVersion" validate:"supported_k8s_version" `
// description: |
// DON'T USE IN PRODUCTION: enable debug mode and use debug images. For usage, see: https://github.com/edgelesssys/constellation/blob/main/debugd/README.md
2022-09-05 10:53:37 -04:00
DebugCluster * bool ` yaml:"debugCluster" validate:"required" `
2022-05-16 12:54:25 -04:00
// description: |
2022-05-24 05:57:48 -04:00
// Supported cloud providers and their specific configurations.
2022-05-23 09:01:39 -04:00
Provider ProviderConfig ` yaml:"provider" validate:"dive" `
2022-05-16 12:54:25 -04:00
// description: |
// Create SSH users on Constellation nodes.
2022-05-17 04:52:37 -04:00
// examples:
// - value: '[]UserKey{ { Username: "Alice", PublicKey: "ssh-rsa AAAAB3NzaC...5QXHKW1rufgtJeSeJ8= alice@domain.com" } }'
2022-05-23 09:01:39 -04:00
SSHUsers [ ] UserKey ` yaml:"sshUsers,omitempty" validate:"dive" `
2022-07-18 06:28:02 -04:00
// description: |
2022-08-29 10:49:44 -04:00
// Configuration to apply during constellation upgrade.
// examples:
// - value: 'UpgradeConfig{ Image: "", Measurements: Measurements{} }'
Upgrade UpgradeConfig ` yaml:"upgrade,omitempty" `
}
// UpgradeConfig defines configuration used during constellation upgrade.
type UpgradeConfig struct {
// description: |
// Updated machine image to install on all nodes.
Image string ` yaml:"image" `
// description: |
// Measurements of the updated image.
Measurements Measurements ` yaml:"measurements" `
2022-05-17 04:52:37 -04:00
}
// UserKey describes a user that should be created with corresponding public SSH key.
type UserKey struct {
// description: |
// Username of new SSH user.
2022-05-23 09:01:39 -04:00
Username string ` yaml:"username" validate:"required" `
2022-05-17 04:52:37 -04:00
// description: |
// Public key of new SSH user.
2022-05-23 09:01:39 -04:00
PublicKey string ` yaml:"publicKey" validate:"required" `
2022-05-16 12:54:25 -04:00
}
2022-03-22 11:03:15 -04:00
2022-05-16 12:54:25 -04:00
// ProviderConfig are cloud-provider specific configuration values used by the CLI.
// Fields should remain pointer-types so custom specific configs can nil them
// if not required.
type ProviderConfig struct {
// description: |
// Configuration for Azure as provider.
2022-05-24 05:57:48 -04:00
Azure * AzureConfig ` yaml:"azure,omitempty" validate:"omitempty,dive" `
2022-05-16 12:54:25 -04:00
// description: |
// Configuration for Google Cloud as provider.
2022-05-24 05:57:48 -04:00
GCP * GCPConfig ` yaml:"gcp,omitempty" validate:"omitempty,dive" `
2022-05-16 12:54:25 -04:00
// description: |
// Configuration for QEMU as provider.
2022-05-24 05:57:48 -04:00
QEMU * QEMUConfig ` yaml:"qemu,omitempty" validate:"omitempty,dive" `
2022-05-16 12:54:25 -04:00
}
// AzureConfig are Azure specific configuration values used by the CLI.
type AzureConfig struct {
// description: |
// Subscription ID of the used Azure account. See: https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription
2022-05-23 09:01:39 -04:00
SubscriptionID string ` yaml:"subscription" validate:"uuid" `
2022-05-16 12:54:25 -04:00
// description: |
// Tenant ID of the used Azure account. See: https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-ad-tenant
2022-05-23 09:01:39 -04:00
TenantID string ` yaml:"tenant" validate:"uuid" `
2022-05-16 12:54:25 -04:00
// description: |
// Azure datacenter region to be used. See: https://docs.microsoft.com/en-us/azure/availability-zones/az-overview#azure-regions-with-availability-zones
2022-05-23 09:01:39 -04:00
Location string ` yaml:"location" validate:"required" `
2022-05-16 12:54:25 -04:00
// description: |
2022-09-11 10:09:05 -04:00
// Resource group for the cluster's resources. Must already exist.
2022-08-25 09:12:08 -04:00
ResourceGroup string ` yaml:"resourceGroup" validate:"required" `
// description: |
2022-09-02 11:11:06 -04:00
// Authorize spawned VMs to access Azure API.
UserAssignedIdentity string ` yaml:"userAssignedIdentity" validate:"required" `
// description: |
2022-08-29 08:18:05 -04:00
// Application client ID of the Active Directory app registration.
2022-09-11 10:09:05 -04:00
AppClientID string ` yaml:"appClientID" validate:"uuid" `
2022-08-29 08:18:05 -04:00
// description: |
// Client secret value of the Active Directory app registration credentials.
ClientSecretValue string ` yaml:"clientSecretValue" validate:"required" `
// description: |
2022-09-11 10:09:05 -04:00
// Machine image used to create Constellation nodes.
Image string ` yaml:"image" validate:"required" `
// description: |
// VM instance type to use for Constellation nodes.
InstanceType string ` yaml:"instanceType" validate:"azure_instance_type" `
// description: |
// Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison
StateDiskType string ` yaml:"stateDiskType" validate:"oneof=Premium_LRS Premium_ZRS Standard_LRS StandardSSD_LRS StandardSSD_ZRS" `
// description: |
2022-08-29 08:18:05 -04:00
// Expected confidential VM measurements.
Measurements Measurements ` yaml:"measurements" `
// description: |
// List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning.
EnforcedMeasurements [ ] uint32 ` yaml:"enforcedMeasurements" `
// description: |
2022-08-29 10:41:09 -04:00
// Expected value for the field 'idkeydigest' in the AMD SEV-SNP attestation report. Only usable with ConfidentialVMs. See 4.6 and 7.3 in: https://www.amd.com/system/files/TechDocs/56860.pdf
2022-10-05 09:02:46 -04:00
IDKeyDigest string ` yaml:"idKeyDigest" validate:"required_if=EnforceIdKeyDigest true,omitempty,hexadecimal,len=96" `
2022-08-29 10:41:09 -04:00
// description: |
// Enforce the specified idKeyDigest value during remote attestation.
2022-10-05 09:02:46 -04:00
EnforceIDKeyDigest * bool ` yaml:"enforceIdKeyDigest" validate:"required" `
2022-08-29 10:41:09 -04:00
// description: |
2022-09-11 10:09:05 -04:00
// Use Confidential VMs. If set to false, Trusted Launch VMs are used instead. See: https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview
2022-08-25 09:24:31 -04:00
ConfidentialVM * bool ` yaml:"confidentialVM" validate:"required" `
2022-05-16 12:54:25 -04:00
}
// GCPConfig are GCP specific configuration values used by the CLI.
type GCPConfig struct {
// description: |
// GCP project. See: https://support.google.com/googleapi/answer/7014113?hl=en
2022-05-23 09:01:39 -04:00
Project string ` yaml:"project" validate:"required" `
2022-05-16 12:54:25 -04:00
// description: |
// GCP datacenter region. See: https://cloud.google.com/compute/docs/regions-zones#available
2022-05-23 09:01:39 -04:00
Region string ` yaml:"region" validate:"required" `
2022-05-16 12:54:25 -04:00
// description: |
// GCP datacenter zone. See: https://cloud.google.com/compute/docs/regions-zones#available
2022-05-23 09:01:39 -04:00
Zone string ` yaml:"zone" validate:"required" `
2022-05-16 12:54:25 -04:00
// description: |
2022-09-11 10:09:05 -04:00
// Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization
ServiceAccountKeyPath string ` yaml:"serviceAccountKeyPath" validate:"required" `
// description: |
2022-05-16 12:54:25 -04:00
// Machine image used to create Constellation nodes.
2022-05-23 09:01:39 -04:00
Image string ` yaml:"image" validate:"required" `
2022-05-16 12:54:25 -04:00
// description: |
2022-09-11 10:09:05 -04:00
// VM instance type to use for Constellation nodes.
2022-08-31 11:35:33 -04:00
InstanceType string ` yaml:"instanceType" validate:"gcp_instance_type" `
// description: |
2022-08-02 06:24:55 -04:00
// Type of a node's state disk. The type influences boot time and I/O performance. See: https://cloud.google.com/compute/docs/disks#disk-types
StateDiskType string ` yaml:"stateDiskType" validate:"oneof=pd-standard pd-balanced pd-ssd" `
// description: |
2022-05-24 05:57:48 -04:00
// Expected confidential VM measurements.
2022-05-16 12:54:25 -04:00
Measurements Measurements ` yaml:"measurements" `
2022-08-12 09:59:45 -04:00
// description: |
// List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning.
EnforcedMeasurements [ ] uint32 ` yaml:"enforcedMeasurements" `
2022-05-16 12:54:25 -04:00
}
type QEMUConfig struct {
2022-09-26 09:52:31 -04:00
// description: |
// Path to the image to use for the VMs.
Image string ` yaml:"image" validate:"required" `
// description: |
// Format of the image to use for the VMs. Should be either qcow2 or raw.
ImageFormat string ` yaml:"imageFormat" validate:"oneof=qcow2 raw" `
// description: |
// vCPU count for the VMs.
VCPUs int ` yaml:"vcpus" validate:"required" `
// description: |
// Amount of memory per instance (MiB).
Memory int ` yaml:"memory" validate:"required" `
// description: |
// Container image to use for the QEMU metadata server.
MetadataAPIImage string ` yaml:"metadataAPIServer" validate:"required" `
2022-05-16 12:54:25 -04:00
// description: |
2022-10-05 03:11:30 -04:00
// Libvirt connection URI. Leave empty to start a libvirt instance in Docker.
LibvirtURI string ` yaml:"libvirtSocket" `
// description: |
// Container image to use for launching a containerized libvirt daemon. Only relevant if `libvirtSocket = ""`.
LibvirtContainerImage string ` yaml:"libvirtContainerImage" `
// description: |
2022-05-16 12:54:25 -04:00
// Measurement used to enable measured boot.
Measurements Measurements ` yaml:"measurements" `
2022-08-12 09:59:45 -04:00
// description: |
// List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning.
EnforcedMeasurements [ ] uint32 ` yaml:"enforcedMeasurements" `
2022-03-22 11:03:15 -04:00
}
// Default returns a struct with the default config.
func Default ( ) * Config {
return & Config {
2022-09-15 10:51:07 -04:00
Version : Version1 ,
StateDiskSizeGB : 30 ,
DebugCluster : func ( ) * bool { b := false ; return & b } ( ) ,
2022-05-16 12:54:25 -04:00
Provider : ProviderConfig {
2022-03-22 11:03:15 -04:00
Azure : & AzureConfig {
2022-08-08 05:04:17 -04:00
SubscriptionID : "" ,
TenantID : "" ,
Location : "" ,
UserAssignedIdentity : "" ,
2022-08-25 09:12:08 -04:00
ResourceGroup : "" ,
2022-08-25 08:06:29 -04:00
Image : DefaultImageAzure ,
2022-08-31 11:35:33 -04:00
InstanceType : "Standard_DC4as_v5" ,
2022-08-31 04:33:33 -04:00
StateDiskType : "Premium_LRS" ,
2022-08-12 09:59:45 -04:00
Measurements : copyPCRMap ( azurePCRs ) ,
2022-09-08 11:09:49 -04:00
EnforcedMeasurements : [ ] uint32 { 4 , 8 , 9 , 11 , 12 } ,
2022-10-05 09:02:46 -04:00
IDKeyDigest : "57486a447ec0f1958002a22a06b7673b9fd27d11e1c6527498056054c5fa92d23c50f9de44072760fe2b6fb89740b696" ,
EnforceIDKeyDigest : func ( ) * bool { b := true ; return & b } ( ) ,
2022-08-25 09:24:31 -04:00
ConfidentialVM : func ( ) * bool { b := true ; return & b } ( ) ,
2022-03-22 11:03:15 -04:00
} ,
GCP : & GCPConfig {
2022-08-23 11:49:55 -04:00
Project : "" ,
Region : "" ,
Zone : "" ,
2022-08-25 08:06:29 -04:00
Image : DefaultImageGCP ,
2022-08-31 11:35:33 -04:00
InstanceType : "n2d-standard-4" ,
2022-08-23 11:49:55 -04:00
StateDiskType : "pd-ssd" ,
2022-09-02 11:11:06 -04:00
ServiceAccountKeyPath : "" ,
2022-08-23 11:49:55 -04:00
Measurements : copyPCRMap ( gcpPCRs ) ,
2022-09-08 11:09:49 -04:00
EnforcedMeasurements : [ ] uint32 { 0 , 4 , 8 , 9 , 11 , 12 } ,
2022-03-22 11:03:15 -04:00
} ,
2022-05-02 04:54:54 -04:00
QEMU : & QEMUConfig {
2022-10-05 03:11:30 -04:00
ImageFormat : "qcow2" ,
VCPUs : 2 ,
Memory : 2048 ,
MetadataAPIImage : "ghcr.io/edgelesssys/constellation/qemu-metadata-api:v2.1.0-pre.0.20221004080046-26a21f00b8cb" ,
LibvirtURI : "" ,
LibvirtContainerImage : "ghcr.io/edgelesssys/constellation/libvirt:v2.1.0-pre.0.20221004080046-26a21f00b8cb" ,
Measurements : copyPCRMap ( qemuPCRs ) ,
EnforcedMeasurements : [ ] uint32 { 11 , 12 } ,
2022-05-02 04:54:54 -04:00
} ,
2022-03-22 11:03:15 -04:00
} ,
2022-09-02 07:57:57 -04:00
KubernetesVersion : string ( versions . Default ) ,
2022-03-22 11:03:15 -04:00
}
}
2022-07-18 06:28:02 -04:00
func validateK8sVersion ( fl validator . FieldLevel ) bool {
return versions . IsSupportedK8sVersion ( fl . Field ( ) . String ( ) )
}
2022-08-31 11:35:33 -04:00
func validateAzureInstanceType ( fl validator . FieldLevel ) bool {
azureConfig := fl . Parent ( ) . Interface ( ) . ( AzureConfig )
var acceptNonCVM bool
if azureConfig . ConfidentialVM != nil {
// This is the inverse of the config value (acceptNonCVMs is true if confidentialVM is false).
// We could make the validator the other way around, but this should be an explicit bypass rather than checking if CVMs are "allowed".
acceptNonCVM = ! * azureConfig . ConfidentialVM
}
return validInstanceTypeForProvider ( fl . Field ( ) . String ( ) , acceptNonCVM , cloudprovider . Azure )
}
func validateGCPInstanceType ( fl validator . FieldLevel ) bool {
return validInstanceTypeForProvider ( fl . Field ( ) . String ( ) , false , cloudprovider . GCP )
}
2022-09-07 05:53:44 -04:00
// validateProvider checks if zero or more than one providers are defined in the config.
func validateProvider ( sl validator . StructLevel ) {
provider := sl . Current ( ) . Interface ( ) . ( ProviderConfig )
providerCount := 0
if provider . Azure != nil {
providerCount ++
}
if provider . GCP != nil {
providerCount ++
}
if provider . QEMU != nil {
providerCount ++
}
if providerCount < 1 {
sl . ReportError ( provider , "Provider" , "Provider" , "no_provider" , "" )
} else if providerCount > 1 {
sl . ReportError ( provider , "Provider" , "Provider" , "more_than_one_provider" , "" )
}
}
2022-05-23 09:01:39 -04:00
// Validate checks the config values and returns validation error messages.
// The function only returns an error if the validation itself fails.
func ( c * Config ) Validate ( ) ( [ ] string , error ) {
trans := ut . New ( en . New ( ) ) . GetFallback ( )
validate := validator . New ( )
if err := en_translations . RegisterDefaultTranslations ( validate , trans ) ; err != nil {
return nil , err
}
2022-08-31 11:35:33 -04:00
// Register Azure & GCP InstanceType validation error types
2022-09-07 05:53:44 -04:00
if err := validate . RegisterTranslation ( "azure_instance_type" , trans , registerTranslateAzureInstanceTypeError , c . translateAzureInstanceTypeError ) ; err != nil {
2022-08-31 11:35:33 -04:00
return nil , err
}
if err := validate . RegisterTranslation ( "gcp_instance_type" , trans , registerTranslateGCPInstanceTypeError , translateGCPInstanceTypeError ) ; err != nil {
return nil , err
}
2022-09-07 05:53:44 -04:00
// Register Provider validation error types
if err := validate . RegisterTranslation ( "no_provider" , trans , registerNoProviderError , translateNoProviderError ) ; err != nil {
return nil , err
}
if err := validate . RegisterTranslation ( "more_than_one_provider" , trans , registerMoreThanOneProviderError , c . translateMoreThanOneProviderError ) ; err != nil {
return nil , err
}
2022-07-18 06:28:02 -04:00
// register custom validator with label supported_k8s_version to validate version based on available versionConfigs.
if err := validate . RegisterValidation ( "supported_k8s_version" , validateK8sVersion ) ; err != nil {
return nil , err
}
2022-08-31 11:35:33 -04:00
// register custom validator with label azure_instance_type to validate version based on available versionConfigs.
if err := validate . RegisterValidation ( "azure_instance_type" , validateAzureInstanceType ) ; err != nil {
return nil , err
}
2022-09-07 05:53:44 -04:00
// register custom validator with label gcp_instance_type to validate version based on available versionConfigs.
2022-08-31 11:35:33 -04:00
if err := validate . RegisterValidation ( "gcp_instance_type" , validateGCPInstanceType ) ; err != nil {
return nil , err
}
2022-09-07 05:53:44 -04:00
// Register provider validation
validate . RegisterStructValidation ( validateProvider , ProviderConfig { } )
2022-05-23 09:01:39 -04:00
err := validate . Struct ( c )
if err == nil {
return nil , nil
}
var errs validator . ValidationErrors
if ! errors . As ( err , & errs ) {
return nil , err
}
var msgs [ ] string
for _ , e := range errs {
msgs = append ( msgs , e . Translate ( trans ) )
}
return msgs , nil
}
2022-09-07 05:53:44 -04:00
// Validation translation functions for Azure & GCP instance type errors.
func registerTranslateAzureInstanceTypeError ( ut ut . Translator ) error {
return ut . Add ( "azure_instance_type" , "{0} must be one of {1}" , true )
}
func ( c * Config ) translateAzureInstanceTypeError ( ut ut . Translator , fe validator . FieldError ) string {
2022-08-31 11:35:33 -04:00
// Suggest trusted launch VMs if confidential VMs have been specifically disabled
2022-09-07 05:53:44 -04:00
var t string
2022-08-31 11:35:33 -04:00
if c . Provider . Azure != nil && c . Provider . Azure . ConfidentialVM != nil && ! * c . Provider . Azure . ConfidentialVM {
2022-09-07 05:53:44 -04:00
t , _ = ut . T ( "azure_instance_type" , fe . Field ( ) , fmt . Sprintf ( "%v" , instancetypes . AzureTrustedLaunchInstanceTypes ) )
} else {
t , _ = ut . T ( "azure_instance_type" , fe . Field ( ) , fmt . Sprintf ( "%v" , instancetypes . AzureCVMInstanceTypes ) )
2022-08-31 11:35:33 -04:00
}
return t
}
func registerTranslateGCPInstanceTypeError ( ut ut . Translator ) error {
return ut . Add ( "gcp_instance_type" , fmt . Sprintf ( "{0} must be one of %v" , instancetypes . GCPInstanceTypes ) , true )
}
func translateGCPInstanceTypeError ( ut ut . Translator , fe validator . FieldError ) string {
t , _ := ut . T ( "gcp_instance_type" , fe . Field ( ) )
return t
}
2022-09-07 05:53:44 -04:00
// Validation translation functions for Provider errors.
func registerNoProviderError ( ut ut . Translator ) error {
return ut . Add ( "no_provider" , "{0}: No provider has been defined (requires either Azure, GCP or QEMU)" , true )
}
func translateNoProviderError ( ut ut . Translator , fe validator . FieldError ) string {
t , _ := ut . T ( "no_provider" , fe . Field ( ) )
return t
}
func registerMoreThanOneProviderError ( ut ut . Translator ) error {
return ut . Add ( "more_than_one_provider" , "{0}: Only one provider can be defined ({1} are defined)" , true )
}
func ( c * Config ) translateMoreThanOneProviderError ( ut ut . Translator , fe validator . FieldError ) string {
definedProviders := make ( [ ] string , 0 )
// c.Provider should not be nil as Provider would need to be defined for the validation to fail in this place.
if c . Provider . Azure != nil {
definedProviders = append ( definedProviders , "Azure" )
}
if c . Provider . GCP != nil {
definedProviders = append ( definedProviders , "GCP" )
}
if c . Provider . QEMU != nil {
definedProviders = append ( definedProviders , "QEMU" )
}
// Show single string if only one other provider is defined, show list with brackets if multiple are defined.
t , _ := ut . T ( "more_than_one_provider" , fe . Field ( ) , strings . Join ( definedProviders , ", " ) )
return t
}
2022-05-23 09:01:39 -04:00
// HasProvider checks whether the config contains the provider.
func ( c * Config ) HasProvider ( provider cloudprovider . Provider ) bool {
switch provider {
case cloudprovider . Azure :
return c . Provider . Azure != nil
case cloudprovider . GCP :
return c . Provider . GCP != nil
case cloudprovider . QEMU :
return c . Provider . QEMU != nil
}
return false
}
2022-08-01 03:37:05 -04:00
// Image returns OS image for the configured cloud provider.
// If multiple cloud providers are configured (which is not supported)
// only a single image is returned.
func ( c * Config ) Image ( ) string {
if c . HasProvider ( cloudprovider . Azure ) {
return c . Provider . Azure . Image
}
if c . HasProvider ( cloudprovider . GCP ) {
return c . Provider . GCP . Image
}
return ""
}
func ( c * Config ) UpdateMeasurements ( newMeasurements Measurements ) {
if c . Provider . Azure != nil {
c . Provider . Azure . Measurements . CopyFrom ( newMeasurements )
}
if c . Provider . GCP != nil {
c . Provider . GCP . Measurements . CopyFrom ( newMeasurements )
}
if c . Provider . QEMU != nil {
c . Provider . QEMU . Measurements . CopyFrom ( newMeasurements )
}
}
2022-05-18 05:39:14 -04:00
// RemoveProviderExcept removes all provider specific configurations, i.e.,
// sets them to nil, except the one specified.
// If an unknown provider is passed, the same configuration is returned.
func ( c * Config ) RemoveProviderExcept ( provider cloudprovider . Provider ) {
currentProviderConfigs := c . Provider
c . Provider = ProviderConfig { }
switch provider {
case cloudprovider . Azure :
c . Provider . Azure = currentProviderConfigs . Azure
case cloudprovider . GCP :
c . Provider . GCP = currentProviderConfigs . GCP
case cloudprovider . QEMU :
c . Provider . QEMU = currentProviderConfigs . QEMU
default :
c . Provider = currentProviderConfigs
}
}
2022-09-06 07:06:09 -04:00
// IsDebugImage checks whether image name looks like a release image, if not it is
2022-08-16 09:53:54 -04:00
// probably a debug image. In the end we do not if bootstrapper or debugd
// was put inside an image just by looking at its name.
2022-09-06 07:06:09 -04:00
func ( c * Config ) IsDebugImage ( ) bool {
2022-08-16 09:53:54 -04:00
switch {
case c . Provider . GCP != nil :
gcpRegex := regexp . MustCompile ( ` ^projects\/constellation-images\/global\/images\/constellation-v[\d]+-[\d]+-[\d]+$ ` )
return ! gcpRegex . MatchString ( c . Provider . GCP . Image )
case c . Provider . Azure != nil :
2022-09-01 06:58:31 -04:00
azureRegex := regexp . MustCompile ( ` ^\/CommunityGalleries\/ConstellationCVM-b3782fa0-0df7-4f2f-963e-fc7fc42663df\/Images\/constellation\/Versions\/[\d]+.[\d]+.[\d]+$ ` )
2022-08-16 09:53:54 -04:00
return ! azureRegex . MatchString ( c . Provider . Azure . Image )
default :
return false
}
}
2022-08-31 05:59:07 -04:00
// GetProvider returns the configured cloud provider.
func ( c * Config ) GetProvider ( ) cloudprovider . Provider {
if c . Provider . Azure != nil {
return cloudprovider . Azure
}
if c . Provider . GCP != nil {
return cloudprovider . GCP
}
if c . Provider . QEMU != nil {
return cloudprovider . QEMU
}
return cloudprovider . Unknown
}
2022-08-25 09:24:31 -04:00
// IsAzureNonCVM checks whether the chosen provider is azure and confidential VMs are disabled.
func ( c * Config ) IsAzureNonCVM ( ) bool {
return c . Provider . Azure != nil && c . Provider . Azure . ConfidentialVM != nil && ! * c . Provider . Azure . ConfidentialVM
}
2022-10-05 09:02:46 -04:00
func ( c * Config ) EnforcesIDKeyDigest ( ) bool {
return c . Provider . Azure != nil && c . Provider . Azure . EnforceIDKeyDigest != nil && * c . Provider . Azure . EnforceIDKeyDigest
2022-08-31 14:10:49 -04:00
}
2022-05-16 12:54:25 -04:00
// FromFile returns config file with `name` read from `fileHandler` by parsing
// it as YAML.
2022-03-22 11:03:15 -04:00
func FromFile ( fileHandler file . Handler , name string ) ( * Config , error ) {
2022-08-08 05:04:17 -04:00
var conf Config
if err := fileHandler . ReadYAMLStrict ( name , & conf ) ; err != nil {
2022-05-13 05:56:43 -04:00
if errors . Is ( err , fs . ErrNotExist ) {
2022-05-16 08:20:21 -04:00
return nil , fmt . Errorf ( "unable to find %s - use `constellation config generate` to generate it first" , name )
2022-05-13 05:56:43 -04:00
}
2022-03-22 11:03:15 -04:00
return nil , fmt . Errorf ( "could not load config from file %s: %w" , name , err )
}
2022-08-08 05:04:17 -04:00
return & conf , nil
2022-03-22 11:03:15 -04:00
}
2022-08-12 09:59:45 -04:00
func copyPCRMap ( m map [ uint32 ] [ ] byte ) map [ uint32 ] [ ] byte {
res := make ( Measurements )
res . CopyFrom ( m )
return res
}
2022-08-31 11:35:33 -04:00
func validInstanceTypeForProvider ( insType string , acceptNonCVM bool , provider cloudprovider . Provider ) bool {
switch provider {
case cloudprovider . GCP :
for _ , instanceType := range instancetypes . GCPInstanceTypes {
if insType == instanceType {
return true
}
}
return false
case cloudprovider . Azure :
if acceptNonCVM {
for _ , instanceType := range instancetypes . AzureTrustedLaunchInstanceTypes {
if insType == instanceType {
return true
}
}
} else {
for _ , instanceType := range instancetypes . AzureCVMInstanceTypes {
if insType == instanceType {
return true
}
}
}
return false
default :
return false
}
}
2022-09-05 10:53:37 -04:00
// IsDebugCluster checks whether the cluster is configured as a debug cluster.
func ( c * Config ) IsDebugCluster ( ) bool {
if c . DebugCluster != nil && * c . DebugCluster {
return true
}
return false
}