mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-25 15:39:37 -05:00
AB#2061 Self Documenting Config File (#143)
Move firewall up into root config, remove VPC config & autogenerate comments in config file.
This commit is contained in:
parent
cdfd962fcc
commit
b905c28515
@ -11,7 +11,7 @@ import (
|
|||||||
type gcpclient interface {
|
type gcpclient interface {
|
||||||
GetState() (state.ConstellationState, error)
|
GetState() (state.ConstellationState, error)
|
||||||
SetState(state.ConstellationState) error
|
SetState(state.ConstellationState) error
|
||||||
CreateVPCs(ctx context.Context, input gcpcl.VPCsInput) error
|
CreateVPCs(ctx context.Context) error
|
||||||
CreateFirewall(ctx context.Context, input gcpcl.FirewallInput) error
|
CreateFirewall(ctx context.Context, input gcpcl.FirewallInput) error
|
||||||
CreateInstances(ctx context.Context, input gcpcl.CreateInstancesInput) error
|
CreateInstances(ctx context.Context, input gcpcl.CreateInstancesInput) error
|
||||||
CreateServiceAccount(ctx context.Context, input gcpcl.ServiceAccountInput) (string, error)
|
CreateServiceAccount(ctx context.Context, input gcpcl.ServiceAccountInput) (string, error)
|
||||||
|
@ -261,7 +261,7 @@ func (c *fakeGcpClient) SetState(stat state.ConstellationState) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeGcpClient) CreateVPCs(ctx context.Context, input gcpcl.VPCsInput) error {
|
func (c *fakeGcpClient) CreateVPCs(ctx context.Context) error {
|
||||||
c.network = "network"
|
c.network = "network"
|
||||||
c.subnetwork = "subnetwork"
|
c.subnetwork = "subnetwork"
|
||||||
return nil
|
return nil
|
||||||
@ -377,7 +377,7 @@ func (c *stubGcpClient) SetState(state.ConstellationState) error {
|
|||||||
return c.setStateErr
|
return c.setStateErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *stubGcpClient) CreateVPCs(ctx context.Context, input gcpcl.VPCsInput) error {
|
func (c *stubGcpClient) CreateVPCs(ctx context.Context) error {
|
||||||
return c.createVPCsErr
|
return c.createVPCsErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
azurecl "github.com/edgelesssys/constellation/cli/azure/client"
|
azurecl "github.com/edgelesssys/constellation/cli/azure/client"
|
||||||
|
"github.com/edgelesssys/constellation/cli/cloud/cloudtypes"
|
||||||
"github.com/edgelesssys/constellation/cli/cloudprovider"
|
"github.com/edgelesssys/constellation/cli/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/cli/gcp"
|
"github.com/edgelesssys/constellation/cli/gcp"
|
||||||
"github.com/edgelesssys/constellation/cli/gcp/client"
|
"github.com/edgelesssys/constellation/cli/gcp/client"
|
||||||
@ -41,9 +42,9 @@ func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, c
|
|||||||
case cloudprovider.GCP:
|
case cloudprovider.GCP:
|
||||||
cl, err := c.newGCPClient(
|
cl, err := c.newGCPClient(
|
||||||
ctx,
|
ctx,
|
||||||
*config.Provider.GCP.Project,
|
config.Provider.GCP.Project,
|
||||||
*config.Provider.GCP.Zone,
|
config.Provider.GCP.Zone,
|
||||||
*config.Provider.GCP.Region,
|
config.Provider.GCP.Region,
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -53,10 +54,10 @@ func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, c
|
|||||||
return c.createGCP(ctx, cl, config, insType, coordCount, nodeCount)
|
return c.createGCP(ctx, cl, config, insType, coordCount, nodeCount)
|
||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
cl, err := c.newAzureClient(
|
cl, err := c.newAzureClient(
|
||||||
*config.Provider.Azure.SubscriptionID,
|
config.Provider.Azure.SubscriptionID,
|
||||||
*config.Provider.Azure.TenantID,
|
config.Provider.Azure.TenantID,
|
||||||
name,
|
name,
|
||||||
*config.Provider.Azure.Location,
|
config.Provider.Azure.Location,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return state.ConstellationState{}, err
|
return state.ConstellationState{}, err
|
||||||
@ -71,19 +72,22 @@ func (c *Creator) createGCP(ctx context.Context, cl gcpclient, config *config.Co
|
|||||||
) (stat state.ConstellationState, retErr error) {
|
) (stat state.ConstellationState, retErr error) {
|
||||||
defer rollbackOnError(context.Background(), c.out, &retErr, &rollbackerGCP{client: cl})
|
defer rollbackOnError(context.Background(), c.out, &retErr, &rollbackerGCP{client: cl})
|
||||||
|
|
||||||
if err := cl.CreateVPCs(ctx, *config.Provider.GCP.VPCsInput); err != nil {
|
if err := cl.CreateVPCs(ctx); err != nil {
|
||||||
return state.ConstellationState{}, err
|
return state.ConstellationState{}, err
|
||||||
}
|
}
|
||||||
if err := cl.CreateFirewall(ctx, *config.Provider.GCP.FirewallInput); err != nil {
|
if err := cl.CreateFirewall(ctx, gcpcl.FirewallInput{
|
||||||
|
Ingress: cloudtypes.Firewall(config.IngressFirewall),
|
||||||
|
Egress: cloudtypes.Firewall(config.EgressFirewall),
|
||||||
|
}); err != nil {
|
||||||
return state.ConstellationState{}, err
|
return state.ConstellationState{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
createInput := client.CreateInstancesInput{
|
createInput := client.CreateInstancesInput{
|
||||||
CountCoordinators: coordCount,
|
CountCoordinators: coordCount,
|
||||||
CountNodes: nodeCount,
|
CountNodes: nodeCount,
|
||||||
ImageId: *config.Provider.GCP.Image,
|
ImageId: config.Provider.GCP.Image,
|
||||||
InstanceType: insType,
|
InstanceType: insType,
|
||||||
StateDiskSizeGB: *config.StateDiskSizeGB,
|
StateDiskSizeGB: config.StateDiskSizeGB,
|
||||||
KubeEnv: gcp.KubeEnv,
|
KubeEnv: gcp.KubeEnv,
|
||||||
}
|
}
|
||||||
if err := cl.CreateInstances(ctx, createInput); err != nil {
|
if err := cl.CreateInstances(ctx, createInput); err != nil {
|
||||||
@ -103,16 +107,20 @@ func (c *Creator) createAzure(ctx context.Context, cl azureclient, config *confi
|
|||||||
if err := cl.CreateVirtualNetwork(ctx); err != nil {
|
if err := cl.CreateVirtualNetwork(ctx); err != nil {
|
||||||
return state.ConstellationState{}, err
|
return state.ConstellationState{}, err
|
||||||
}
|
}
|
||||||
if err := cl.CreateSecurityGroup(ctx, *config.Provider.Azure.NetworkSecurityGroupInput); err != nil {
|
|
||||||
|
if err := cl.CreateSecurityGroup(ctx, azurecl.NetworkSecurityGroupInput{
|
||||||
|
Ingress: cloudtypes.Firewall(config.IngressFirewall),
|
||||||
|
Egress: cloudtypes.Firewall(config.EgressFirewall),
|
||||||
|
}); err != nil {
|
||||||
return state.ConstellationState{}, err
|
return state.ConstellationState{}, err
|
||||||
}
|
}
|
||||||
createInput := azurecl.CreateInstancesInput{
|
createInput := azurecl.CreateInstancesInput{
|
||||||
CountCoordinators: coordCount,
|
CountCoordinators: coordCount,
|
||||||
CountNodes: nodeCount,
|
CountNodes: nodeCount,
|
||||||
InstanceType: insType,
|
InstanceType: insType,
|
||||||
StateDiskSizeGB: *config.StateDiskSizeGB,
|
StateDiskSizeGB: config.StateDiskSizeGB,
|
||||||
Image: *config.Provider.Azure.Image,
|
Image: config.Provider.Azure.Image,
|
||||||
UserAssingedIdentity: *config.Provider.Azure.UserAssignedIdentity,
|
UserAssingedIdentity: config.Provider.Azure.UserAssignedIdentity,
|
||||||
}
|
}
|
||||||
if err := cl.CreateInstances(ctx, createInput); err != nil {
|
if err := cl.CreateInstances(ctx, createInput); err != nil {
|
||||||
return state.ConstellationState{}, err
|
return state.ConstellationState{}, err
|
||||||
|
@ -73,7 +73,7 @@ func (c *ServiceAccountCreator) createServiceAccountGCP(ctx context.Context, cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
input := gcpcl.ServiceAccountInput{
|
input := gcpcl.ServiceAccountInput{
|
||||||
Roles: *config.Provider.GCP.ServiceAccountRoles,
|
Roles: config.Provider.GCP.ServiceAccountRoles,
|
||||||
}
|
}
|
||||||
serviceAccount, err := cl.CreateServiceAccount(ctx, input)
|
serviceAccount, err := cl.CreateServiceAccount(ctx, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -68,19 +68,19 @@ func (v *Validators) updatePCR(pcrIndex uint32, encoded string) error {
|
|||||||
func (v *Validators) setPCRs(config *config.Config) error {
|
func (v *Validators) setPCRs(config *config.Config) error {
|
||||||
switch v.provider {
|
switch v.provider {
|
||||||
case cloudprovider.GCP:
|
case cloudprovider.GCP:
|
||||||
gcpPCRs := *config.Provider.GCP.Measurements
|
gcpPCRs := config.Provider.GCP.Measurements
|
||||||
if err := v.checkPCRs(gcpPCRs); err != nil {
|
if err := v.checkPCRs(gcpPCRs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.pcrs = gcpPCRs
|
v.pcrs = gcpPCRs
|
||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
azurePCRs := *config.Provider.Azure.Measurements
|
azurePCRs := config.Provider.Azure.Measurements
|
||||||
if err := v.checkPCRs(azurePCRs); err != nil {
|
if err := v.checkPCRs(azurePCRs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.pcrs = azurePCRs
|
v.pcrs = azurePCRs
|
||||||
case cloudprovider.QEMU:
|
case cloudprovider.QEMU:
|
||||||
qemuPCRs := *config.Provider.QEMU.Measurements
|
qemuPCRs := config.Provider.QEMU.Measurements
|
||||||
if err := v.checkPCRs(qemuPCRs); err != nil {
|
if err := v.checkPCRs(qemuPCRs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -66,18 +66,18 @@ func TestNewValidators(t *testing.T) {
|
|||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
conf := &config.Config{Provider: &config.ProviderConfig{}}
|
conf := &config.Config{Provider: config.ProviderConfig{}}
|
||||||
if tc.provider == cloudprovider.GCP {
|
if tc.provider == cloudprovider.GCP {
|
||||||
measurements := config.Measurements(tc.pcrs)
|
measurements := config.Measurements(tc.pcrs)
|
||||||
conf.Provider.GCP = &config.GCPConfig{Measurements: &measurements}
|
conf.Provider.GCP = &config.GCPConfig{Measurements: measurements}
|
||||||
}
|
}
|
||||||
if tc.provider == cloudprovider.Azure {
|
if tc.provider == cloudprovider.Azure {
|
||||||
measurements := config.Measurements(tc.pcrs)
|
measurements := config.Measurements(tc.pcrs)
|
||||||
conf.Provider.Azure = &config.AzureConfig{Measurements: &measurements}
|
conf.Provider.Azure = &config.AzureConfig{Measurements: measurements}
|
||||||
}
|
}
|
||||||
if tc.provider == cloudprovider.QEMU {
|
if tc.provider == cloudprovider.QEMU {
|
||||||
measurements := config.Measurements(tc.pcrs)
|
measurements := config.Measurements(tc.pcrs)
|
||||||
conf.Provider.QEMU = &config.QEMUConfig{Measurements: &measurements}
|
conf.Provider.QEMU = &config.QEMUConfig{Measurements: measurements}
|
||||||
}
|
}
|
||||||
|
|
||||||
validators, err := NewValidators(tc.provider, conf)
|
validators, err := NewValidators(tc.provider, conf)
|
||||||
|
@ -6,20 +6,14 @@ import (
|
|||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
|
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
|
||||||
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
|
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
|
||||||
|
"github.com/edgelesssys/constellation/internal/config"
|
||||||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FirewallRule struct {
|
type FirewallRule = config.FirewallRule
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
Protocol string
|
|
||||||
IPRange string
|
|
||||||
FromPort int
|
|
||||||
ToPort int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Firewall []FirewallRule
|
type Firewall config.Firewall
|
||||||
|
|
||||||
func (f Firewall) GCP() ([]*computepb.Firewall, error) {
|
func (f Firewall) GCP() ([]*computepb.Firewall, error) {
|
||||||
var fw []*computepb.Firewall
|
var fw []*computepb.Firewall
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/file"
|
"github.com/edgelesssys/constellation/internal/file"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"gopkg.in/yaml.v3"
|
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newConfigGenerateCmd() *cobra.Command {
|
func newConfigGenerateCmd() *cobra.Command {
|
||||||
@ -38,7 +38,12 @@ func configGenerate(cmd *cobra.Command, fileHandler file.Handler) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if flags.file == "-" {
|
if flags.file == "-" {
|
||||||
return yaml.NewEncoder(cmd.OutOrStdout()).Encode(config.Default())
|
content, err := encoder.NewEncoder(config.Default()).Encode()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = cmd.OutOrStdout().Write(content)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileHandler.WriteYAML(flags.file, config.Default(), 0o644)
|
return fileHandler.WriteYAML(flags.file, config.Default(), 0o644)
|
||||||
|
@ -13,12 +13,6 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func defaultConfigAsYAML(t *testing.T) string {
|
|
||||||
var readBuffer bytes.Buffer
|
|
||||||
require.NoError(t, yaml.NewEncoder(&readBuffer).Encode(config.Default()))
|
|
||||||
return readBuffer.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConfigGenerateDefault(t *testing.T) {
|
func TestConfigGenerateDefault(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
@ -28,9 +22,10 @@ func TestConfigGenerateDefault(t *testing.T) {
|
|||||||
|
|
||||||
require.NoError(configGenerate(cmd, fileHandler))
|
require.NoError(configGenerate(cmd, fileHandler))
|
||||||
|
|
||||||
readYAML, err := fileHandler.Read(constants.ConfigFilename)
|
var readConfig config.Config
|
||||||
|
err := fileHandler.ReadYAML(constants.ConfigFilename, &readConfig)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal(defaultConfigAsYAML(t), string(readYAML))
|
assert.Equal(*config.Default(), readConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigGenerateDefaultExists(t *testing.T) {
|
func TestConfigGenerateDefaultExists(t *testing.T) {
|
||||||
@ -66,5 +61,8 @@ func TestConfigGenerateStdOut(t *testing.T) {
|
|||||||
|
|
||||||
require.NoError(configGenerate(cmd, fileHandler))
|
require.NoError(configGenerate(cmd, fileHandler))
|
||||||
|
|
||||||
assert.Equal(defaultConfigAsYAML(t), outBuffer.String())
|
var readConfig config.Config
|
||||||
|
require.NoError(yaml.NewDecoder(&outBuffer).Decode(&readConfig))
|
||||||
|
|
||||||
|
assert.Equal(*config.Default(), readConfig)
|
||||||
}
|
}
|
||||||
|
@ -460,7 +460,7 @@ func getGCPInstances(stat state.ConstellationState, config *config.Config) (coor
|
|||||||
// TODO: make min / max configurable and abstract autoscaling for different cloud providers
|
// TODO: make min / max configurable and abstract autoscaling for different cloud providers
|
||||||
nodes = ScalingGroup{
|
nodes = ScalingGroup{
|
||||||
Instances: nodeInstances,
|
Instances: nodeInstances,
|
||||||
GroupID: gcp.AutoscalingNodeGroup(stat.GCPProject, stat.GCPZone, stat.GCPNodeInstanceGroup, *config.AutoscalingNodeGroupsMin, *config.AutoscalingNodeGroupsMax),
|
GroupID: gcp.AutoscalingNodeGroup(stat.GCPProject, stat.GCPZone, stat.GCPNodeInstanceGroup, config.AutoscalingNodeGroupsMin, config.AutoscalingNodeGroupsMax),
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -493,7 +493,7 @@ func getAzureInstances(stat state.ConstellationState, config *config.Config) (co
|
|||||||
// TODO: make min / max configurable and abstract autoscaling for different cloud providers
|
// TODO: make min / max configurable and abstract autoscaling for different cloud providers
|
||||||
nodes = ScalingGroup{
|
nodes = ScalingGroup{
|
||||||
Instances: nodeInstances,
|
Instances: nodeInstances,
|
||||||
GroupID: azure.AutoscalingNodeGroup(stat.AzureNodesScaleSet, *config.AutoscalingNodeGroupsMin, *config.AutoscalingNodeGroupsMax),
|
GroupID: azure.AutoscalingNodeGroup(stat.AzureNodesScaleSet, config.AutoscalingNodeGroupsMin, config.AutoscalingNodeGroupsMax),
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -78,14 +78,8 @@ type FirewallInput struct {
|
|||||||
Egress cloudtypes.Firewall
|
Egress cloudtypes.Firewall
|
||||||
}
|
}
|
||||||
|
|
||||||
// VPCsInput defines the VPC configuration.
|
|
||||||
type VPCsInput struct {
|
|
||||||
SubnetCIDR string
|
|
||||||
SubnetExtCIDR string
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateVPCs creates all necessary VPC networks.
|
// CreateVPCs creates all necessary VPC networks.
|
||||||
func (c *Client) CreateVPCs(ctx context.Context, input VPCsInput) error {
|
func (c *Client) CreateVPCs(ctx context.Context) error {
|
||||||
c.network = c.name + "-" + c.uid
|
c.network = c.name + "-" + c.uid
|
||||||
|
|
||||||
op, err := c.createVPC(ctx, c.network)
|
op, err := c.createVPC(ctx, c.network)
|
||||||
@ -96,7 +90,7 @@ func (c *Client) CreateVPCs(ctx context.Context, input VPCsInput) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.createSubnets(ctx, input.SubnetCIDR); err != nil {
|
if err := c.createSubnets(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +146,11 @@ func (c *Client) terminateVPC(ctx context.Context, network string) (Operation, e
|
|||||||
return c.networksAPI.Delete(ctx, req)
|
return c.networksAPI.Delete(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) createSubnets(ctx context.Context, subnetCIDR string) error {
|
func (c *Client) createSubnets(ctx context.Context) error {
|
||||||
c.subnetwork = "node-net-" + c.uid
|
c.subnetwork = "node-net-" + c.uid
|
||||||
c.secondarySubnetworkRange = "net-ext" + c.uid
|
c.secondarySubnetworkRange = "net-ext" + c.uid
|
||||||
|
|
||||||
op, err := c.createSubnet(ctx, c.subnetwork, subnetCIDR, c.network, c.secondarySubnetworkRange)
|
op, err := c.createSubnet(ctx, c.subnetwork, c.network, c.secondarySubnetworkRange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -164,12 +158,12 @@ func (c *Client) createSubnets(ctx context.Context, subnetCIDR string) error {
|
|||||||
return c.waitForOperations(ctx, []Operation{op})
|
return c.waitForOperations(ctx, []Operation{op})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) createSubnet(ctx context.Context, name, cidr, network, secondaryRangeName string) (Operation, error) {
|
func (c *Client) createSubnet(ctx context.Context, name, network, secondaryRangeName string) (Operation, error) {
|
||||||
req := &computepb.InsertSubnetworkRequest{
|
req := &computepb.InsertSubnetworkRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
Region: c.region,
|
||||||
SubnetworkResource: &computepb.Subnetwork{
|
SubnetworkResource: &computepb.Subnetwork{
|
||||||
IpCidrRange: proto.String(cidr),
|
IpCidrRange: proto.String("192.168.178.0/24"),
|
||||||
Name: proto.String(name),
|
Name: proto.String(name),
|
||||||
Network: proto.String("projects/" + c.project + "/global/networks/" + network),
|
Network: proto.String("projects/" + c.project + "/global/networks/" + network),
|
||||||
SecondaryIpRanges: []*computepb.SubnetworkSecondaryRange{
|
SecondaryIpRanges: []*computepb.SubnetworkSecondaryRange{
|
||||||
|
@ -13,11 +13,6 @@ import (
|
|||||||
func TestCreateVPCs(t *testing.T) {
|
func TestCreateVPCs(t *testing.T) {
|
||||||
someErr := errors.New("failed")
|
someErr := errors.New("failed")
|
||||||
|
|
||||||
testInput := VPCsInput{
|
|
||||||
SubnetCIDR: "192.0.2.0/24",
|
|
||||||
SubnetExtCIDR: "198.51.100.0/24",
|
|
||||||
}
|
|
||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
operationGlobalAPI operationGlobalAPI
|
operationGlobalAPI operationGlobalAPI
|
||||||
operationRegionAPI operationRegionAPI
|
operationRegionAPI operationRegionAPI
|
||||||
@ -80,9 +75,9 @@ func TestCreateVPCs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(client.CreateVPCs(ctx, testInput))
|
assert.Error(client.CreateVPCs(ctx))
|
||||||
} else {
|
} else {
|
||||||
assert.NoError(client.CreateVPCs(ctx, testInput))
|
assert.NoError(client.CreateVPCs(ctx))
|
||||||
assert.NotNil(client.network)
|
assert.NotNil(client.network)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -85,7 +85,7 @@ func getGCPInstances(stat state.ConstellationState, config *configc.Config) (coo
|
|||||||
// TODO: make min / max configurable and abstract autoscaling for different cloud providers
|
// TODO: make min / max configurable and abstract autoscaling for different cloud providers
|
||||||
nodes = cmdc.ScalingGroup{
|
nodes = cmdc.ScalingGroup{
|
||||||
Instances: nodeInstances,
|
Instances: nodeInstances,
|
||||||
GroupID: gcp.AutoscalingNodeGroup(stat.GCPProject, stat.GCPZone, stat.GCPNodeInstanceGroup, *config.AutoscalingNodeGroupsMin, *config.AutoscalingNodeGroupsMax),
|
GroupID: gcp.AutoscalingNodeGroup(stat.GCPProject, stat.GCPZone, stat.GCPNodeInstanceGroup, config.AutoscalingNodeGroupsMin, config.AutoscalingNodeGroupsMax),
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
3
go.mod
3
go.mod
@ -77,6 +77,7 @@ require (
|
|||||||
github.com/spf13/afero v1.8.2
|
github.com/spf13/afero v1.8.2
|
||||||
github.com/spf13/cobra v1.4.0
|
github.com/spf13/cobra v1.4.0
|
||||||
github.com/stretchr/testify v1.7.1
|
github.com/stretchr/testify v1.7.1
|
||||||
|
github.com/talos-systems/talos/pkg/machinery v1.0.4
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
|
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
|
||||||
github.com/willdonnelly/passwd v0.0.0-20141013001024-7935dab3074c
|
github.com/willdonnelly/passwd v0.0.0-20141013001024-7935dab3074c
|
||||||
go.etcd.io/etcd/client/v3 v3.5.2
|
go.etcd.io/etcd/client/v3 v3.5.2
|
||||||
@ -90,7 +91,7 @@ require (
|
|||||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e
|
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e
|
||||||
google.golang.org/grpc v1.45.0
|
google.golang.org/grpc v1.45.0
|
||||||
google.golang.org/protobuf v1.27.1
|
google.golang.org/protobuf v1.27.1
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99
|
||||||
k8s.io/api v0.24.0
|
k8s.io/api v0.24.0
|
||||||
k8s.io/apimachinery v0.24.0
|
k8s.io/apimachinery v0.24.0
|
||||||
k8s.io/cli-runtime v0.24.0
|
k8s.io/cli-runtime v0.24.0
|
||||||
|
5
go.sum
5
go.sum
@ -1402,6 +1402,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
|
|||||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
|
github.com/talos-systems/talos/pkg/machinery v1.0.4 h1:zUZgIRSxAXOI6LygMDUqgS0rtFTf4DpDCL35UpW/6s4=
|
||||||
|
github.com/talos-systems/talos/pkg/machinery v1.0.4/go.mod h1:cJ/031WJGDnGQLW+zp+0lwkEn47orpJdfsJDf0BQVGM=
|
||||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||||
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
||||||
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
|
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
|
||||||
@ -2280,8 +2282,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
|||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99 h1:dbuHpmKjkDzSOMKAWl10QNlgaZUd3V1q99xc81tt2Kc=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
//go:generate docgen ./config.go ./config_doc.go Configuration
|
||||||
|
// This binary can be build from siderolabs/talos projects. Located at:
|
||||||
|
// https://github.com/siderolabs/talos/tree/master/hack/docgen
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -5,119 +8,133 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
|
||||||
azureClient "github.com/edgelesssys/constellation/cli/azure/client"
|
|
||||||
"github.com/edgelesssys/constellation/cli/cloud/cloudtypes"
|
|
||||||
"github.com/edgelesssys/constellation/cli/ec2"
|
|
||||||
awsClient "github.com/edgelesssys/constellation/cli/ec2/client"
|
|
||||||
gcpClient "github.com/edgelesssys/constellation/cli/gcp/client"
|
|
||||||
"github.com/edgelesssys/constellation/coordinator/attestation/vtpm"
|
|
||||||
"github.com/edgelesssys/constellation/internal/constants"
|
"github.com/edgelesssys/constellation/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/internal/deploy/ssh"
|
"github.com/edgelesssys/constellation/internal/deploy/ssh"
|
||||||
"github.com/edgelesssys/constellation/internal/file"
|
"github.com/edgelesssys/constellation/internal/file"
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// Config defines configuration used by CLI.
|
||||||
// gcpPCRs is a map of the expected PCR values for a GCP Constellation node.
|
|
||||||
// TODO: Get a full list once we have stable releases.
|
|
||||||
gcpPCRs = Measurements{
|
|
||||||
0: {0x0F, 0x35, 0xC2, 0x14, 0x60, 0x8D, 0x93, 0xC7, 0xA6, 0xE6, 0x8A, 0xE7, 0x35, 0x9B, 0x4A, 0x8B, 0xE5, 0xA0, 0xE9, 0x9E, 0xEA, 0x91, 0x07, 0xEC, 0xE4, 0x27, 0xC4, 0xDE, 0xA4, 0xE4, 0x39, 0xCF},
|
|
||||||
uint32(vtpm.PCRIndexOwnerID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
||||||
uint32(vtpm.PCRIndexClusterID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
||||||
}
|
|
||||||
|
|
||||||
// azurePCRs is a map of the expected PCR values for an Azure Constellation node.
|
|
||||||
// TODO: Get a full list once we have a working setup with stable releases.
|
|
||||||
azurePCRs = Measurements{
|
|
||||||
uint32(vtpm.PCRIndexOwnerID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
||||||
uint32(vtpm.PCRIndexClusterID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
||||||
}
|
|
||||||
|
|
||||||
qemuPCRs = Measurements{
|
|
||||||
uint32(vtpm.PCRIndexOwnerID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
||||||
uint32(vtpm.PCRIndexClusterID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config defines a configuration used by the CLI.
|
|
||||||
// All fields in this struct and its child structs have pointer types
|
|
||||||
// to ensure the default values of the actual type is not confused with an omitted value.
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AutoscalingNodeGroupsMin *int `yaml:"autoscalingNodeGroupsMin,omitempty"`
|
// description: |
|
||||||
AutoscalingNodeGroupsMax *int `yaml:"autoscalingNodeGroupsMax,omitempty"`
|
// Minimum number of nodes in autoscaling group.
|
||||||
StateDiskSizeGB *int `yaml:"StateDisksizeGB,omitempty"`
|
// worker nodes.
|
||||||
Provider *ProviderConfig `yaml:"provider,omitempty"`
|
AutoscalingNodeGroupsMin int `yaml:"autoscalingNodeGroupsMin"`
|
||||||
|
// description: |
|
||||||
|
// Maximum number of nodes in autoscaling group.
|
||||||
|
// worker nodes.
|
||||||
|
AutoscalingNodeGroupsMax int `yaml:"autoscalingNodeGroupsMax"`
|
||||||
|
// description: |
|
||||||
|
// Size (in GB) of data disk used for nodes.
|
||||||
|
StateDiskSizeGB int `yaml:"stateDisksizeGB"`
|
||||||
|
// description: |
|
||||||
|
// Ingress firewall rules for node network.
|
||||||
|
IngressFirewall Firewall `yaml:"ingressFirewall,omitempty"`
|
||||||
|
// description: |
|
||||||
|
// Egress firewall rules for node network.
|
||||||
|
EgressFirewall Firewall `yaml:"egressFirewall,omitempty"`
|
||||||
|
// description: |
|
||||||
|
// Supported cloud providers & their specific configurations.
|
||||||
|
Provider ProviderConfig `yaml:"provider"`
|
||||||
|
// description: |
|
||||||
|
// Create SSH users on Constellation nodes.
|
||||||
SSHUsers []*ssh.UserKey `yaml:"sshUsers,omitempty"`
|
SSHUsers []*ssh.UserKey `yaml:"sshUsers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FirewallRule struct {
|
||||||
|
// description: |
|
||||||
|
// Name of rule.
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
// description: |
|
||||||
|
// Description for rule.
|
||||||
|
Description string `yaml:"description"`
|
||||||
|
// description: |
|
||||||
|
// Protocol, such as 'udp' or 'tcp'.
|
||||||
|
Protocol string `yaml:"protocol"`
|
||||||
|
// description: |
|
||||||
|
// CIDR range for which this rule is applied.
|
||||||
|
IPRange string `yaml:"iprange"`
|
||||||
|
// description: |
|
||||||
|
// Port of start port of a range.
|
||||||
|
FromPort int `yaml:"fromport"`
|
||||||
|
// description: |
|
||||||
|
// End port of a range, or 0 if a single port is given by FromPort.
|
||||||
|
ToPort int `yaml:"toport"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Firewall []FirewallRule
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
Azure *AzureConfig `yaml:"azureConfig,omitempty"`
|
||||||
|
// description: |
|
||||||
|
// Configuration for Google Cloud as provider.
|
||||||
|
GCP *GCPConfig `yaml:"gcpConfig,omitempty"`
|
||||||
|
// description: |
|
||||||
|
// Configuration for QEMU as provider.
|
||||||
|
QEMU *QEMUConfig `yaml:"qemuConfig,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
SubscriptionID string `yaml:"subscription"`
|
||||||
|
// 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
|
||||||
|
TenantID string `yaml:"tenant"`
|
||||||
|
// description: |
|
||||||
|
// Azure datacenter region to be used. See: https://docs.microsoft.com/en-us/azure/availability-zones/az-overview#azure-regions-with-availability-zones
|
||||||
|
Location string `yaml:"location"`
|
||||||
|
// description: |
|
||||||
|
// Machine image used to create Constellation nodes.
|
||||||
|
Image string `yaml:"image"`
|
||||||
|
// description: |
|
||||||
|
// Expected confidential VM measurements.
|
||||||
|
Measurements Measurements `yaml:"measurements"`
|
||||||
|
// description: |
|
||||||
|
// Authorize spawned VMs to access Azure API. See: https://constellation-docs.edgeless.systems/6c320851-bdd2-41d5-bf10-e27427398692/#/getting-started/install?id=azure
|
||||||
|
UserAssignedIdentity string `yaml:"userassignedIdentity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
Project string `yaml:"project"`
|
||||||
|
// description: |
|
||||||
|
// GCP datacenter region. See: https://cloud.google.com/compute/docs/regions-zones#available
|
||||||
|
Region string `yaml:"region"`
|
||||||
|
// description: |
|
||||||
|
// GCP datacenter zone. See: https://cloud.google.com/compute/docs/regions-zones#available
|
||||||
|
Zone string `yaml:"zone"`
|
||||||
|
// description: |
|
||||||
|
// Machine image used to create Constellation nodes.
|
||||||
|
Image string `yaml:"image"`
|
||||||
|
// description: |
|
||||||
|
// Roles added to service account.
|
||||||
|
ServiceAccountRoles []string `yaml:"serviceAccountRoles"`
|
||||||
|
// description: |
|
||||||
|
// Measurement used to enable measured boot.
|
||||||
|
Measurements Measurements `yaml:"measurements"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QEMUConfig struct {
|
||||||
|
// description: |
|
||||||
|
// Measurement used to enable measured boot.
|
||||||
|
Measurements Measurements `yaml:"measurements"`
|
||||||
|
}
|
||||||
|
|
||||||
// Default returns a struct with the default config.
|
// Default returns a struct with the default config.
|
||||||
func Default() *Config {
|
func Default() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
AutoscalingNodeGroupsMin: intPtr(1),
|
AutoscalingNodeGroupsMin: 1,
|
||||||
AutoscalingNodeGroupsMax: intPtr(10),
|
AutoscalingNodeGroupsMax: 10,
|
||||||
StateDiskSizeGB: intPtr(30),
|
StateDiskSizeGB: 30,
|
||||||
Provider: &ProviderConfig{
|
IngressFirewall: Firewall{
|
||||||
EC2: &EC2Config{
|
|
||||||
Image: proto.String("ami-07d3864beb84157d3"),
|
|
||||||
Tags: &[]ec2.Tag{
|
|
||||||
{
|
|
||||||
Key: "responsible",
|
|
||||||
Value: "cli",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Key: "Name",
|
|
||||||
Value: "Constellation",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SecurityGroupInput: &awsClient.SecurityGroupInput{
|
|
||||||
Inbound: cloudtypes.Firewall{
|
|
||||||
{
|
|
||||||
Description: "Coordinator default port",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: constants.CoordinatorPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Description: "Enclave SSH",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: constants.EnclaveSSHPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Description: "WireGuard default port",
|
|
||||||
Protocol: "UDP",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: constants.WireguardPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Description: "SSH",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: constants.SSHPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Description: "NVMe over TCP",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: constants.NVMEOverTCPPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Description: "NodePort",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: constants.NodePortFrom,
|
|
||||||
ToPort: constants.NodePortTo,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Azure: &AzureConfig{
|
|
||||||
SubscriptionID: proto.String("0d202bbb-4fa7-4af8-8125-58c269a05435"),
|
|
||||||
TenantID: proto.String("adb650a8-5da3-4b15-b4b0-3daf65ff7626"),
|
|
||||||
Location: proto.String("North Europe"),
|
|
||||||
Image: proto.String("/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/CONSTELLATION-IMAGES/providers/Microsoft.Compute/galleries/Constellation/images/constellation-coreos/versions/0.0.1651150807"),
|
|
||||||
NetworkSecurityGroupInput: &azureClient.NetworkSecurityGroupInput{
|
|
||||||
Ingress: cloudtypes.Firewall{
|
|
||||||
{
|
{
|
||||||
Name: "coordinator",
|
Name: "coordinator",
|
||||||
Description: "Coordinator default port",
|
Description: "Coordinator default port",
|
||||||
@ -148,124 +165,50 @@ func Default() *Config {
|
|||||||
ToPort: constants.NodePortTo,
|
ToPort: constants.NodePortTo,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
Provider: ProviderConfig{
|
||||||
Measurements: &azurePCRs,
|
Azure: &AzureConfig{
|
||||||
UserAssignedIdentity: proto.String("/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-dev-identity"),
|
SubscriptionID: "0d202bbb-4fa7-4af8-8125-58c269a05435",
|
||||||
|
TenantID: "adb650a8-5da3-4b15-b4b0-3daf65ff7626",
|
||||||
|
Location: "North Europe",
|
||||||
|
Image: "/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/CONSTELLATION-IMAGES/providers/Microsoft.Compute/galleries/Constellation/images/constellation-coreos/versions/0.0.1651150807",
|
||||||
|
Measurements: azurePCRs,
|
||||||
|
UserAssignedIdentity: "/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-dev-identity",
|
||||||
},
|
},
|
||||||
GCP: &GCPConfig{
|
GCP: &GCPConfig{
|
||||||
Project: proto.String("constellation-331613"),
|
Project: "constellation-331613",
|
||||||
Region: proto.String("europe-west3"),
|
Region: "europe-west3",
|
||||||
Zone: proto.String("europe-west3-b"),
|
Zone: "europe-west3-b",
|
||||||
Image: proto.String("projects/constellation-images/global/images/constellation-coreos-1651150807"),
|
Image: "projects/constellation-images/global/images/constellation-coreos-1651150807",
|
||||||
FirewallInput: &gcpClient.FirewallInput{
|
ServiceAccountRoles: []string{
|
||||||
Ingress: cloudtypes.Firewall{
|
|
||||||
{
|
|
||||||
Name: "coordinator",
|
|
||||||
Description: "Coordinator default port",
|
|
||||||
Protocol: "tcp",
|
|
||||||
FromPort: constants.CoordinatorPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "wireguard",
|
|
||||||
Description: "WireGuard default port",
|
|
||||||
Protocol: "udp",
|
|
||||||
FromPort: constants.WireguardPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "ssh",
|
|
||||||
Description: "SSH",
|
|
||||||
Protocol: "tcp",
|
|
||||||
FromPort: constants.SSHPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "nodeport",
|
|
||||||
Description: "NodePort",
|
|
||||||
Protocol: "tcp",
|
|
||||||
FromPort: constants.NodePortFrom,
|
|
||||||
ToPort: constants.NodePortTo,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
VPCsInput: &gcpClient.VPCsInput{
|
|
||||||
SubnetCIDR: "192.168.178.0/24",
|
|
||||||
SubnetExtCIDR: "10.10.0.0/16",
|
|
||||||
},
|
|
||||||
ServiceAccountRoles: &[]string{
|
|
||||||
"roles/compute.instanceAdmin.v1",
|
"roles/compute.instanceAdmin.v1",
|
||||||
"roles/compute.networkAdmin",
|
"roles/compute.networkAdmin",
|
||||||
"roles/compute.securityAdmin",
|
"roles/compute.securityAdmin",
|
||||||
"roles/storage.admin",
|
"roles/storage.admin",
|
||||||
"roles/iam.serviceAccountUser",
|
"roles/iam.serviceAccountUser",
|
||||||
},
|
},
|
||||||
Measurements: &gcpPCRs,
|
Measurements: gcpPCRs,
|
||||||
},
|
},
|
||||||
QEMU: &QEMUConfig{
|
QEMU: &QEMUConfig{
|
||||||
Measurements: &qemuPCRs,
|
Measurements: qemuPCRs,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromFile returns a default config that has been merged with a config file.
|
// FromFile returns config file with `name` read from `fileHandler` by parsing
|
||||||
// If name is empty, the defaults are returned.
|
// it as YAML.
|
||||||
|
// If name is empty, the default configuration is returned.
|
||||||
func FromFile(fileHandler file.Handler, name string) (*Config, error) {
|
func FromFile(fileHandler file.Handler, name string) (*Config, error) {
|
||||||
conf := Default()
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return conf, nil
|
return Default(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := fileHandler.ReadYAML(name, conf); err != nil {
|
var emptyConf Config
|
||||||
|
if err := fileHandler.ReadYAML(name, &emptyConf); err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
return nil, fmt.Errorf("unable to find %s - use `constellation config generate` to generate it first", name)
|
return nil, fmt.Errorf("unable to find %s - use `constellation config generate` to generate it first", name)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("could not load config from file %s: %w", name, err)
|
return nil, fmt.Errorf("could not load config from file %s: %w", name, err)
|
||||||
}
|
}
|
||||||
return conf, nil
|
return &emptyConf, nil
|
||||||
}
|
|
||||||
|
|
||||||
// ProviderConfig are cloud-provider specific configuration values used by the CLI.
|
|
||||||
type ProviderConfig struct {
|
|
||||||
EC2 *EC2Config `yaml:"ec2Config,omitempty"`
|
|
||||||
Azure *AzureConfig `yaml:"azureConfig,omitempty"`
|
|
||||||
GCP *GCPConfig `yaml:"gcpConfig,omitempty"`
|
|
||||||
QEMU *QEMUConfig `yaml:"qemuConfig,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// EC2Config are AWS EC2 specific configuration values used by the CLI.
|
|
||||||
type EC2Config struct {
|
|
||||||
Image *string `yaml:"image,omitempty"`
|
|
||||||
Tags *[]ec2.Tag `yaml:"tags,omitempty"`
|
|
||||||
SecurityGroupInput *awsClient.SecurityGroupInput `yaml:"securityGroupInput,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AzureConfig are Azure specific configuration values used by the CLI.
|
|
||||||
type AzureConfig struct {
|
|
||||||
SubscriptionID *string `yaml:"subscription,omitempty"` // TODO: This will be user input
|
|
||||||
TenantID *string `yaml:"tenant,omitempty"` // TODO: This will be user input
|
|
||||||
Location *string `yaml:"location,omitempty"` // TODO: This will be user input
|
|
||||||
Image *string `yaml:"image,omitempty"`
|
|
||||||
NetworkSecurityGroupInput *azureClient.NetworkSecurityGroupInput `yaml:"networkSecurityGroupInput,omitempty"`
|
|
||||||
Measurements *Measurements `yaml:"measurements,omitempty"`
|
|
||||||
UserAssignedIdentity *string `yaml:"userassignedIdentity,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GCPConfig are GCP specific configuration values used by the CLI.
|
|
||||||
type GCPConfig struct {
|
|
||||||
Project *string `yaml:"project,omitempty"` // TODO: This will be user input
|
|
||||||
Region *string `yaml:"region,omitempty"` // TODO: This will be user input
|
|
||||||
Zone *string `yaml:"zone,omitempty"` // TODO: This will be user input
|
|
||||||
Image *string `yaml:"image,omitempty"`
|
|
||||||
FirewallInput *gcpClient.FirewallInput `yaml:"firewallInput,omitempty"`
|
|
||||||
VPCsInput *gcpClient.VPCsInput `yaml:"vpcsInput,omitempty"`
|
|
||||||
ServiceAccountRoles *[]string `yaml:"serviceAccountRoles,omitempty"`
|
|
||||||
Measurements *Measurements `yaml:"measurements,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type QEMUConfig struct {
|
|
||||||
Measurements *Measurements `yaml:"measurements,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// intPtr returns a pointer to the copied value of in.
|
|
||||||
func intPtr(in int) *int {
|
|
||||||
return &in
|
|
||||||
}
|
}
|
||||||
|
220
internal/config/config_doc.go
Normal file
220
internal/config/config_doc.go
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
// Code generated by hack/docgen tool. DO NOT EDIT.
|
||||||
|
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ConfigDoc encoder.Doc
|
||||||
|
ProviderConfigDoc encoder.Doc
|
||||||
|
AzureConfigDoc encoder.Doc
|
||||||
|
GCPConfigDoc encoder.Doc
|
||||||
|
QEMUConfigDoc encoder.Doc
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ConfigDoc.Type = "Config"
|
||||||
|
ConfigDoc.Comments[encoder.LineComment] = "Config defines configuration used by CLI."
|
||||||
|
ConfigDoc.Description = "Config defines configuration used by CLI."
|
||||||
|
ConfigDoc.Fields = make([]encoder.Doc, 4)
|
||||||
|
ConfigDoc.Fields[0].Name = "autoscalingNodeGroupsMin"
|
||||||
|
ConfigDoc.Fields[0].Type = "int"
|
||||||
|
ConfigDoc.Fields[0].Note = ""
|
||||||
|
ConfigDoc.Fields[0].Description = "Minimum number of nodes in autoscaling group.\nworker nodes."
|
||||||
|
ConfigDoc.Fields[0].Comments[encoder.LineComment] = "Minimum number of nodes in autoscaling group."
|
||||||
|
ConfigDoc.Fields[1].Name = "autoscalingNodeGroupsMax"
|
||||||
|
ConfigDoc.Fields[1].Type = "int"
|
||||||
|
ConfigDoc.Fields[1].Note = ""
|
||||||
|
ConfigDoc.Fields[1].Description = "Maximum number of nodes in autoscaling group.\nworker nodes."
|
||||||
|
ConfigDoc.Fields[1].Comments[encoder.LineComment] = "Maximum number of nodes in autoscaling group."
|
||||||
|
ConfigDoc.Fields[2].Name = "StateDisksizeGB"
|
||||||
|
ConfigDoc.Fields[2].Type = "int"
|
||||||
|
ConfigDoc.Fields[2].Note = ""
|
||||||
|
ConfigDoc.Fields[2].Description = "Size (in GB) of root disk used for nodes."
|
||||||
|
ConfigDoc.Fields[2].Comments[encoder.LineComment] = "Size (in GB) of root disk used for nodes."
|
||||||
|
ConfigDoc.Fields[3].Name = "provider"
|
||||||
|
ConfigDoc.Fields[3].Type = "ProviderConfig"
|
||||||
|
ConfigDoc.Fields[3].Note = ""
|
||||||
|
ConfigDoc.Fields[3].Description = "Supported cloud providers & their specific configurations."
|
||||||
|
ConfigDoc.Fields[3].Comments[encoder.LineComment] = "Supported cloud providers & their specific configurations."
|
||||||
|
|
||||||
|
ProviderConfigDoc.Type = "ProviderConfig"
|
||||||
|
ProviderConfigDoc.Comments[encoder.LineComment] = "ProviderConfig are cloud-provider specific configuration values used by the CLI."
|
||||||
|
ProviderConfigDoc.Description = "ProviderConfig are cloud-provider specific configuration values used by the CLI."
|
||||||
|
ProviderConfigDoc.AppearsIn = []encoder.Appearance{
|
||||||
|
{
|
||||||
|
TypeName: "Config",
|
||||||
|
FieldName: "provider",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ProviderConfigDoc.Fields = make([]encoder.Doc, 3)
|
||||||
|
ProviderConfigDoc.Fields[0].Name = "azureConfig"
|
||||||
|
ProviderConfigDoc.Fields[0].Type = "AzureConfig"
|
||||||
|
ProviderConfigDoc.Fields[0].Note = ""
|
||||||
|
ProviderConfigDoc.Fields[0].Description = "Configuration for Azure as provider."
|
||||||
|
ProviderConfigDoc.Fields[0].Comments[encoder.LineComment] = "Configuration for Azure as provider."
|
||||||
|
ProviderConfigDoc.Fields[1].Name = "gcpConfig"
|
||||||
|
ProviderConfigDoc.Fields[1].Type = "GCPConfig"
|
||||||
|
ProviderConfigDoc.Fields[1].Note = ""
|
||||||
|
ProviderConfigDoc.Fields[1].Description = "Configuration for Google Cloud as provider."
|
||||||
|
ProviderConfigDoc.Fields[1].Comments[encoder.LineComment] = "Configuration for Google Cloud as provider."
|
||||||
|
ProviderConfigDoc.Fields[2].Name = "qemuConfig"
|
||||||
|
ProviderConfigDoc.Fields[2].Type = "QEMUConfig"
|
||||||
|
ProviderConfigDoc.Fields[2].Note = ""
|
||||||
|
ProviderConfigDoc.Fields[2].Description = "Configuration for QEMU as provider."
|
||||||
|
ProviderConfigDoc.Fields[2].Comments[encoder.LineComment] = "Configuration for QEMU as provider."
|
||||||
|
|
||||||
|
AzureConfigDoc.Type = "AzureConfig"
|
||||||
|
AzureConfigDoc.Comments[encoder.LineComment] = "AzureConfig are Azure specific configuration values used by the CLI."
|
||||||
|
AzureConfigDoc.Description = "AzureConfig are Azure specific configuration values used by the CLI."
|
||||||
|
AzureConfigDoc.AppearsIn = []encoder.Appearance{
|
||||||
|
{
|
||||||
|
TypeName: "ProviderConfig",
|
||||||
|
FieldName: "azureConfig",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
AzureConfigDoc.Fields = make([]encoder.Doc, 7)
|
||||||
|
AzureConfigDoc.Fields[0].Name = "subscription"
|
||||||
|
AzureConfigDoc.Fields[0].Type = "string"
|
||||||
|
AzureConfigDoc.Fields[0].Note = ""
|
||||||
|
AzureConfigDoc.Fields[0].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"
|
||||||
|
AzureConfigDoc.Fields[0].Comments[encoder.LineComment] = "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"
|
||||||
|
AzureConfigDoc.Fields[1].Name = "tenant"
|
||||||
|
AzureConfigDoc.Fields[1].Type = "string"
|
||||||
|
AzureConfigDoc.Fields[1].Note = ""
|
||||||
|
AzureConfigDoc.Fields[1].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"
|
||||||
|
AzureConfigDoc.Fields[1].Comments[encoder.LineComment] = "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"
|
||||||
|
AzureConfigDoc.Fields[2].Name = "location"
|
||||||
|
AzureConfigDoc.Fields[2].Type = "string"
|
||||||
|
AzureConfigDoc.Fields[2].Note = ""
|
||||||
|
AzureConfigDoc.Fields[2].Description = "Azure datacenter region to be used. See: https://docs.microsoft.com/en-us/azure/availability-zones/az-overview#azure-regions-with-availability-zones"
|
||||||
|
AzureConfigDoc.Fields[2].Comments[encoder.LineComment] = "Azure datacenter region to be used. See: https://docs.microsoft.com/en-us/azure/availability-zones/az-overview#azure-regions-with-availability-zones"
|
||||||
|
AzureConfigDoc.Fields[3].Name = "image"
|
||||||
|
AzureConfigDoc.Fields[3].Type = "string"
|
||||||
|
AzureConfigDoc.Fields[3].Note = ""
|
||||||
|
AzureConfigDoc.Fields[3].Description = "Machine image used to create Constellation nodes."
|
||||||
|
AzureConfigDoc.Fields[3].Comments[encoder.LineComment] = "Machine image used to create Constellation nodes."
|
||||||
|
AzureConfigDoc.Fields[4].Name = "networkSecurityGroupInput"
|
||||||
|
AzureConfigDoc.Fields[4].Type = "NetworkSecurityGroupInput"
|
||||||
|
AzureConfigDoc.Fields[4].Note = ""
|
||||||
|
AzureConfigDoc.Fields[4].Description = "Firewall rules."
|
||||||
|
AzureConfigDoc.Fields[4].Comments[encoder.LineComment] = "Firewall rules."
|
||||||
|
AzureConfigDoc.Fields[5].Name = "measurements"
|
||||||
|
AzureConfigDoc.Fields[5].Type = "Measurements"
|
||||||
|
AzureConfigDoc.Fields[5].Note = ""
|
||||||
|
AzureConfigDoc.Fields[5].Description = "Measurement used to enable measured boot."
|
||||||
|
AzureConfigDoc.Fields[5].Comments[encoder.LineComment] = "Measurement used to enable measured boot."
|
||||||
|
AzureConfigDoc.Fields[6].Name = "userassignedIdentity"
|
||||||
|
AzureConfigDoc.Fields[6].Type = "string"
|
||||||
|
AzureConfigDoc.Fields[6].Note = ""
|
||||||
|
AzureConfigDoc.Fields[6].Description = "Why is this needed? Docs only say that it is needed. (TODO) See: https://constellation-docs.edgeless.systems/6c320851-bdd2-41d5-bf10-e27427398692/#/getting-started/install?id=azure"
|
||||||
|
AzureConfigDoc.Fields[6].Comments[encoder.LineComment] = "Why is this needed? Docs only say that it is needed. (TODO) See: https://constellation-docs.edgeless.systems/6c320851-bdd2-41d5-bf10-e27427398692/#/getting-started/install?id=azure"
|
||||||
|
|
||||||
|
GCPConfigDoc.Type = "GCPConfig"
|
||||||
|
GCPConfigDoc.Comments[encoder.LineComment] = "GCPConfig are GCP specific configuration values used by the CLI."
|
||||||
|
GCPConfigDoc.Description = "GCPConfig are GCP specific configuration values used by the CLI."
|
||||||
|
GCPConfigDoc.AppearsIn = []encoder.Appearance{
|
||||||
|
{
|
||||||
|
TypeName: "ProviderConfig",
|
||||||
|
FieldName: "gcpConfig",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
GCPConfigDoc.Fields = make([]encoder.Doc, 8)
|
||||||
|
GCPConfigDoc.Fields[0].Name = "project"
|
||||||
|
GCPConfigDoc.Fields[0].Type = "string"
|
||||||
|
GCPConfigDoc.Fields[0].Note = ""
|
||||||
|
GCPConfigDoc.Fields[0].Description = "GCP project. See: https://support.google.com/googleapi/answer/7014113?hl=en"
|
||||||
|
GCPConfigDoc.Fields[0].Comments[encoder.LineComment] = "GCP project. See: https://support.google.com/googleapi/answer/7014113?hl=en"
|
||||||
|
GCPConfigDoc.Fields[1].Name = "region"
|
||||||
|
GCPConfigDoc.Fields[1].Type = "string"
|
||||||
|
GCPConfigDoc.Fields[1].Note = ""
|
||||||
|
GCPConfigDoc.Fields[1].Description = "GCP datacenter region. See: https://cloud.google.com/compute/docs/regions-zones#available"
|
||||||
|
GCPConfigDoc.Fields[1].Comments[encoder.LineComment] = "GCP datacenter region. See: https://cloud.google.com/compute/docs/regions-zones#available"
|
||||||
|
GCPConfigDoc.Fields[2].Name = "zone"
|
||||||
|
GCPConfigDoc.Fields[2].Type = "string"
|
||||||
|
GCPConfigDoc.Fields[2].Note = ""
|
||||||
|
GCPConfigDoc.Fields[2].Description = "GCP datacenter zone. See: https://cloud.google.com/compute/docs/regions-zones#available"
|
||||||
|
GCPConfigDoc.Fields[2].Comments[encoder.LineComment] = "GCP datacenter zone. See: https://cloud.google.com/compute/docs/regions-zones#available"
|
||||||
|
GCPConfigDoc.Fields[3].Name = "image"
|
||||||
|
GCPConfigDoc.Fields[3].Type = "string"
|
||||||
|
GCPConfigDoc.Fields[3].Note = ""
|
||||||
|
GCPConfigDoc.Fields[3].Description = "Machine image used to create Constellation nodes."
|
||||||
|
GCPConfigDoc.Fields[3].Comments[encoder.LineComment] = "Machine image used to create Constellation nodes."
|
||||||
|
GCPConfigDoc.Fields[4].Name = "firewallInput"
|
||||||
|
GCPConfigDoc.Fields[4].Type = "FirewallInput"
|
||||||
|
GCPConfigDoc.Fields[4].Note = ""
|
||||||
|
GCPConfigDoc.Fields[4].Description = "Firewall rules."
|
||||||
|
GCPConfigDoc.Fields[4].Comments[encoder.LineComment] = "Firewall rules."
|
||||||
|
GCPConfigDoc.Fields[5].Name = "vpcsInput"
|
||||||
|
GCPConfigDoc.Fields[5].Type = "VPCsInput"
|
||||||
|
GCPConfigDoc.Fields[5].Note = ""
|
||||||
|
GCPConfigDoc.Fields[5].Description = "Virtual Private Cloud settings."
|
||||||
|
GCPConfigDoc.Fields[5].Comments[encoder.LineComment] = "Virtual Private Cloud settings."
|
||||||
|
GCPConfigDoc.Fields[6].Name = "serviceAccountRoles"
|
||||||
|
GCPConfigDoc.Fields[6].Type = "[]string"
|
||||||
|
GCPConfigDoc.Fields[6].Note = ""
|
||||||
|
GCPConfigDoc.Fields[6].Description = "Roles added to service account."
|
||||||
|
GCPConfigDoc.Fields[6].Comments[encoder.LineComment] = "Roles added to service account."
|
||||||
|
GCPConfigDoc.Fields[7].Name = "measurements"
|
||||||
|
GCPConfigDoc.Fields[7].Type = "Measurements"
|
||||||
|
GCPConfigDoc.Fields[7].Note = ""
|
||||||
|
GCPConfigDoc.Fields[7].Description = "Measurement used to enable measured boot."
|
||||||
|
GCPConfigDoc.Fields[7].Comments[encoder.LineComment] = "Measurement used to enable measured boot."
|
||||||
|
|
||||||
|
QEMUConfigDoc.Type = "QEMUConfig"
|
||||||
|
QEMUConfigDoc.Comments[encoder.LineComment] = ""
|
||||||
|
QEMUConfigDoc.Description = ""
|
||||||
|
QEMUConfigDoc.AppearsIn = []encoder.Appearance{
|
||||||
|
{
|
||||||
|
TypeName: "ProviderConfig",
|
||||||
|
FieldName: "qemuConfig",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
QEMUConfigDoc.Fields = make([]encoder.Doc, 1)
|
||||||
|
QEMUConfigDoc.Fields[0].Name = "measurements"
|
||||||
|
QEMUConfigDoc.Fields[0].Type = "Measurements"
|
||||||
|
QEMUConfigDoc.Fields[0].Note = ""
|
||||||
|
QEMUConfigDoc.Fields[0].Description = "Measurement used to enable measured boot."
|
||||||
|
QEMUConfigDoc.Fields[0].Comments[encoder.LineComment] = "Measurement used to enable measured boot."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Config) Doc() *encoder.Doc {
|
||||||
|
return &ConfigDoc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ ProviderConfig) Doc() *encoder.Doc {
|
||||||
|
return &ProviderConfigDoc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ AzureConfig) Doc() *encoder.Doc {
|
||||||
|
return &AzureConfigDoc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ GCPConfig) Doc() *encoder.Doc {
|
||||||
|
return &GCPConfigDoc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ QEMUConfig) Doc() *encoder.Doc {
|
||||||
|
return &QEMUConfigDoc
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfigurationDoc returns documentation for the file ./config_doc.go.
|
||||||
|
func GetConfigurationDoc() *encoder.FileDoc {
|
||||||
|
return &encoder.FileDoc{
|
||||||
|
Name: "Configuration",
|
||||||
|
Description: "",
|
||||||
|
Structs: []*encoder.Doc{
|
||||||
|
&ConfigDoc,
|
||||||
|
&ProviderConfigDoc,
|
||||||
|
&AzureConfigDoc,
|
||||||
|
&GCPConfigDoc,
|
||||||
|
&QEMUConfigDoc,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -3,8 +3,6 @@ package config
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/cli/cloud/cloudtypes"
|
|
||||||
"github.com/edgelesssys/constellation/cli/gcp/client"
|
|
||||||
"github.com/edgelesssys/constellation/internal/constants"
|
"github.com/edgelesssys/constellation/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/internal/file"
|
"github.com/edgelesssys/constellation/internal/file"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
@ -19,49 +17,58 @@ func TestDefaultConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFromFile(t *testing.T) {
|
func TestFromFile(t *testing.T) {
|
||||||
someProviderConfig := &ProviderConfig{
|
|
||||||
GCP: &GCPConfig{
|
|
||||||
FirewallInput: &client.FirewallInput{
|
|
||||||
Ingress: cloudtypes.Firewall{
|
|
||||||
{
|
|
||||||
Name: "firstFirewallRule",
|
|
||||||
Description: "firstFirewallRule description",
|
|
||||||
Protocol: "tcp",
|
|
||||||
FromPort: 4444,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "secondFirewallRule",
|
|
||||||
Description: "secondFirewallRule description",
|
|
||||||
Protocol: "udp",
|
|
||||||
FromPort: 5555,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
from *Config
|
config *Config
|
||||||
configName string
|
configName string
|
||||||
wantResultMutator func(c *Config) // mutates the Default() config to the expected result.
|
wantResult *Config
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"overwrite slices": {
|
"default config from default file": {
|
||||||
from: &Config{Provider: someProviderConfig},
|
config: Default(),
|
||||||
configName: constants.ConfigFilename,
|
configName: constants.ConfigFilename,
|
||||||
wantResultMutator: func(c *Config) { c.Provider = someProviderConfig },
|
wantResult: Default(),
|
||||||
},
|
},
|
||||||
"default with empty name": {
|
"default config from different path": {
|
||||||
from: &Config{},
|
config: Default(),
|
||||||
|
configName: "other-config.yaml",
|
||||||
|
wantResult: Default(),
|
||||||
|
},
|
||||||
|
"default config when path empty": {
|
||||||
|
config: nil,
|
||||||
configName: "",
|
configName: "",
|
||||||
wantResultMutator: func(c *Config) {},
|
wantResult: Default(),
|
||||||
},
|
},
|
||||||
"err with wrong name": {
|
"err when path not exist": {
|
||||||
from: &Config{},
|
config: nil,
|
||||||
configName: "wrongName.json",
|
configName: "wrong-name.yaml",
|
||||||
wantResultMutator: func(c *Config) {},
|
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
|
"custom config from default file": {
|
||||||
|
config: &Config{
|
||||||
|
AutoscalingNodeGroupsMin: 42,
|
||||||
|
AutoscalingNodeGroupsMax: 1337,
|
||||||
|
},
|
||||||
|
configName: constants.ConfigFilename,
|
||||||
|
wantResult: &Config{
|
||||||
|
AutoscalingNodeGroupsMin: 42,
|
||||||
|
AutoscalingNodeGroupsMax: 1337,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"modify default config": {
|
||||||
|
config: func() *Config {
|
||||||
|
conf := Default()
|
||||||
|
conf.Provider.GCP.Region = "eu-north1"
|
||||||
|
conf.Provider.GCP.Zone = "eu-north1-a"
|
||||||
|
return conf
|
||||||
|
}(),
|
||||||
|
configName: constants.ConfigFilename,
|
||||||
|
wantResult: func() *Config {
|
||||||
|
conf := Default()
|
||||||
|
conf.Provider.GCP.Region = "eu-north1"
|
||||||
|
conf.Provider.GCP.Zone = "eu-north1-a"
|
||||||
|
return conf
|
||||||
|
}(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range testCases {
|
for name, tc := range testCases {
|
||||||
@ -70,7 +77,9 @@ func TestFromFile(t *testing.T) {
|
|||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, tc.from, file.OptNone))
|
if tc.config != nil {
|
||||||
|
require.NoError(fileHandler.WriteYAML(tc.configName, tc.config, file.OptNone))
|
||||||
|
}
|
||||||
|
|
||||||
result, err := FromFile(fileHandler, tc.configName)
|
result, err := FromFile(fileHandler, tc.configName)
|
||||||
|
|
||||||
@ -78,14 +87,7 @@ func TestFromFile(t *testing.T) {
|
|||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
} else {
|
} else {
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
wantResult := Default()
|
assert.Equal(tc.wantResult, result)
|
||||||
tc.wantResultMutator(wantResult)
|
|
||||||
assert.EqualValues(wantResult.AutoscalingNodeGroupsMin, result.AutoscalingNodeGroupsMin)
|
|
||||||
assert.EqualValues(wantResult.AutoscalingNodeGroupsMax, result.AutoscalingNodeGroupsMax)
|
|
||||||
require.NotNil(wantResult.Provider)
|
|
||||||
require.NotNil(wantResult.Provider.GCP, result.Provider.GCP)
|
|
||||||
require.NotNil(wantResult.Provider.GCP.FirewallInput, result.Provider.GCP.FirewallInput)
|
|
||||||
assert.Equal(len(wantResult.Provider.GCP.FirewallInput.Ingress), len(result.Provider.GCP.FirewallInput.Ingress))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,35 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import "encoding/base64"
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/coordinator/attestation/vtpm"
|
||||||
|
)
|
||||||
|
|
||||||
type Measurements map[uint32][]byte
|
type Measurements map[uint32][]byte
|
||||||
|
|
||||||
|
var (
|
||||||
|
// gcpPCRs is a map of the expected PCR values for a GCP Constellation node.
|
||||||
|
// TODO: Get a full list once we have stable releases.
|
||||||
|
gcpPCRs = Measurements{
|
||||||
|
0: {0x0F, 0x35, 0xC2, 0x14, 0x60, 0x8D, 0x93, 0xC7, 0xA6, 0xE6, 0x8A, 0xE7, 0x35, 0x9B, 0x4A, 0x8B, 0xE5, 0xA0, 0xE9, 0x9E, 0xEA, 0x91, 0x07, 0xEC, 0xE4, 0x27, 0xC4, 0xDE, 0xA4, 0xE4, 0x39, 0xCF},
|
||||||
|
uint32(vtpm.PCRIndexOwnerID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
|
uint32(vtpm.PCRIndexClusterID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
|
}
|
||||||
|
|
||||||
|
// azurePCRs is a map of the expected PCR values for an Azure Constellation node.
|
||||||
|
// TODO: Get a full list once we have a working setup with stable releases.
|
||||||
|
azurePCRs = Measurements{
|
||||||
|
uint32(vtpm.PCRIndexOwnerID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
|
uint32(vtpm.PCRIndexClusterID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
|
}
|
||||||
|
|
||||||
|
qemuPCRs = Measurements{
|
||||||
|
uint32(vtpm.PCRIndexOwnerID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
|
uint32(vtpm.PCRIndexClusterID): {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func (m Measurements) MarshalYAML() (interface{}, error) {
|
func (m Measurements) MarshalYAML() (interface{}, error) {
|
||||||
base64Map := make(map[uint32]string)
|
base64Map := make(map[uint32]string)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
|
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ func (h *Handler) WriteYAML(name string, content any, options Option) (err error
|
|||||||
err = errors.New("recovered from panic")
|
err = errors.New("recovered from panic")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
data, err := yaml.Marshal(content)
|
data, err := encoder.NewEncoder(content).Encode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user