func TestStackTags(t *testing.T) { testCases := []struct { expectedTags []*cloudformation.Tag clusterYaml string }{ { expectedTags: []*cloudformation.Tag{}, clusterYaml: ` #no stackTags set `, }, { expectedTags: []*cloudformation.Tag{ &cloudformation.Tag{ Key: aws.String("KeyA"), Value: aws.String("ValueA"), }, &cloudformation.Tag{ Key: aws.String("KeyB"), Value: aws.String("ValueB"), }, &cloudformation.Tag{ Key: aws.String("KeyC"), Value: aws.String("ValueC"), }, }, clusterYaml: ` stackTags: KeyA: ValueA KeyB: ValueB KeyC: ValueC `, }, } for _, testCase := range testCases { configBody := defaultConfigValues(t, testCase.clusterYaml) clusterConfig, err := config.ClusterFromBytes([]byte(configBody)) if err != nil { t.Errorf("could not get valid cluster config: %v", err) continue } cluster := &Cluster{ Cluster: *clusterConfig, } cfSvc := &dummyCloudformationService{ ExpectedTags: testCase.expectedTags, } _, err = cluster.createStack(cfSvc, "") if err != nil { t.Errorf("error creating cluster: %v\nfor test case %+v", err, testCase) } } }
func TestValidateDNSConfig(t *testing.T) { dnsConfig := ` createRecordSet: true recordSetTTL: 60 hostedZone: staging.core-os.net ` configBody := minimalConfigYaml + dnsConfig clusterConfig, err := config.ClusterFromBytes([]byte(configBody)) if err != nil { t.Errorf("could not get valid cluster config: %v", err) } c := &Cluster{Cluster: *clusterConfig} r53 := dummyR53Service{ HostedZones: []Zone{ Zone{ Id: "staging_id", DNS: "staging.core-os.net.", }, }, ResourceRecordSets: map[string]string{ "staging_id": "existing-record.staging.core-os.net.", }, } if err := c.validateDNSConfig(r53); err != nil { t.Errorf("returned error for valid config: %v", err) } c.HostedZone = "non-existant-zone" if err := c.validateDNSConfig(r53); err == nil { t.Errorf("failed to catch non-existent hosted zone") } c.HostedZone = "staging.core-os.net" c.ExternalDNSName = "existing-record.staging.core-os.net" if err := c.validateDNSConfig(r53); err == nil { t.Errorf("failed to catch already existing ExternalDNSName") } }
func TestValidateKeyPair(t *testing.T) { clusterConfig, err := config.ClusterFromBytes([]byte(defaultConfigValues(t, ""))) if err != nil { t.Errorf("could not get valid cluster config: %v", err) } c := &Cluster{Cluster: *clusterConfig} ec2Svc := dummyEC2Service{} ec2Svc.KeyPairs = map[string]bool{ c.KeyName: true, } if err := c.validateKeyPair(ec2Svc); err != nil { t.Errorf("returned an error for valid key") } c.KeyName = "invalidKeyName" if err := c.validateKeyPair(ec2Svc); err == nil { t.Errorf("failed to catch invalid key \"%s\"", c.KeyName) } }
func TestValidateWorkerRootVolume(t *testing.T) { testCases := []struct { expectedRootVolume *ec2.CreateVolumeInput clusterYaml string }{ { expectedRootVolume: &ec2.CreateVolumeInput{ Iops: aws.Int64(0), Size: aws.Int64(30), VolumeType: aws.String("gp2"), }, clusterYaml: ` # no root volumes set `, }, { expectedRootVolume: &ec2.CreateVolumeInput{ Iops: aws.Int64(0), Size: aws.Int64(30), VolumeType: aws.String("standard"), }, clusterYaml: ` workerRootVolumeType: standard `, }, { expectedRootVolume: &ec2.CreateVolumeInput{ Iops: aws.Int64(0), Size: aws.Int64(50), VolumeType: aws.String("gp2"), }, clusterYaml: ` workerRootVolumeType: gp2 workerRootVolumeSize: 50 `, }, { expectedRootVolume: &ec2.CreateVolumeInput{ Iops: aws.Int64(2000), Size: aws.Int64(100), VolumeType: aws.String("io1"), }, clusterYaml: ` workerRootVolumeType: io1 workerRootVolumeSize: 100 workerRootVolumeIOPS: 2000 `, }, } for _, testCase := range testCases { configBody := defaultConfigValues(t, testCase.clusterYaml) clusterConfig, err := config.ClusterFromBytes([]byte(configBody)) if err != nil { t.Errorf("could not get valid cluster config: %v", err) continue } c := &Cluster{ Cluster: *clusterConfig, } ec2Svc := &dummyEC2Service{ ExpectedRootVolume: testCase.expectedRootVolume, } if err := c.validateWorkerRootVolume(ec2Svc); err != nil { t.Errorf("error creating cluster: %v\nfor test case %+v", err, testCase) } } }
func TestValidateDNSConfig(t *testing.T) { r53 := dummyR53Service{ HostedZones: []Zone{ { Id: "/hostedzone/staging_id_1", DNS: "staging.core-os.net.", }, { Id: "/hostedzone/staging_id_2", DNS: "staging.core-os.net.", }, { Id: "/hostedzone/staging_id_3", DNS: "zebras.coreos.com.", }, { Id: "/hostedzone/staging_id_4", DNS: "core-os.net.", }, }, ResourceRecordSets: map[string]string{ "staging_id_1": "existing-record.staging.core-os.net.", }, } validDNSConfigs := []string{ ` createRecordSet: true recordSetTTL: 60 hostedZone: core-os.net `, ` createRecordSet: true recordSetTTL: 60 hostedZoneId: staging_id_1 `, ` createRecordSet: true recordSetTTL: 60 hostedZoneId: /hostedzone/staging_id_2 `, } invalidDNSConfigs := []string{ ` createRecordSet: true recordSetTTL: 60 hostedZone: staging.core-os.net # hostedZone is ambiguous `, ` createRecordSet: true recordSetTTL: 60 hostedZoneId: /hostedzone/staging_id_3 # <staging_id_id> is not a super-domain `, ` createRecordSet: true recordSetTTL: 60 hostedZone: zebras.coreos.com # zebras.coreos.com is not a super-domain `, ` createRecordSet: true recordSetTTL: 60 hostedZoneId: /hostedzone/staging_id_5 #non-existant hostedZoneId `, ` createRecordSet: true recordSetTTL: 60 hostedZone: unicorns.core-os.net #non-existant hostedZone DNS name `, } for _, validConfig := range validDNSConfigs { configBody := defaultConfigValues(t, validConfig) clusterConfig, err := config.ClusterFromBytes([]byte(configBody)) if err != nil { t.Errorf("could not get valid cluster config: %v", err) continue } c := &Cluster{Cluster: *clusterConfig} if err := c.validateDNSConfig(r53); err != nil { t.Errorf("returned error for valid config: %v", err) } } for _, invalidConfig := range invalidDNSConfigs { configBody := defaultConfigValues(t, invalidConfig) clusterConfig, err := config.ClusterFromBytes([]byte(configBody)) if err != nil { t.Errorf("could not get valid cluster config: %v", err) continue } c := &Cluster{Cluster: *clusterConfig} if err := c.validateDNSConfig(r53); err == nil { t.Errorf("failed to produce error for invalid config: %s", configBody) } } }
func TestExistingVPCValidation(t *testing.T) { goodExistingVPCConfigs := []string{ ``, //Tests default create VPC mode, which bypasses existing VPC validation ` vpcCIDR: 10.5.0.0/16 vpcId: vpc-xxx1 routeTableId: rtb-xxxxxx instanceCIDR: 10.5.11.0/24 controllerIP: 10.5.11.10 `, ` vpcCIDR: 192.168.1.0/24 vpcId: vpc-xxx2 instanceCIDR: 192.168.1.50/28 controllerIP: 192.168.1.50 `, ` vpcCIDR: 192.168.1.0/24 vpcId: vpc-xxx2 controllerIP: 192.168.1.5 subnets: - instanceCIDR: 192.168.1.0/28 - instanceCIDR: 192.168.1.32/28 - instanceCIDR: 192.168.1.64/28 `, } badExistingVPCConfigs := []string{ ` vpcCIDR: 10.0.0.0/16 vpcId: vpc-xxx3 #vpc does not exist instanceCIDR: 10.0.0.0/24 controllerIP: 10.0.0.50 routeTableId: rtb-xxxxxx `, ` vpcCIDR: 10.10.0.0/16 #vpc cidr does match existing vpc-xxx1 vpcId: vpc-xxx1 instanceCIDR: 10.10.0.0/24 controllerIP: 10.10.0.50 routeTableId: rtb-xxxxxx `, ` vpcCIDR: 10.5.0.0/16 instanceCIDR: 10.5.2.0/28 #instance cidr conflicts with existing subnet controllerIP: 10.5.2.10 vpcId: vpc-xxx1 routeTableId: rtb-xxxxxx `, ` vpcCIDR: 192.168.1.0/24 instanceCIDR: 192.168.1.100/26 #instance cidr conflicts with existing subnet controllerIP: 192.168.1.80 vpcId: vpc-xxx2 routeTableId: rtb-xxxxxx `, ` vpcCIDR: 192.168.1.0/24 controllerIP: 192.168.1.80 vpcId: vpc-xxx2 routeTableId: rtb-xxxxxx subnets: - instanceCIDR: 192.168.1.100/26 #instance cidr conflicts with existing subnet - instanceCIDR: 192.168.1.0/26 `, } ec2Service := dummyEC2Service{ VPCs: map[string]VPC{ "vpc-xxx1": { cidr: "10.5.0.0/16", subnetCidrs: []string{ "10.5.1.0/24", "10.5.2.0/24", "10.5.10.100/29", }, }, "vpc-xxx2": { cidr: "192.168.1.0/24", subnetCidrs: []string{ "192.168.1.100/28", "192.168.1.150/28", "192.168.1.200/28", }, }, }, } validateCluster := func(networkConfig string) error { configBody := defaultConfigValues(t, networkConfig) clusterConfig, err := config.ClusterFromBytes([]byte(configBody)) if err != nil { t.Errorf("could not get valid cluster config: %v", err) return nil } cluster := &Cluster{ Cluster: *clusterConfig, } return cluster.validateExistingVPCState(ec2Service) } for _, networkConfig := range goodExistingVPCConfigs { if err := validateCluster(networkConfig); err != nil { t.Errorf("Correct config tested invalid: %s\n%s", err, networkConfig) } } for _, networkConfig := range badExistingVPCConfigs { if err := validateCluster(networkConfig); err == nil { t.Errorf("Incorrect config tested valid, expected error:\n%s", networkConfig) } } }