func NewManifest(config Config, iaasConfig iaas.Config) (Manifest, error) { config = NewConfigWithDefaults(config) releases := []core.Release{ { Name: "etcd", Version: "latest", }, } cidr, err := core.ParseCIDRBlock(config.IPRange) if err != nil { return Manifest{}, err } etcdNetwork1 := core.Network{ Name: "etcd1", Subnets: []core.NetworkSubnet{{ CloudProperties: iaasConfig.NetworkSubnet(cidr.String()), Gateway: cidr.GetFirstIP().Add(1).String(), Range: cidr.String(), Reserved: []string{cidr.Range(2, 3), cidr.GetLastIP().String()}, Static: []string{cidr.Range(4, cidr.CIDRSize-5)}, }}, Type: "manual", } compilation := core.Compilation{ Network: etcdNetwork1.Name, ReuseCompilationVMs: true, Workers: 3, CloudProperties: iaasConfig.Compilation("us-east-1a"), } update := core.Update{ Canaries: 1, CanaryWatchTime: "1000-180000", MaxInFlight: 1, Serial: true, UpdateWatchTime: "1000-180000", } stemcell := core.ResourcePoolStemcell{ Name: iaasConfig.Stemcell(), Version: "latest", } z1ResourcePool := core.ResourcePool{ Name: "etcd_z1", Network: etcdNetwork1.Name, Stemcell: stemcell, CloudProperties: iaasConfig.ResourcePool(etcdNetwork1.Subnets[0].Range), } staticIPs, err := etcdNetwork1.StaticIPsFromRange(24) if err != nil { return Manifest{}, err } etcdZ1JobTemplates := []core.JobTemplate{ { Name: "etcd", Release: "etcd", }, } etcdZ1Job := core.Job{ Name: "etcd_z1", Instances: 1, Networks: []core.JobNetwork{{ Name: etcdNetwork1.Name, StaticIPs: []string{staticIPs[0]}, }}, PersistentDisk: 1024, ResourcePool: z1ResourcePool.Name, Templates: etcdZ1JobTemplates, } if config.IPTablesAgent { etcdZ1Job.Templates = append(etcdZ1Job.Templates, core.JobTemplate{ Name: "iptables_agent", Release: "etcd", }) } testconsumerZ1Job := core.Job{ Name: "testconsumer_z1", Instances: 1, Networks: []core.JobNetwork{{ Name: etcdNetwork1.Name, StaticIPs: []string{staticIPs[8]}, }}, PersistentDisk: 1024, ResourcePool: z1ResourcePool.Name, Templates: []core.JobTemplate{ { Name: "etcd_testconsumer", Release: "etcd", }, }, } globalProperties := Properties{ Etcd: &PropertiesEtcd{ Cluster: []PropertiesEtcdCluster{{ Instances: 1, Name: "etcd_z1", }}, Machines: etcdZ1Job.Networks[0].StaticIPs, PeerRequireSSL: false, RequireSSL: false, HeartbeatIntervalInMilliseconds: 50, }, EtcdTestConsumer: &PropertiesEtcdTestConsumer{ Etcd: PropertiesEtcdTestConsumerEtcd{ Machines: etcdZ1Job.Networks[0].StaticIPs, }, }, } if config.TurbulenceHost != "" { globalProperties.TurbulenceAgent = &core.PropertiesTurbulenceAgent{ API: core.PropertiesTurbulenceAgentAPI{ Host: config.TurbulenceHost, Password: turbulence.DefaultPassword, CACert: turbulence.APICACert, }, } etcdZ1Job.Templates = append(etcdZ1Job.Templates, core.JobTemplate{ Name: "turbulence_agent", Release: "turbulence", }) releases = append(releases, core.Release{ Name: "turbulence", Version: "latest", }) } return Manifest{ DirectorUUID: config.DirectorUUID, Name: config.Name, Compilation: compilation, Jobs: []core.Job{ etcdZ1Job, testconsumerZ1Job, }, Networks: []core.Network{ etcdNetwork1, }, Properties: globalProperties, Releases: releases, ResourcePools: []core.ResourcePool{ z1ResourcePool, }, Update: update, }, nil }
func NewManifest(config Config, iaasConfig iaas.Config) (Manifest, error) { turbulenceRelease := core.Release{ Name: "turbulence", Version: "latest", } cidrBlock, err := core.ParseCIDRBlock(config.IPRange) if err != nil { return Manifest{}, err } cloudProperties := iaasConfig.NetworkSubnet(config.IPRange) cpi := iaasConfig.CPI() cpiRelease := core.Release{ Name: cpi.ReleaseName, Version: "latest", } turbulenceNetwork := core.Network{ Name: "turbulence", Subnets: []core.NetworkSubnet{{ CloudProperties: cloudProperties, Gateway: cidrBlock.GetFirstIP().Add(1).String(), Range: cidrBlock.String(), Reserved: []string{cidrBlock.Range(2, 3), cidrBlock.GetLastIP().String()}, Static: []string{cidrBlock.Range(4, cidrBlock.CIDRSize-5)}, }}, Type: "manual", } update := core.Update{ Canaries: 1, CanaryWatchTime: "1000-180000", MaxInFlight: 1, Serial: true, UpdateWatchTime: "1000-180000", } staticIps, err := turbulenceNetwork.StaticIPsFromRange(17) if err != nil { return Manifest{}, err } vmType := "default" if config.BOSH.VMType != "" { vmType = config.BOSH.VMType } persistentDiskType := "default" if config.BOSH.PersistentDiskType != "" { persistentDiskType = config.BOSH.PersistentDiskType } apiJob := core.InstanceGroup{ Instances: 1, Name: "api", AZs: []string{"z1"}, Networks: []core.InstanceGroupNetwork{ { Name: "private", StaticIPs: []string{ staticIps[16], }, }, }, VMType: vmType, Stemcell: "default", PersistentDiskType: persistentDiskType, Jobs: []core.InstanceGroupJob{ { Name: "turbulence_api", Release: turbulenceRelease.Name, }, { Name: cpi.JobName, Release: cpiRelease.Name, }, }, } directorCACert := BOSHDirectorCACert if config.BOSH.DirectorCACert != "" { directorCACert = config.BOSH.DirectorCACert } iaasProperties := iaasConfig.Properties(staticIps[16]) turbulenceProperties := Properties{ WardenCPI: iaasProperties.WardenCPI, AWS: iaasProperties.AWS, Registry: iaasProperties.Registry, Blobstore: iaasProperties.Blobstore, Agent: iaasProperties.Agent, TurbulenceAPI: &PropertiesTurbulenceAPI{ Certificate: APICertificate, CPIJobName: cpi.JobName, Director: PropertiesTurbulenceAPIDirector{ CACert: directorCACert, Host: config.BOSH.Target, Password: config.BOSH.Password, Username: config.BOSH.Username, }, Password: DefaultPassword, PrivateKey: APIPrivateKey, }, } return Manifest{ DirectorUUID: config.DirectorUUID, Name: config.Name, Stemcells: []core.Stemcell{ { Alias: "default", Version: "latest", Name: iaasConfig.Stemcell(), }, }, Releases: []core.Release{turbulenceRelease, cpiRelease}, Update: update, InstanceGroups: []core.InstanceGroup{apiJob}, Properties: turbulenceProperties, }, nil }
Expect(ips).To(HaveLen(0)) }) }) Describe("StaticIPsFromRange", func() { BeforeEach(func() { network = core.Network{ Subnets: []core.NetworkSubnet{ {Static: []string{"10.0.0.1-10.0.0.2"}}, {Static: []string{"10.0.0.3 - 10.0.0.4"}}, }, } }) It("returns the requested number of ips", func() { ips, err := network.StaticIPsFromRange(3) Expect(err).NotTo(HaveOccurred()) Expect(ips).To(HaveLen(3)) Expect(ips).To(ConsistOf([]string{"10.0.0.1", "10.0.0.2", "10.0.0.3"})) }) Context("failure cases", func() { It("returns an error when the count is greater than the number of ips in range", func() { _, err := network.StaticIPsFromRange(5) Expect(err).To(MatchError("can't allocate 5 ips from 4 available ips")) }) It("returns an error when the count is less than zero", func() { _, err := network.StaticIPsFromRange(-1) Expect(err).To(MatchError("count must be greater than or equal to zero"))