func jobIndexOfLeader(kv consulclient.HTTPKV, client bosh.Client, deploymentName string) (int, error) { resp, err := http.Get(fmt.Sprintf("%s/v1/status/leader", kv.Address())) if err != nil { return -1, err } var leader string if err := json.NewDecoder(resp.Body).Decode(&leader); err != nil { return -1, err } vms, err := client.DeploymentVMs(deploymentName) if err != nil { return -1, err } for _, vm := range vms { if len(vm.IPs) > 0 { if vm.IPs[0] == strings.Split(leader, ":")[0] { return vm.Index, nil } } } return -1, errors.New("could not determine leader") }
func downloadAndUploadRelease(boshClient bosh.Client, release string) error { file, size, err := download(release) if err != nil { return err } _, err = boshClient.UploadRelease(bosh.NewSizeReader(file, size)) return err }
func downloadAndUploadStemcell(boshClient bosh.Client, stemcell string) error { file, size, err := download(stemcell) if err != nil { return err } _, err = boshClient.UploadStemcell(bosh.NewSizeReader(file, size)) return err }
func DeploymentVMs(boshClient bosh.Client, deploymentName string) ([]bosh.VM, error) { vms, err := boshClient.DeploymentVMs(deploymentName) if err != nil { return nil, err } for index := range vms { vms[index].IPs = nil } return vms, nil }
func DownloadLatestConsulRelease(client bosh.Client) (string, error) { resp, err := http.Get("http://bosh.io/api/v1/releases/github.com/cloudfoundry-incubator/consul-release") if err != nil { return "", err } defer resp.Body.Close() releases := []release{} json.NewDecoder(resp.Body).Decode(&releases) if len(releases) < 1 { return "", errors.New("no releases") } dir, err := ioutil.TempDir("", "") if err != nil { return "", err } out, err := os.Create(filepath.Join(dir, "consul-release.tgz")) if err != nil { return "", err } defer out.Close() resp, err = http.Get(releases[0].URL) if err != nil { return "", err } defer resp.Body.Close() _, err = io.Copy(out, resp.Body) if err != nil { return "", err } _, err = out.Seek(0, 0) if err != nil { return "", err } info, err := out.Stat() if err != nil { return "", err } _, err = client.UploadRelease(bosh.NewSizeReader(out, info.Size())) if err != nil { return "", err } return releases[0].Version, nil }
func DeployEtcdWithInstanceCount(count int, client bosh.Client, config Config) (manifest destiny.Manifest, err error) { guid, err := NewGUID() if err != nil { return } info, err := client.Info() if err != nil { return } manifestConfig := destiny.Config{ DirectorUUID: info.UUID, Name: fmt.Sprintf("etcd-%s", guid), } switch info.CPI { case "aws_cpi": manifestConfig.IAAS = destiny.AWS if config.AWS.Subnet != "" { manifestConfig.AWS.Subnet = config.AWS.Subnet } else { err = errors.New("AWSSubnet is required for AWS IAAS deployment") return } case "warden_cpi": manifestConfig.IAAS = destiny.Warden default: err = errors.New("unknown infrastructure type") return } manifest = destiny.NewEtcd(manifestConfig) manifest.Jobs[0], manifest.Properties = destiny.SetJobInstanceCount(manifest.Jobs[0], manifest.Networks[0], manifest.Properties, count) yaml, err := manifest.ToYAML() if err != nil { return } yaml, err = client.ResolveManifestVersions(yaml) if err != nil { return } manifest, err = destiny.FromYAML(yaml) if err != nil { return } err = client.Deploy(yaml) if err != nil { return } return }
func VerifyDeploymentRelease(client bosh.Client, deploymentName string, releaseVersion string) (err error) { deployments, err := client.Deployments() if err != nil { return } for _, deployment := range deployments { if deployment.Name == deploymentName { for _, release := range deployment.Releases { if release.Name == "consul" { switch { case len(release.Versions) > 1: err = errors.New("too many releases") case len(release.Versions) == 1 && release.Versions[0] != releaseVersion: err = fmt.Errorf("expected consul-release version %q but got %q", releaseVersion, release.Versions[0]) } } } } } return }
package precheck_test import ( "fmt" "testing" "acceptance-tests/testing/helpers" "github.com/pivotal-cf-experimental/bosh-test/bosh" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var ( config helpers.Config client bosh.Client ) func TestDeploy(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "precheck") } var _ = BeforeSuite(func() { configPath, err := helpers.ConfigPath() Expect(err).NotTo(HaveOccurred()) config, err = helpers.LoadConfig(configPath) Expect(err).NotTo(HaveOccurred()) client = bosh.NewClient(bosh.Config{
import ( "net/http" "net/http/httptest" "github.com/pivotal-cf-experimental/bosh-test/bosh" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("locks", func() { It("returns active locks from the bosh director", func() { var ( client bosh.Client serverCallCount int ) server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { serverCallCount++ Expect(r.URL.Path).To(Equal("/locks")) Expect(r.Method).To(Equal("GET")) username, password, ok := r.BasicAuth() Expect(ok).To(BeTrue()) Expect(username).To(Equal("some-username")) Expect(password).To(Equal("some-password")) w.Write([]byte(`[{"type":"deployment","resource":["some-deployment"],"timeout":"1475796348.793560"}]`)) })) client = bosh.NewClient(bosh.Config{
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestTurbulence(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "turbulence") } var ( config helpers.Config client bosh.Client turbulenceManifest destiny.Manifest turbulenceClient turbulence.Client ) var _ = BeforeSuite(func() { configPath, err := helpers.ConfigPath() Expect(err).NotTo(HaveOccurred()) config, err = helpers.LoadConfig(configPath) Expect(err).NotTo(HaveOccurred()) client = bosh.NewClient(bosh.Config{ URL: fmt.Sprintf("https://%s:25555", config.BOSH.Target), Username: config.BOSH.Username, Password: config.BOSH.Password,
func DeployTurbulence(client bosh.Client, config Config) (turbulence.Manifest, error) { info, err := client.Info() if err != nil { return turbulence.Manifest{}, err } guid, err := NewGUID() if err != nil { return turbulence.Manifest{}, err } manifestConfig := turbulence.Config{ DirectorUUID: info.UUID, Name: "turbulence-consul-" + guid, BOSH: turbulence.ConfigBOSH{ Target: config.BOSH.Target, Username: config.BOSH.Username, Password: config.BOSH.Password, DirectorCACert: config.BOSH.DirectorCACert, }, } var iaasConfig iaas.Config switch info.CPI { case "aws_cpi": awsConfig := iaas.AWSConfig{ AccessKeyID: config.AWS.AccessKeyID, SecretAccessKey: config.AWS.SecretAccessKey, DefaultKeyName: config.AWS.DefaultKeyName, DefaultSecurityGroups: config.AWS.DefaultSecurityGroups, Region: config.AWS.Region, RegistryHost: config.Registry.Host, RegistryPassword: config.Registry.Password, RegistryPort: config.Registry.Port, RegistryUsername: config.Registry.Username, } manifestConfig.BOSH.PersistentDiskType = config.BOSH.Errand.DefaultPersistentDiskType manifestConfig.BOSH.VMType = config.BOSH.Errand.DefaultVMType if len(config.AWS.Subnets) > 0 { subnet := config.AWS.Subnets[0] var cidrBlock string cidrPool := NewCIDRPool(subnet.Range, 24, 27) cidrBlock, err = cidrPool.Last() if err != nil { return turbulence.Manifest{}, err } awsConfig.Subnets = append(awsConfig.Subnets, iaas.AWSConfigSubnet{ID: subnet.ID, Range: cidrBlock, AZ: subnet.AZ, SecurityGroup: subnet.SecurityGroup}) manifestConfig.IPRange = cidrBlock } else { return turbulence.Manifest{}, errors.New("aws.subnet is required for AWS IAAS deployment") } iaasConfig = awsConfig case "warden_cpi": var cidrBlock string cidrPool := NewCIDRPool("10.244.4.0", 24, 27) cidrBlock, err = cidrPool.Last() if err != nil { return turbulence.Manifest{}, err } manifestConfig.IPRange = cidrBlock iaasConfig = iaas.NewWardenConfig() default: return turbulence.Manifest{}, errors.New("unknown infrastructure type") } turbulenceManifest, err := turbulence.NewManifest(manifestConfig, iaasConfig) if err != nil { return turbulence.Manifest{}, err } yaml, err := turbulenceManifest.ToYAML() if err != nil { return turbulence.Manifest{}, err } yaml, err = client.ResolveManifestVersions(yaml) if err != nil { return turbulence.Manifest{}, err } turbulenceManifest, err = turbulence.FromYAML(yaml) if err != nil { return turbulence.Manifest{}, err } _, err = client.Deploy(yaml) if err != nil { return turbulence.Manifest{}, err } return turbulenceManifest, nil }
func deployConsul(deploymentPrefix string, count int, client bosh.Client, config Config, releaseVersion string, manifestGenerator ManifestGenerator) (manifest consul.ManifestV2, kv consulclient.HTTPKV, err error) { guid, err := NewGUID() if err != nil { return } info, err := client.Info() if err != nil { return } manifestConfig := consul.ConfigV2{ DirectorUUID: info.UUID, Name: fmt.Sprintf("consul-%s-%s", deploymentPrefix, guid), TurbulenceHost: config.TurbulenceHost, WindowsClients: config.WindowsClients, } var iaasConfig iaas.Config switch info.CPI { case "aws_cpi": manifestConfig.PersistentDiskType = config.BOSH.Errand.DefaultPersistentDiskType manifestConfig.VMType = config.BOSH.Errand.DefaultVMType awsConfig := buildAWSConfig(config) if len(config.AWS.Subnets) > 0 { subnet := config.AWS.Subnets[0] var cidrBlock string cidrPool := NewCIDRPool(subnet.Range, 24, 27) cidrBlock, err = cidrPool.Get(ginkgoConfig.GinkgoConfig.ParallelNode) if err != nil { return } awsConfig.Subnets = append(awsConfig.Subnets, iaas.AWSConfigSubnet{ID: subnet.ID, Range: cidrBlock, AZ: subnet.AZ, SecurityGroup: subnet.SecurityGroup}) manifestConfig.AZs = append(manifestConfig.AZs, consul.ConfigAZ{IPRange: cidrBlock, Nodes: count, Name: "z1"}) } else { err = errors.New("AWSSubnet is required for AWS IAAS deployment") return } iaasConfig = awsConfig case "warden_cpi": iaasConfig = iaas.NewWardenConfig() var cidrBlock string cidrPool := NewCIDRPool("10.244.4.0", 24, 27) cidrBlock, err = cidrPool.Get(ginkgoConfig.GinkgoConfig.ParallelNode) if err != nil { return } manifestConfig.AZs = []consul.ConfigAZ{ { IPRange: cidrBlock, Nodes: count, Name: "z1", }, } default: err = errors.New("unknown infrastructure type") return } manifest, err = manifestGenerator(manifestConfig, iaasConfig) if err != nil { return } for i := range manifest.Releases { if manifest.Releases[i].Name == "consul" { manifest.Releases[i].Version = releaseVersion } } yaml, err := manifest.ToYAML() if err != nil { return } yaml, err = client.ResolveManifestVersions(yaml) if err != nil { return } err = consul.FromYAML(yaml, &manifest) if err != nil { return } _, err = client.Deploy(yaml) if err != nil { return } err = VerifyDeploymentRelease(client, manifestConfig.Name, releaseVersion) if err != nil { return } kv = consulclient.NewHTTPKV(fmt.Sprintf("http://%s:6769", manifest.InstanceGroups[1].Networks[0].StaticIPs[0])) return }
func DeployMultiAZConsulMigration(client bosh.Client, config Config, deploymentName string) (consul.ManifestV2, error) { info, err := client.Info() if err != nil { return consul.ManifestV2{}, err } manifestConfig := consul.ConfigV2{ DirectorUUID: info.UUID, Name: deploymentName, WindowsClients: config.WindowsClients, } var iaasConfig iaas.Config switch info.CPI { case "aws_cpi": manifestConfig.PersistentDiskType = config.BOSH.Errand.DefaultPersistentDiskType manifestConfig.VMType = config.BOSH.Errand.DefaultVMType awsConfig := buildAWSConfig(config) if len(config.AWS.CloudConfigSubnets) >= 2 { subnet := config.AWS.CloudConfigSubnets[0] awsConfig.Subnets = append(awsConfig.Subnets, iaas.AWSConfigSubnet{ID: subnet.ID, Range: subnet.Range, AZ: subnet.AZ, SecurityGroup: subnet.SecurityGroup}) manifestConfig.AZs = append(manifestConfig.AZs, consul.ConfigAZ{Name: "z1", IPRange: subnet.Range, Nodes: 2}) subnet = config.AWS.CloudConfigSubnets[1] awsConfig.Subnets = append(awsConfig.Subnets, iaas.AWSConfigSubnet{ID: subnet.ID, Range: subnet.Range, AZ: subnet.AZ, SecurityGroup: subnet.SecurityGroup}) manifestConfig.AZs = append(manifestConfig.AZs, consul.ConfigAZ{Name: "z2", IPRange: subnet.Range, Nodes: 1}) } else { return consul.ManifestV2{}, errors.New("AWSSubnet is required for AWS IAAS deployment") } iaasConfig = awsConfig case "warden_cpi": iaasConfig = iaas.NewWardenConfig() var cidrBlock string cidrPool := NewCIDRPool("10.244.4.0", 24, 27) cidrBlock, err = cidrPool.Get(0) if err != nil { return consul.ManifestV2{}, err } var cidrBlock2 string cidrPool2 := NewCIDRPool("10.244.5.0", 24, 27) cidrBlock2, err = cidrPool2.Get(0) if err != nil { return consul.ManifestV2{}, err } manifestConfig.AZs = []consul.ConfigAZ{ { Name: "z1", IPRange: cidrBlock, Nodes: 2, }, { Name: "z2", IPRange: cidrBlock2, Nodes: 1, }, } default: return consul.ManifestV2{}, errors.New("unknown infrastructure type") } manifest, err := consul.NewManifestV2(manifestConfig, iaasConfig) if err != nil { return consul.ManifestV2{}, err } consulInstanceGroup, err := manifest.GetInstanceGroup("consul") if err != nil { return consul.ManifestV2{}, err } consulInstanceGroup.MigratedFrom = []core.InstanceGroupMigratedFrom{ { Name: "consul_z1", AZ: "z1", }, { Name: "consul_z2", AZ: "z2", }, } consulTestConsumerInstanceGroup, err := manifest.GetInstanceGroup("test_consumer") if err != nil { return consul.ManifestV2{}, err } consulTestConsumerInstanceGroup.MigratedFrom = []core.InstanceGroupMigratedFrom{ { Name: "consul_test_consumer", AZ: "z1", }, } for i := range manifest.Releases { if manifest.Releases[i].Name == "consul" { manifest.Releases[i].Version = ConsulReleaseVersion() } } manifestYAML, err := manifest.ToYAML() if err != nil { return consul.ManifestV2{}, err } _, err = client.Deploy(manifestYAML) if err != nil { return consul.ManifestV2{}, err } if err := VerifyDeploymentRelease(client, manifestConfig.Name, ConsulReleaseVersion()); err != nil { return consul.ManifestV2{}, err } return manifest, nil }
func DeployMultiAZConsul(deploymentPrefix string, client bosh.Client, config Config) (manifest consul.Manifest, err error) { guid, err := NewGUID() if err != nil { return } info, err := client.Info() if err != nil { return } manifestConfig := consul.Config{ DirectorUUID: info.UUID, Name: fmt.Sprintf("consul-%s-%s", deploymentPrefix, guid), } var iaasConfig iaas.Config switch info.CPI { case "aws_cpi": awsConfig := buildAWSConfig(config) if len(config.AWS.Subnets) >= 2 { subnet := config.AWS.CloudConfigSubnets[0] awsConfig.Subnets = append(awsConfig.Subnets, iaas.AWSConfigSubnet{ID: subnet.ID, Range: subnet.Range, AZ: subnet.AZ, SecurityGroup: subnet.SecurityGroup}) manifestConfig.Networks = append(manifestConfig.Networks, consul.ConfigNetwork{IPRange: subnet.Range, Nodes: 2}) subnet = config.AWS.CloudConfigSubnets[1] awsConfig.Subnets = append(awsConfig.Subnets, iaas.AWSConfigSubnet{ID: subnet.ID, Range: subnet.Range, AZ: subnet.AZ, SecurityGroup: subnet.SecurityGroup}) manifestConfig.Networks = append(manifestConfig.Networks, consul.ConfigNetwork{IPRange: subnet.Range, Nodes: 1}) } else { err = errors.New("AWSSubnet is required for AWS IAAS deployment") return } iaasConfig = awsConfig case "warden_cpi": iaasConfig = iaas.NewWardenConfig() manifestConfig.Networks = []consul.ConfigNetwork{ {IPRange: "10.244.4.0/24", Nodes: 2}, {IPRange: "10.244.5.0/24", Nodes: 1}, } default: err = errors.New("unknown infrastructure type") return } manifest, err = consul.NewManifest(manifestConfig, iaasConfig) if err != nil { return } for i := range manifest.Releases { if manifest.Releases[i].Name == "consul" { manifest.Releases[i].Version = ConsulReleaseVersion() } } yaml, err := manifest.ToYAML() if err != nil { return } yaml, err = client.ResolveManifestVersions(yaml) if err != nil { return } err = consul.FromYAML(yaml, &manifest) if err != nil { return } _, err = client.Deploy(yaml) if err != nil { return } err = VerifyDeploymentRelease(client, manifestConfig.Name, ConsulReleaseVersion()) if err != nil { return } return }
import ( "net/http" "net/http/httptest" "time" "github.com/pivotal-cf-experimental/bosh-test/bosh" "github.com/pivotal-cf-experimental/gomegamatchers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("ResolveManifestVersions", func() { var ( client bosh.Client ) BeforeEach(func() { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() Expect(ok).To(BeTrue()) Expect(username).To(Equal("some-username")) Expect(password).To(Equal("some-password")) switch r.URL.Path { case "/releases/consats": Expect(r.Method).To(Equal("GET")) w.Write([]byte(`{"versions":["2.0.0","3.0.0","4.0.0"]}`)) case "/stemcells": Expect(r.Method).To(Equal("GET"))