func main() {
	var (
		cfManifest    string
		outputDir     string
		boshServerUrl string
		machineIp     string
	)
	flag.StringVar(&cfManifest, "manifest", "", "Path to CF manifest file")
	flag.StringVar(&outputDir, "outputDir", "", "Directory where the generated install script and certs will be created")
	flag.StringVar(&boshServerUrl, "boshUrl", "", "Bosh director URL e.g. https://admin:[email protected]:25555")
	flag.StringVar(&machineIp, "machineIp", "", "(optional) IP address of this cell")

	flag.Parse()
	if outputDir == "" || (boshServerUrl == "" && cfManifest == "") {
		usage()
	}
	if boshServerUrl != "" && cfManifest != "" {
		fmt.Fprintln(os.Stderr, "Error: only boshServerUrl or cfManifest may be specified")
		usage()
	}

	var manifest models.Manifest
	if cfManifest != "" {
		manifestContents, err := ioutil.ReadFile(cfManifest)
		err = yaml.Unmarshal(manifestContents, &manifest)
		if err != nil {
			Fatal(err)
		}
	} else {

		u, _ := url.Parse(boshServerUrl)

		_, err := os.Stat(outputDir)
		if err != nil {
			if os.IsNotExist(err) {
				os.MkdirAll(outputDir, 0755)
			}
		}

		bosh := NewBosh(*u)
		bosh.Authorize()

		response := bosh.MakeRequest("/deployments")
		defer response.Body.Close()

		if response.StatusCode != http.StatusOK {
			buf := new(bytes.Buffer)
			_, err := buf.ReadFrom(response.Body)
			if err != nil {
				fmt.Printf("Could not read response from BOSH director.")
				os.Exit(1)
			}

			fmt.Fprintf(os.Stderr, "Unexpected BOSH director response: %v, %v", response.StatusCode, buf.String())
			os.Exit(1)
		}

		deployments := []models.IndexDeployment{}
		json.NewDecoder(response.Body).Decode(&deployments)
		idx := GetDiegoDeployment(deployments)
		if idx == -1 {
			fmt.Fprintf(os.Stderr, "BOSH Director does not have exactly one deployment containing a cf and diego release.")
			os.Exit(1)
		}

		response = bosh.MakeRequest("/deployments/" + deployments[idx].Name)
		defer response.Body.Close()

		deployment := models.ShowDeployment{}
		json.NewDecoder(response.Body).Decode(&deployment)

		err = yaml.Unmarshal([]byte(deployment.Manifest), &manifest)
		if err != nil {
			Fatal(err)
		}
	}

	args, err := models.NewInstallerArguments(&manifest)
	if err != nil {
		Fatal(err)
	}

	args.FillEtcdCluster()
	args.FillSharedSecret()
	args.FillMetronAgent()
	args.FillSyslog()
	args.FillConsul()
	args.FillBBS()
	args.FillRep()

	if machineIp == "" {
		consulIp := strings.Split(args.ConsulIPs, ",")[0]
		conn, err := net.Dial("udp", consulIp+":65530")
		Fatal(err)
		machineIp = strings.Split(conn.LocalAddr().String(), ":")[0]
	}
	args.FillMachineIp(machineIp)

	generateInstallScript(outputDir, args)
	writeCerts(outputDir, args)
}
package yaml_test

import (
	"yaml"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

type Manifest struct {
	Properties *struct {
		Syslog *struct{} `yaml:"syslog_daemon_config"`
	} `yaml:"properties"`
}

type Properties struct {
}

var _ = Describe("Yaml", func() {
	It("works with empty objects", func() {
		// y, err := ioutil.ReadFile("../integration/syslog_with_empty_config.yml")
		// Expect(err).ToNot(HaveOccurred())
		y := `
properties:
  syslog_daemon_config:
`
		err := yaml.Unmarshal([]byte(y), &Manifest{})
		Expect(err).To(BeNil())
	})
})