func describeHTTPMetadataService() {
	var (
		dnsResolver     *fakeinf.FakeDNSResolver
		platform        *fakeplat.FakePlatform
		logger          boshlog.Logger
		metadataService MetadataService
	)

	BeforeEach(func() {
		dnsResolver = &fakeinf.FakeDNSResolver{}
		platform = fakeplat.NewFakePlatform()
		logger = boshlog.NewLogger(boshlog.LevelNone)
		metadataService = NewHTTPMetadataService("fake-metadata-host", dnsResolver, platform, logger)
	})

	ItEnsuresMinimalNetworkSetup := func(subject func() (string, error)) {
		Context("when no networks are configured", func() {
			BeforeEach(func() {
				platform.GetConfiguredNetworkInterfacesInterfaces = []string{}
			})

			It("sets up DHCP network", func() {
				_, err := subject()
				Expect(err).ToNot(HaveOccurred())

				Expect(platform.SetupNetworkingCalled).To(BeTrue())
				Expect(platform.SetupNetworkingNetworks).To(Equal(boshsettings.Networks{
					"eth0": boshsettings.Network{
						Type: "dynamic",
					},
				}))
			})

			Context("when setting up DHCP fails", func() {
				BeforeEach(func() {
					platform.SetupNetworkingErr = errors.New("fake-network-error")
				})

				It("returns an error", func() {
					_, err := subject()
					Expect(err).To(HaveOccurred())
					Expect(err.Error()).To(ContainSubstring("fake-network-error"))
				})
			})
		})
	}

	Describe("IsAvailable", func() {
		It("returns true", func() {
			Expect(metadataService.IsAvailable()).To(BeTrue())
		})
	})

	Describe("GetPublicKey", func() {
		var (
			ts *httptest.Server
		)

		BeforeEach(func() {
			handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				GinkgoRecover()

				Expect(r.Method).To(Equal("GET"))
				Expect(r.URL.Path).To(Equal("/latest/meta-data/public-keys/0/openssh-key"))

				w.Write([]byte("fake-public-key"))
			})

			ts = httptest.NewServer(handler)

			metadataService = NewHTTPMetadataService(ts.URL, dnsResolver, platform, logger)
		})

		AfterEach(func() {
			ts.Close()
		})

		ItEnsuresMinimalNetworkSetup(func() (string, error) {
			return metadataService.GetPublicKey()
		})

		It("returns fetched public key", func() {
			publicKey, err := metadataService.GetPublicKey()
			Expect(err).NotTo(HaveOccurred())
			Expect(publicKey).To(Equal("fake-public-key"))
		})
	})

	Describe("GetInstanceID", func() {
		var (
			ts *httptest.Server
		)

		BeforeEach(func() {
			handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				GinkgoRecover()

				Expect(r.Method).To(Equal("GET"))
				Expect(r.URL.Path).To(Equal("/latest/meta-data/instance-id"))

				w.Write([]byte("fake-instance-id"))
			})

			ts = httptest.NewServer(handler)

			metadataService = NewHTTPMetadataService(ts.URL, dnsResolver, platform, logger)
		})

		AfterEach(func() {
			ts.Close()
		})

		ItEnsuresMinimalNetworkSetup(func() (string, error) {
			return metadataService.GetInstanceID()
		})

		It("returns fetched instance id", func() {
			publicKey, err := metadataService.GetInstanceID()
			Expect(err).NotTo(HaveOccurred())
			Expect(publicKey).To(Equal("fake-instance-id"))
		})
	})

	Describe("GetServerName", func() {
		var (
			ts         *httptest.Server
			serverName *string
		)

		handlerFunc := func(w http.ResponseWriter, r *http.Request) {
			GinkgoRecover()

			Expect(r.Method).To(Equal("GET"))
			Expect(r.URL.Path).To(Equal("/latest/user-data"))

			var jsonStr string

			if serverName == nil {
				jsonStr = `{}`
			} else {
				jsonStr = fmt.Sprintf(`{"server":{"name":"%s"}}`, *serverName)
			}

			w.Write([]byte(jsonStr))
		}

		BeforeEach(func() {
			serverName = nil

			handler := http.HandlerFunc(handlerFunc)
			ts = httptest.NewServer(handler)
			metadataService = NewHTTPMetadataService(ts.URL, dnsResolver, platform, logger)
		})

		AfterEach(func() {
			ts.Close()
		})

		Context("when the server name is present in the JSON", func() {
			BeforeEach(func() {
				name := "fake-server-name"
				serverName = &name
			})

			It("returns the server name", func() {
				name, err := metadataService.GetServerName()
				Expect(err).ToNot(HaveOccurred())
				Expect(name).To(Equal("fake-server-name"))
			})

			ItEnsuresMinimalNetworkSetup(func() (string, error) {
				return metadataService.GetServerName()
			})
		})

		Context("when the server name is not present in the JSON", func() {
			BeforeEach(func() {
				serverName = nil
			})

			It("returns an error", func() {
				name, err := metadataService.GetServerName()
				Expect(err).To(HaveOccurred())
				Expect(name).To(BeEmpty())
			})
		})
	})

	Describe("GetRegistryEndpoint", func() {
		var (
			ts          *httptest.Server
			registryURL *string
			dnsServer   *string
		)

		handlerFunc := func(w http.ResponseWriter, r *http.Request) {
			GinkgoRecover()

			Expect(r.Method).To(Equal("GET"))
			Expect(r.URL.Path).To(Equal("/latest/user-data"))

			var jsonStr string

			if dnsServer == nil {
				jsonStr = fmt.Sprintf(`{"registry":{"endpoint":"%s"}}`, *registryURL)
			} else {
				jsonStr = fmt.Sprintf(`{
					"registry":{"endpoint":"%s"},
					"dns":{"nameserver":["%s"]}
				}`, *registryURL, *dnsServer)
			}

			w.Write([]byte(jsonStr))
		}

		BeforeEach(func() {
			url := "http://fake-registry.com"
			registryURL = &url
			dnsServer = nil

			handler := http.HandlerFunc(handlerFunc)
			ts = httptest.NewServer(handler)
			metadataService = NewHTTPMetadataService(ts.URL, dnsResolver, platform, logger)
		})

		AfterEach(func() {
			ts.Close()
		})

		ItEnsuresMinimalNetworkSetup(func() (string, error) {
			return metadataService.GetRegistryEndpoint()
		})

		Context("when metadata contains a dns server", func() {
			BeforeEach(func() {
				server := "fake-dns-server-ip"
				dnsServer = &server
			})

			Context("when registry endpoint is successfully resolved", func() {
				BeforeEach(func() {
					dnsResolver.RegisterRecord(fakeinf.FakeDNSRecord{
						DNSServers: []string{"fake-dns-server-ip"},
						Host:       "http://fake-registry.com",
						IP:         "http://fake-registry-ip",
					})
				})

				It("returns the successfully resolved registry endpoint", func() {
					endpoint, err := metadataService.GetRegistryEndpoint()
					Expect(err).ToNot(HaveOccurred())
					Expect(endpoint).To(Equal("http://fake-registry-ip"))
				})
			})

			Context("when registry endpoint is not successfully resolved", func() {
				BeforeEach(func() {
					dnsResolver.LookupHostErr = errors.New("fake-lookup-host-err")
				})

				It("returns error because it failed to resolve registry endpoint", func() {
					endpoint, err := metadataService.GetRegistryEndpoint()
					Expect(err).To(HaveOccurred())
					Expect(err.Error()).To(ContainSubstring("fake-lookup-host-err"))
					Expect(endpoint).To(BeEmpty())
				})
			})
		})

		Context("when metadata does not contain dns servers", func() {
			It("returns fetched registry endpoint", func() {
				endpoint, err := metadataService.GetRegistryEndpoint()
				Expect(err).NotTo(HaveOccurred())
				Expect(endpoint).To(Equal("http://fake-registry.com"))
			})
		})
	})

	Describe("GetNetworks", func() {
		It("returns nil networks, since you don't need them for bootstrapping since your network must be set up before you can get the metadata", func() {
			Expect(metadataService.GetNetworks()).To(BeNil())
		})
	})
}
import (
	"encoding/json"
	"errors"

	. "github.com/cloudfoundry/bosh-init/internal/github.com/onsi/ginkgo"
	. "github.com/cloudfoundry/bosh-init/internal/github.com/onsi/gomega"

	. "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-agent/infrastructure"
	fakeplatform "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-agent/platform/fakes"
	boshlog "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/logger"
)

var _ = Describe("ConfigDriveSettingsSource", func() {
	var (
		platform *fakeplatform.FakePlatform
		source   *ConfigDriveSettingsSource
	)

	BeforeEach(func() {
		diskPaths := []string{"/fake-disk-path-1", "/fake-disk-path-2"}
		metadataPath := "fake-metadata-path"
		settingsPath := "fake-settings-path"
		platform = fakeplatform.NewFakePlatform()
		logger := boshlog.NewLogger(boshlog.LevelNone)
		source = NewConfigDriveSettingsSource(diskPaths, metadataPath, settingsPath, platform, logger)
	})

	BeforeEach(func() {
		// Set up default settings and metadata
		platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-metadata-path", []byte(`{}`), nil)
		platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-settings-path", []byte(`{}`), nil)
package infrastructure_test

import (
	"errors"

	. "github.com/cloudfoundry/bosh-init/internal/github.com/onsi/ginkgo"
	. "github.com/cloudfoundry/bosh-init/internal/github.com/onsi/gomega"

	. "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-agent/infrastructure"
	fakeplatform "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-agent/platform/fakes"
	boshlog "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/logger"
)

var _ = Describe("ConfigDriveSettingsSource", func() {
	var (
		platform *fakeplatform.FakePlatform
		source   *CDROMSettingsSource
	)

	BeforeEach(func() {
		settingsFileName := "fake-settings-file-name"
		platform = fakeplatform.NewFakePlatform()
		logger := boshlog.NewLogger(boshlog.LevelNone)
		source = NewCDROMSettingsSource(settingsFileName, platform, logger)
	})

	Describe("PublicSSHKeyForUsername", func() {
		It("returns an empty string", func() {
			publicKey, err := source.PublicSSHKeyForUsername("fake-username")
			Expect(err).ToNot(HaveOccurred())
			Expect(publicKey).To(Equal(""))
		})
func describeConfigDriveMetadataService() {
	var (
		metadataService MetadataService
		resolver        *fakeinf.FakeDNSResolver
		platform        *fakeplatform.FakePlatform
		logger          boshlog.Logger
	)

	updateMetadata := func(metadataContents MetadataContentsType) {
		metadataJSON, err := json.Marshal(metadataContents)
		Expect(err).ToNot(HaveOccurred())
		platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-metadata-path", metadataJSON, nil)

		Expect(metadataService.IsAvailable()).To(BeTrue())
	}

	updateUserdata := func(userdataContents string) {
		platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-userdata-path", []byte(userdataContents), nil)

		Expect(metadataService.IsAvailable()).To(BeTrue())
	}

	BeforeEach(func() {
		resolver = &fakeinf.FakeDNSResolver{}
		platform = fakeplatform.NewFakePlatform()
		logger = boshlog.NewLogger(boshlog.LevelNone)
		diskPaths := []string{
			"/fake-disk-path-1",
			"/fake-disk-path-2",
		}
		metadataService = NewConfigDriveMetadataService(
			resolver,
			platform,
			diskPaths,
			"fake-metadata-path",
			"fake-userdata-path",
			logger,
		)

		userdataContents := fmt.Sprintf(`{"server":{"name":"fake-server-name"},"registry":{"endpoint":"fake-registry-endpoint"}}`)
		platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-userdata-path", []byte(userdataContents), nil)

		metadata := MetadataContentsType{
			PublicKeys: map[string]PublicKeyType{
				"0": PublicKeyType{
					"openssh-key": "fake-openssh-key",
				},
			},
			InstanceID: "fake-instance-id",
		}
		updateMetadata(metadata)
	})

	Describe("GetNetworks", func() {
		It("returns the network settings", func() {
			userdataContents := `
				{
					"networks": {
						"network_1": {"type": "manual", "ip": "1.2.3.4", "netmask": "2.3.4.5", "gateway": "3.4.5.6", "default": ["dns"], "dns": ["8.8.8.8"], "mac": "fake-mac-address-1"},
						"network_2": {"type": "dynamic", "default": ["dns"], "dns": ["8.8.8.8"], "mac": "fake-mac-address-2"}
					}
				}`
			updateUserdata(userdataContents)

			networks, err := metadataService.GetNetworks()
			Expect(err).ToNot(HaveOccurred())
			Expect(networks).To(Equal(boshsettings.Networks{
				"network_1": boshsettings.Network{
					Type:    "manual",
					IP:      "1.2.3.4",
					Netmask: "2.3.4.5",
					Gateway: "3.4.5.6",
					Default: []string{"dns"},
					DNS:     []string{"8.8.8.8"},
					Mac:     "fake-mac-address-1",
				},
				"network_2": boshsettings.Network{
					Type:    "dynamic",
					Default: []string{"dns"},
					DNS:     []string{"8.8.8.8"},
					Mac:     "fake-mac-address-2",
				},
			}))
		})

		It("returns a nil Networks if the settings are missing (from an old CPI version)", func() {
			userdataContents := `{}`
			updateUserdata(userdataContents)

			networks, err := metadataService.GetNetworks()
			Expect(err).ToNot(HaveOccurred())
			Expect(networks).To(BeNil())
		})
	})

	Describe("IsAvailable", func() {
		It("return true when it can load successfully", func() {
			Expect(metadataService.IsAvailable()).To(BeTrue())
		})

		It("returns an error if it fails to read meta-data.json from disk", func() {
			platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-metadata-path", []byte{}, errors.New("fake-read-disk-error"))
			Expect(metadataService.IsAvailable()).To(BeFalse())
		})

		It("tries to load meta-data.json from potential disk locations", func() {
			platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-metadata-path", []byte{}, errors.New("fake-read-disk-error"))
			Expect(metadataService.IsAvailable()).To(BeFalse())

			Expect(platform.GetFileContentsFromDiskDiskPaths).To(ContainElement("/fake-disk-path-1"))
			Expect(platform.GetFileContentsFromDiskDiskPaths).To(ContainElement("/fake-disk-path-2"))
		})

		It("returns an error if it fails to parse meta-data.json contents", func() {
			platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-metadata-path", []byte("broken"), nil)
			Expect(metadataService.IsAvailable()).To(BeFalse())
		})

		It("returns an error if it fails to read user_data from disk", func() {
			platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-userdata-path", []byte{}, errors.New("fake-read-disk-error"))
			Expect(metadataService.IsAvailable()).To(BeFalse())
		})

		It("returns an error if it fails to parse user_data contents", func() {
			platform.SetGetFilesContentsFromDisk("/fake-disk-path-1/fake-userdata-path", []byte("broken"), nil)
			Expect(metadataService.IsAvailable()).To(BeFalse())
		})

		Context("when disk paths are not given", func() {
			It("returns false", func() {
				metadataService = NewConfigDriveMetadataService(
					resolver,
					platform,
					[]string{},
					"fake-metadata-path",
					"fake-userdata-path",
					logger,
				)
				Expect(metadataService.IsAvailable()).To(BeFalse())
			})
		})
	})

	Describe("GetPublicKey", func() {
		It("returns public key", func() {
			value, err := metadataService.GetPublicKey()
			Expect(err).ToNot(HaveOccurred())
			Expect(value).To(Equal("fake-openssh-key"))
		})

		It("returns an error if it fails to get ssh key", func() {
			updateMetadata(MetadataContentsType{})

			value, err := metadataService.GetPublicKey()
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("Failed to load openssh-key from config drive metadata service"))

			Expect(value).To(Equal(""))
		})
	})

	Describe("GetInstanceID", func() {
		It("returns instance id", func() {
			value, err := metadataService.GetInstanceID()
			Expect(err).ToNot(HaveOccurred())
			Expect(value).To(Equal("fake-instance-id"))
		})

		It("returns an error if it fails to get instance id", func() {
			updateMetadata(MetadataContentsType{})

			value, err := metadataService.GetInstanceID()
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("Failed to load instance-id from config drive metadata service"))

			Expect(value).To(Equal(""))
		})
	})

	Describe("GetServerName", func() {
		It("returns server name", func() {
			value, err := metadataService.GetServerName()
			Expect(err).ToNot(HaveOccurred())
			Expect(value).To(Equal("fake-server-name"))
		})

		It("returns an error if it fails to get server name", func() {
			updateUserdata("{}")

			value, err := metadataService.GetServerName()
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("Failed to load server name from config drive metadata service"))

			Expect(value).To(Equal(""))
		})
	})

	Describe("GetRegistryEndpoint", func() {
		It("returns an error if it fails to get registry endpoint", func() {
			updateUserdata("{}")

			value, err := metadataService.GetRegistryEndpoint()
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("Failed to load registry endpoint from config drive metadata service"))

			Expect(value).To(Equal(""))
		})

		Context("when user_data does not contain a dns server", func() {
			It("returns registry endpoint", func() {
				value, err := metadataService.GetRegistryEndpoint()
				Expect(err).ToNot(HaveOccurred())
				Expect(value).To(Equal("fake-registry-endpoint"))
			})
		})

		Context("when user_data contains a dns server", func() {
			BeforeEach(func() {
				userdataContents := fmt.Sprintf(
					`{"server":{"name":"%s"},"registry":{"endpoint":"%s"},"dns":{"nameserver":["%s"]}}`,
					"fake-server-name",
					"http://fake-registry.com",
					"fake-dns-server-ip",
				)
				updateUserdata(userdataContents)
			})

			Context("when registry endpoint is successfully resolved", func() {
				BeforeEach(func() {
					resolver.RegisterRecord(fakeinf.FakeDNSRecord{
						DNSServers: []string{"fake-dns-server-ip"},
						Host:       "http://fake-registry.com",
						IP:         "http://fake-registry-ip",
					})
				})

				It("returns the successfully resolved registry endpoint", func() {
					endpoint, err := metadataService.GetRegistryEndpoint()
					Expect(err).ToNot(HaveOccurred())
					Expect(endpoint).To(Equal("http://fake-registry-ip"))
				})
			})

			Context("when registry endpoint is not successfully resolved", func() {
				BeforeEach(func() {
					resolver.LookupHostErr = errors.New("fake-lookup-host-err")
				})

				It("returns error because it failed to resolve registry endpoint", func() {
					endpoint, err := metadataService.GetRegistryEndpoint()
					Expect(err).To(HaveOccurred())
					Expect(err.Error()).To(ContainSubstring("fake-lookup-host-err"))
					Expect(endpoint).To(BeEmpty())
				})
			})
		})
	})
}
package infrastructure_test

import (
	. "github.com/cloudfoundry/bosh-init/internal/github.com/onsi/ginkgo"
	. "github.com/cloudfoundry/bosh-init/internal/github.com/onsi/gomega"

	. "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-agent/infrastructure"
	fakeplat "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-agent/platform/fakes"
	boshlog "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/logger"
)

var _ = Describe("SettingsSourceFactory", func() {
	Describe("New", func() {
		var (
			options  SettingsOptions
			platform *fakeplat.FakePlatform
			logger   boshlog.Logger
			factory  SettingsSourceFactory
		)

		BeforeEach(func() {
			options = SettingsOptions{}
			platform = fakeplat.NewFakePlatform()
			logger = boshlog.NewLogger(boshlog.LevelNone)
		})

		JustBeforeEach(func() {
			factory = NewSettingsSourceFactory(options, platform, logger)
		})

		Context("when UseRegistry is set to true", func() {
			BeforeEach(func() {
Beispiel #6
0
func describeHTTPRegistry() {
	var (
		metadataService *fakeinf.FakeMetadataService
		registry        Registry
		platform        *fakeplat.FakePlatform
	)

	BeforeEach(func() {
		metadataService = &fakeinf.FakeMetadataService{}
		platform = &fakeplat.FakePlatform{}
		registry = NewHTTPRegistry(metadataService, platform, false)
	})

	Describe("GetSettings", func() {
		var (
			ts           *httptest.Server
			settingsJSON string
		)

		BeforeEach(func() {
			boshRegistryHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				GinkgoRecover()

				Expect(r.Method).To(Equal("GET"))
				Expect(r.URL.Path).To(Equal("/instances/fake-identifier/settings"))

				w.Write([]byte(settingsJSON))
			})

			ts = httptest.NewServer(boshRegistryHandler)
		})

		AfterEach(func() {
			ts.Close()
		})

		Describe("Network bootstrapping", func() {
			BeforeEach(func() {
				settingsJSON = `{"settings": "{\"agent_id\":\"my-agent-id\"}"}`
				metadataService.InstanceID = "fake-identifier"
				metadataService.RegistryEndpoint = ts.URL
				registry = NewHTTPRegistry(metadataService, platform, false)
			})

			Context("when the metadata has Networks information", func() {
				It("configures the network with those settings before hitting the registry", func() {
					networkSettings := boshsettings.Networks{
						"net1": boshsettings.Network{IP: "1.2.3.4"},
						"net2": boshsettings.Network{IP: "2.3.4.5"},
					}
					metadataService.Networks = networkSettings

					_, err := registry.GetSettings()
					Expect(err).ToNot(HaveOccurred())

					Expect(platform.SetupNetworkingCalled).To(BeTrue())
					Expect(platform.SetupNetworkingNetworks).To(Equal(networkSettings))
				})
			})

			Context("when the metadata has no Networks information", func() {
				It("does no network configuration for now (the stemcell set up dhcp already)", func() {
					metadataService.Networks = boshsettings.Networks{}

					_, err := registry.GetSettings()
					Expect(err).ToNot(HaveOccurred())

					Expect(platform.SetupNetworkingCalled).To(BeFalse())
				})
			})

			Context("when the metadata service fails to get Networks information", func() {
				It("wraps the error", func() {
					metadataService.Networks = boshsettings.Networks{}
					metadataService.NetworksErr = errors.New("fake-get-networks-err")

					_, err := registry.GetSettings()
					Expect(err).To(HaveOccurred())

					Expect(err.Error()).To(Equal("Getting networks: fake-get-networks-err"))
				})
			})

			Context("when the SetupNetworking fails", func() {
				It("wraps the error", func() {
					networkSettings := boshsettings.Networks{
						"net1": boshsettings.Network{IP: "1.2.3.4"},
						"net2": boshsettings.Network{IP: "2.3.4.5"},
					}
					metadataService.Networks = networkSettings
					platform.SetupNetworkingErr = errors.New("fake-setup-networking-error")

					_, err := registry.GetSettings()
					Expect(err).To(HaveOccurred())

					Expect(err.Error()).To(Equal("Setting up networks: fake-setup-networking-error"))
				})
			})
		})

		Context("when registry is configured to not use server name as id", func() {
			BeforeEach(func() {
				registry = NewHTTPRegistry(metadataService, platform, false)
				metadataService.InstanceID = "fake-identifier"
				metadataService.RegistryEndpoint = ts.URL
			})

			It("returns settings fetched from http server based on instance id", func() {
				settingsJSON = `{"settings": "{\"agent_id\":\"my-agent-id\"}"}`

				settings, err := registry.GetSettings()
				Expect(err).ToNot(HaveOccurred())
				Expect(settings).To(Equal(boshsettings.Settings{AgentID: "my-agent-id"}))
			})

			It("returns error if registry settings wrapper cannot be parsed", func() {
				settingsJSON = "invalid-json"

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Unmarshalling settings wrapper"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})

			It("returns error if registry settings wrapper contains invalid json", func() {
				settingsJSON = `{"settings": "invalid-json"}`

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Unmarshalling wrapped settings"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})

			It("returns error if metadata service fails to return instance id", func() {
				metadataService.GetInstanceIDErr = errors.New("fake-get-instance-id-err")

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("fake-get-instance-id-err"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})

			It("returns error if metadata service fails to return registry endpoint", func() {
				metadataService.GetRegistryEndpointErr = errors.New("fake-get-registry-endpoint-err")

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("fake-get-registry-endpoint-err"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})

			Describe("setting fields", func() {
				It("unmarshalls JSON properly", func() {
					settingsJSON = `{
						"agent_id": "my-agent-id",
						"blobstore": {
							"options": {
								"bucket_name": "george",
								"encryption_key": "optional encryption key",
								"access_key_id": "optional access key id",
								"secret_access_key": "optional secret access key",
								"port": 443
							},
							"provider": "s3"
						},
						"disks": {
							"ephemeral": "/dev/sdb",
							"persistent": {
								"vol-xxxxxx": "/dev/sdf"
							},
							"system": "/dev/sda1"
						},
						"env": {
							"bosh": {
								"password": "******"
							}
						},
						"networks": {
							"netA": {
								"default": ["dns", "gateway"],
								"ip": "ww.ww.ww.ww",
								"dns": [
									"xx.xx.xx.xx",
									"yy.yy.yy.yy"
								]
							},
							"netB": {
								"dns": [
									"zz.zz.zz.zz"
								]
							}
						},
						"mbus": "https://*****:*****@0.0.0.0:6868",
						"ntp": [
							"0.north-america.pool.ntp.org",
							"1.north-america.pool.ntp.org"
						],
						"vm": {
							"name": "vm-abc-def"
						}
					}`
					settingsJSON = strings.Replace(settingsJSON, `"`, `\"`, -1)
					settingsJSON = strings.Replace(settingsJSON, "\n", "", -1)
					settingsJSON = strings.Replace(settingsJSON, "\t", "", -1)
					settingsJSON = fmt.Sprintf(`{"settings": "%s"}`, settingsJSON)

					expectedSettings := boshsettings.Settings{
						AgentID: "my-agent-id",
						Blobstore: boshsettings.Blobstore{
							Type: "s3",
							Options: map[string]interface{}{
								"bucket_name":       "george",
								"encryption_key":    "optional encryption key",
								"access_key_id":     "optional access key id",
								"secret_access_key": "optional secret access key",
								"port":              443.0,
							},
						},
						Disks: boshsettings.Disks{
							Ephemeral:  "/dev/sdb",
							Persistent: map[string]interface{}{"vol-xxxxxx": "/dev/sdf"},
							System:     "/dev/sda1",
						},
						Env: boshsettings.Env{
							Bosh: boshsettings.BoshEnv{
								Password: "******",
							},
						},
						Networks: boshsettings.Networks{
							"netA": boshsettings.Network{
								Default: []string{"dns", "gateway"},
								IP:      "ww.ww.ww.ww",
								DNS:     []string{"xx.xx.xx.xx", "yy.yy.yy.yy"},
							},
							"netB": boshsettings.Network{
								DNS: []string{"zz.zz.zz.zz"},
							},
						},
						Mbus: "https://*****:*****@0.0.0.0:6868",
						Ntp: []string{
							"0.north-america.pool.ntp.org",
							"1.north-america.pool.ntp.org",
						},
						VM: boshsettings.VM{
							Name: "vm-abc-def",
						},
					}

					metadataService.InstanceID = "fake-identifier"
					metadataService.RegistryEndpoint = ts.URL

					settings, err := registry.GetSettings()
					Expect(err).ToNot(HaveOccurred())
					Expect(settings).To(Equal(expectedSettings))
				})
			})
		})

		Context("when registry is configured to use server name as id", func() {
			BeforeEach(func() {
				registry = NewHTTPRegistry(metadataService, platform, true)
				metadataService.ServerName = "fake-identifier"
				metadataService.RegistryEndpoint = ts.URL
			})

			It("returns settings fetched from http server based on server name", func() {
				settingsJSON = `{"settings": "{\"agent_id\":\"my-agent-id\"}"}`

				settings, err := registry.GetSettings()
				Expect(err).ToNot(HaveOccurred())
				Expect(settings).To(Equal(boshsettings.Settings{AgentID: "my-agent-id"}))
			})

			It("returns error if registry settings wrapper cannot be parsed", func() {
				settingsJSON = "invalid-json"

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Unmarshalling settings wrapper"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})

			It("returns error if registry settings wrapper contains invalid json", func() {
				settingsJSON = `{"settings": "invalid-json"}`

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Unmarshalling wrapped settings"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})

			It("returns error if metadata service fails to return server name", func() {
				metadataService.GetServerNameErr = errors.New("fake-get-server-name-err")

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("fake-get-server-name-err"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})

			It("returns error if metadata service fails to return registry endpoint", func() {
				metadataService.GetRegistryEndpointErr = errors.New("fake-get-registry-endpoint-err")

				settings, err := registry.GetSettings()
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("fake-get-registry-endpoint-err"))

				Expect(settings).To(Equal(boshsettings.Settings{}))
			})
		})
	})
}