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
}
Example #6
0
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
}
Example #8
0
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"))