// Retrieves availability zone against specified id.
func showAvailabilityZone(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "availability-zone show <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	zone, err := client.Esxclient.AvailabilityZones.Get(id)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		fmt.Printf("%s\t%s\t%s\t%s\n", zone.ID, zone.Name, zone.Kind, zone.State)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(zone, w, c)
	} else {
		fmt.Printf("AvailabilityZone ID: %s\n", zone.ID)
		fmt.Printf("  Name:        %s\n", zone.Name)
		fmt.Printf("  Kind:        %s\n", zone.Kind)
		fmt.Printf("  State:       %s\n", zone.State)
	}

	return nil
}
Ejemplo n.º 2
0
func showNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "network show <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	network, err := client.Esxclient.Subnets.Get(id)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		portGroups := getCommaSeparatedStringFromStringArray(network.PortGroups)
		fmt.Printf("%s\t%s\t%s\t%s\t%s\t%t\n", network.ID, network.Name, network.State, portGroups,
			network.Description, network.IsDefault)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(network, w, c)
	} else {
		fmt.Printf("Network ID: %s\n", network.ID)
		fmt.Printf("  Name:        %s\n", network.Name)
		fmt.Printf("  State:       %s\n", network.State)
		fmt.Printf("  Description: %s\n", network.Description)
		fmt.Printf("  Port Groups: %s\n", network.PortGroups)
		fmt.Printf("  Is Default: %t\n", network.IsDefault)
	}

	return nil
}
Ejemplo n.º 3
0
// Set host's availability zone with the specified host ID, returns an error if one occurred
func setHostAvailabilityZone(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 2, "host set-availability-zone <id> <availability-zone-id>")
	if err != nil {
		return err
	}
	id := c.Args().First()
	availabilityZoneId := c.Args()[1]

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	setAvailabilityZoneSpec := photon.HostSetAvailabilityZoneOperation{}
	setAvailabilityZoneSpec.AvailabilityZoneId = availabilityZoneId
	setTask, err := client.Esxclient.Hosts.SetAvailabilityZone(id, &setAvailabilityZoneSpec)
	if err != nil {
		return err
	}
	id, err = waitOnTaskOperation(setTask.ID, c)
	if err != nil {
		return err
	}
	if utils.NeedsFormatting(c) {
		host, err := client.Esxclient.Hosts.Get(id)
		if err != nil {
			return err
		}
		utils.FormatObject(host, w, c)
	}

	return nil
}
Ejemplo n.º 4
0
func setDefaultNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "network set-default <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	task, err := client.Esxclient.Subnets.SetDefault(id)
	if err != nil {
		return err
	}

	if confirmed(utils.IsNonInteractive(c)) {
		id, err := waitOnTaskOperation(task.ID, c)
		if err != nil {
			return err
		}

		if utils.NeedsFormatting(c) {
			network, err := client.Esxclient.Subnets.Get(id)
			if err != nil {
				return err
			}
			utils.FormatObject(network, w, c)
		}
	} else {
		fmt.Println("OK. Canceled")
	}
	return nil
}
Ejemplo n.º 5
0
// Sends a "resize cluster" request to the API client based on the cli.Context
// Returns an error if one occurred
func resizeCluster(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 2, "cluster resize <id> <new worker count> [<options>]")
	if err != nil {
		return err
	}

	cluster_id := c.Args()[0]
	worker_count_string := c.Args()[1]
	worker_count, err := strconv.Atoi(worker_count_string)
	wait_for_ready := c.IsSet("wait-for-ready")

	if len(cluster_id) == 0 || err != nil || worker_count <= 0 {
		return fmt.Errorf("Provide a valid cluster ID and worker count")
	}

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	if !utils.IsNonInteractive(c) {
		fmt.Printf("\nResizing cluster %s to worker count %d\n", cluster_id, worker_count)
	}

	if confirmed(utils.IsNonInteractive(c)) {
		resizeSpec := photon.ClusterResizeOperation{}
		resizeSpec.NewWorkerCount = worker_count
		resizeTask, err := client.Esxclient.Clusters.Resize(cluster_id, &resizeSpec)
		if err != nil {
			return err
		}

		_, err = waitOnTaskOperation(resizeTask.ID, c)
		if err != nil {
			return err
		}

		if wait_for_ready {
			cluster, err := waitForCluster(cluster_id)
			if err != nil {
				return err
			}
			if utils.NeedsFormatting(c) {
				utils.FormatObject(cluster, w, c)
			} else {
				fmt.Printf("Cluster %s is ready\n", cluster.ID)
			}
		} else {
			fmt.Println("Note: A background task is running to gradually resize the cluster to its target capacity.")
			fmt.Printf("You may continue to use the cluster. You can run 'cluster show %s'\n", resizeTask.Entity.ID)
			fmt.Println("to see the state of the cluster. If the resize operation is still in progress, the cluster state")
			fmt.Println("will show as RESIZING. Once the cluster is resized, the cluster state will show as READY.")
		}
	} else {
		fmt.Println("Cancelled")
	}

	return nil
}
Ejemplo n.º 6
0
// Show project info with the specified project id, returns an error if one occurred
func showProject(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "project show <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	project, err := client.Esxclient.Projects.Get(id)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		securityGroups := []string{}
		for _, s := range project.SecurityGroups {
			securityGroups = append(securityGroups, fmt.Sprintf("%s:%t", s.Name, s.Inherited))
		}
		scriptSecurityGroups := strings.Join(securityGroups, ",")
		limits := quotaLineItemListToString(project.ResourceTicket.Limits)
		usages := quotaLineItemListToString(project.ResourceTicket.Usage)

		fmt.Printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n", project.ID, project.Name, project.ResourceTicket.TenantTicketID,
			project.ResourceTicket.TenantTicketName, limits, usages, scriptSecurityGroups)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(project, w, c)
	} else {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 4, 4, 2, ' ', 0)
		fmt.Fprintf(w, "Project ID: %s\n", project.ID)
		fmt.Fprintf(w, "  Name: %s\n", project.Name)
		fmt.Fprintf(w, "  TenantTicketID: %s\n", project.ResourceTicket.TenantTicketID)
		fmt.Fprintf(w, "    TenantTicketName: %s\n", project.ResourceTicket.TenantTicketName)
		fmt.Fprintf(w, "    Limits:\n")
		for _, l := range project.ResourceTicket.Limits {
			fmt.Fprintf(w, "      %s\t%g\t%s\n", l.Key, l.Value, l.Unit)
		}
		fmt.Fprintf(w, "    Usage:\n")
		for _, u := range project.ResourceTicket.Usage {
			fmt.Fprintf(w, "      %s\t%g\t%s\n", u.Key, u.Value, u.Unit)
		}
		if len(project.SecurityGroups) != 0 {
			fmt.Fprintf(w, "  SecurityGroups:\n")
			for _, s := range project.SecurityGroups {
				fmt.Fprintf(w, "    %s\t%t\n", s.Name, s.Inherited)
			}
		}
		err = w.Flush()
		if err != nil {
			return err
		}
	}
	return nil
}
Ejemplo n.º 7
0
// Sends a "show cluster" request to the API client based on the cli.Context
// Returns an error if one occurred
func showCluster(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "cluster show <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	cluster, err := client.Esxclient.Clusters.Get(id)
	if err != nil {
		return err
	}

	vms, err := client.Esxclient.Clusters.GetVMs(id)
	if err != nil {
		return err
	}

	var master_vms []photon.VM
	for _, vm := range vms.Items {
		for _, tag := range vm.Tags {
			if strings.Count(tag, ":") == 2 && !strings.Contains(strings.ToLower(tag), "worker") {
				master_vms = append(master_vms, vm)
				break
			}
		}
	}

	if c.GlobalIsSet("non-interactive") {
		extendedProperties := strings.Trim(strings.TrimLeft(fmt.Sprint(cluster.ExtendedProperties), "map"), "[]")
		fmt.Printf("%s\t%s\t%s\t%s\t%d\t%s\n", cluster.ID, cluster.Name, cluster.State, cluster.Type,
			cluster.WorkerCount, extendedProperties)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(cluster, w, c)
	} else {
		fmt.Println("Cluster ID:            ", cluster.ID)
		fmt.Println("  Name:                ", cluster.Name)
		fmt.Println("  State:               ", cluster.State)
		fmt.Println("  Type:                ", cluster.Type)
		fmt.Println("  Worker count:        ", cluster.WorkerCount)
		fmt.Println("  Extended Properties: ", cluster.ExtendedProperties)
		fmt.Println()
	}

	err = printClusterVMs(master_vms, c.GlobalIsSet("non-interactive"))
	if err != nil {
		return err
	}

	return nil
}
Ejemplo n.º 8
0
// Shows an image based on id
func showImage(c *cli.Context, w io.Writer) error {
	id := c.Args().First()

	if !utils.IsNonInteractive(c) {
		var err error
		id, err = askForInput("Image id: ", id)
		if err != nil {
			return err
		}
	}

	if len(id) == 0 {
		return fmt.Errorf("Please provide image id")
	}

	var err error
	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	image, err := client.Esxclient.Images.Get(id)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		settings := []string{}
		for _, setting := range image.Settings {
			settings = append(settings, fmt.Sprintf("%s:%s", setting.Name, setting.DefaultValue))
		}
		scriptSettings := strings.Join(settings, ",")
		fmt.Printf("%s\t%s\t%s\t%d\t%s\t%s\t%s\t%s\n", image.ID, image.Name, image.State, image.Size, image.ReplicationType,
			image.ReplicationProgress, image.SeedingProgress, scriptSettings)

	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(image, w, c)
	} else {
		fmt.Printf("Image ID: %s\n", image.ID)
		fmt.Printf("  Name:                       %s\n", image.Name)
		fmt.Printf("  State:                      %s\n", image.State)
		fmt.Printf("  Size:                       %d Byte(s)\n", image.Size)
		fmt.Printf("  Image Replication Type:     %s\n", image.ReplicationType)
		fmt.Printf("  Image Replication Progress: %s\n", image.ReplicationProgress)
		fmt.Printf("  Image Seeding Progress:     %s\n", image.SeedingProgress)
		fmt.Printf("  Settings: \n")
		for _, setting := range image.Settings {
			fmt.Printf("    %s : %s\n", setting.Name, setting.DefaultValue)
		}
	}

	return nil
}
// Sends a show resource-ticket task to client based on the cli.Context
// Returns an error if one occurred
func showResourceTicket(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "resource-ticket show <name> [<options>]")
	if err != nil {
		return err
	}
	name := c.Args().First()
	tenantName := c.String("tenant")

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	tenant, err := verifyTenant(tenantName)
	if err != nil {
		return err
	}

	rt, err := findResourceTicket(tenant.ID, name)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		usage := quotaLineItemListToString(rt.Usage)
		limits := quotaLineItemListToString(rt.Limits)
		fmt.Printf("%s\t%s\t%s\t%s\n", rt.Name, rt.ID, limits, usage)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(rt, w, c)
	} else {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 4, 4, 2, ' ', 0)
		fmt.Fprintf(w, "ID\tName\tLimit\tUsage\n")
		for i := 0; i < len(rt.Limits); i++ {
			if i == 0 {
				fmt.Fprintf(w, "%s\t%s\t%s %g %s\t%s %g %s\n", rt.ID, rt.Name,
					rt.Limits[i].Key, rt.Limits[i].Value, rt.Limits[i].Unit,
					rt.Usage[i].Key, rt.Usage[i].Value, rt.Usage[i].Unit)
			} else {
				fmt.Fprintf(w, "\t\t%s %g %s\t%s %g %s\n",
					rt.Limits[i].Key, rt.Limits[i].Value, rt.Limits[i].Unit,
					rt.Usage[i].Key, rt.Usage[i].Value, rt.Usage[i].Unit)
			}
		}
		err := w.Flush()
		if err != nil {
			return err
		}
	}

	return nil
}
// Sends a create availability-zone task to client based on the cli.Context
// Returns an error if one occurred
func createAvailabilityZone(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "availability-zone create [<options>]")
	if err != nil {
		return err
	}
	name := c.String("name")

	if !utils.IsNonInteractive(c) {
		var err error
		name, err = askForInput("AvailabilityZone name: ", name)
		if err != nil {
			return err
		}
	}

	if len(name) == 0 {
		return fmt.Errorf("Please provide availability zone name")
	}

	azSpec := &photon.AvailabilityZoneCreateSpec{
		Name: name,
	}

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	createTask, err := client.Esxclient.AvailabilityZones.Create(azSpec)
	if err != nil {
		return err
	}

	id, err := waitOnTaskOperation(createTask.ID, c)
	if err != nil {
		return err
	}

	if utils.NeedsFormatting(c) {
		zone, err := client.Esxclient.AvailabilityZones.Get(id)
		if err != nil {
			return err
		}
		utils.FormatObject(zone, w, c)
	}

	return nil
}
Ejemplo n.º 11
0
// Show host info with the specified host ID, returns an error if one occurred
func showHost(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "host show <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	host, err := client.Esxclient.Hosts.Get(id)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		tag := strings.Trim(fmt.Sprint(host.Tags), "[]")
		scriptTag := strings.Replace(tag, " ", ",", -1)
		metadata := strings.Trim(strings.TrimLeft(fmt.Sprint(host.Metadata), "map"), "[]")
		scriptMetadata := strings.Replace(metadata, " ", ",", -1)
		fmt.Printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", host.ID, host.Username, host.Password, host.Address,
			scriptTag, host.State, scriptMetadata, host.AvailabilityZone, host.EsxVersion)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(host, w, c)
	} else {
		fmt.Println("Host ID: ", host.ID)
		fmt.Println("  Username:          "******"  Password:          "******"  IP:                ", host.Address)
		fmt.Println("  Tags:              ", host.Tags)
		fmt.Println("  State:             ", host.State)
		fmt.Println("  Metadata:          ", host.Metadata)
		fmt.Println("  AvailabilityZone:  ", host.AvailabilityZone)
		fmt.Println("  Version:           ", host.EsxVersion)
	}

	return nil
}
Ejemplo n.º 12
0
func showTenant(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "tenant show <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	tenant, err := client.Esxclient.Tenants.Get(id)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		securityGroups := []string{}
		for _, s := range tenant.SecurityGroups {
			securityGroups = append(securityGroups, fmt.Sprintf("%s:%t", s.Name, s.Inherited))
		}
		scriptSecurityGroups := strings.Join(securityGroups, ",")
		fmt.Printf("%s\t%s\t%s\n", tenant.ID, tenant.Name, scriptSecurityGroups)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(tenant, w, c)
	} else {
		fmt.Println("Tenant ID: ", tenant.ID)
		fmt.Println("  Name:              ", tenant.Name)
		for i, s := range tenant.SecurityGroups {
			fmt.Printf("    SecurityGroups %d:\n", i+1)
			fmt.Println("      Name:          ", s.Name)
			fmt.Println("      Inherited:     ", s.Inherited)
		}
	}

	return nil
}
Ejemplo n.º 13
0
// Sends a get project task to client based on the config file
// Returns an error if one occurred
func getProject(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "project get")
	if err != nil {
		return err
	}
	config, err := cf.LoadConfig()
	if err != nil {
		return err
	}

	project := config.Project
	if project == nil {
		return fmt.Errorf("Error: No Project selected\n")
	}

	if c.GlobalIsSet("non-interactive") {
		fmt.Printf("%s\t%s\n", project.ID, project.Name)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(project, w, c)
	} else {
		fmt.Printf("Current project is '%s' with ID %s\n", project.ID, project.Name)
	}
	return nil
}
Ejemplo n.º 14
0
// Outputs the set tenant otherwise informs user it is not set
func getTenant(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "tenant get")
	if err != nil {
		return err
	}
	config, err := cf.LoadConfig()
	if err != nil {
		return err
	}

	tenant := config.Tenant
	if tenant == nil {
		fmt.Printf("No tenant selected\n")
	} else {
		if c.GlobalIsSet("non-interactive") {
			fmt.Printf("%s\t%s\n", tenant.ID, tenant.Name)
		} else if utils.NeedsFormatting(c) {
			utils.FormatObject(tenant, w, c)
		} else {
			fmt.Printf("Current tenant is '%s' with ID %s\n", tenant.Name, tenant.ID)
		}
	}
	return nil
}
Ejemplo n.º 15
0
// Retrieves information about a flavor
func showFlavor(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 1, "flavor show <id>")
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	flavor, err := client.Esxclient.Flavors.Get(id)
	if err != nil {
		return err
	}

	if c.GlobalIsSet("non-interactive") {
		costs := quotaLineItemListToString(flavor.Cost)
		fmt.Printf("%s\t%s\t%s\t%s\t%s\n", flavor.ID, flavor.Name, flavor.Kind, costs, flavor.State)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(flavor, w, c)
	} else {
		costList := []string{}
		for _, cost := range flavor.Cost {
			costList = append(costList, fmt.Sprintf("%s %g %s", cost.Key, cost.Value, cost.Unit))
		}
		fmt.Printf("Flavor ID: %s\n", flavor.ID)
		fmt.Printf("  Name:  %s\n", flavor.Name)
		fmt.Printf("  Kind:  %s\n", flavor.Kind)
		fmt.Printf("  Cost:  %s\n", costList)
		fmt.Printf("  State: %s\n", flavor.State)
	}

	return nil
}
Ejemplo n.º 16
0
// Sends a create host task to client based on the cli.Context
// Returns an error if one occurred
func createHost(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "host create [<options>]")
	if err != nil {
		return err
	}
	username := c.String("username")
	password := c.String("password")
	address := c.String("address")
	availabilityZone := c.String("availability_zone")
	tags := c.String("tag")
	metadata := c.String("metadata")
	deploymentID := c.String("deployment_id")

	if !utils.IsNonInteractive(c) {
		var err error
		username, err = askForInput("Username: "******"Password: "******"Host Address: ", address)
		if err != nil {
			return err
		}
		tags, err = askForInput("Host Tags (Options [CLOUD,MGMT]. ',' separated): ", tags)
		if err != nil {
			return err
		}
		metadata, err = askForInput("Host Metadata ({'key':'value'}. required by host of 'MGMT' tag): ", metadata)
		if err != nil {
			return err
		}
		deploymentID, err = askForInput("Deployment ID: ", deploymentID)
		if err != nil {
			return err
		}
	}

	hostSpec := photon.HostCreateSpec{}
	hostSpec.Username = username
	hostSpec.Password = password
	hostSpec.Address = address
	hostSpec.AvailabilityZone = availabilityZone
	hostSpec.Tags = regexp.MustCompile(`\s*,\s*`).Split(tags, -1)

	if len(metadata) == 0 {
		hostSpec.Metadata = map[string]string{}
	} else {
		var data map[string]string
		err := json.Unmarshal([]byte(metadata), &data)
		if err != nil {
			return err
		}
		hostSpec.Metadata = data
	}

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}
	createTask, err := client.Esxclient.Hosts.Create(&hostSpec, deploymentID)
	if err != nil {
		return err
	}
	id, err := waitOnTaskOperation(createTask.ID, c)
	if err != nil {
		return err
	}

	if utils.NeedsFormatting(c) {
		host, err := client.Esxclient.Hosts.Get(id)
		if err != nil {
			return err
		}
		utils.FormatObject(host, w, c)
	}

	return nil
}
Ejemplo n.º 17
0
// Sends a create tenant task to client based on the cli.Context
// Returns an error if one occurred
func createTenant(c *cli.Context, w io.Writer) error {
	if len(c.Args()) > 1 {
		return fmt.Errorf("Unknown argument: %v", c.Args()[1:])
	}
	name := c.Args().First()
	securityGroups := c.String("security-groups")

	if !utils.IsNonInteractive(c) {
		var err error
		name, err = askForInput("Tenant name: ", name)
		if err != nil {
			return err
		}
		securityGroups, err =
			askForInput("Comma-separated security group names, or hit enter for no security groups): ",
				securityGroups)
		if err != nil {
			return err
		}
	}

	if len(name) == 0 {
		return fmt.Errorf("Please provide tenant name")
	}
	securityGroupList := []string{}
	if securityGroups != "" {
		securityGroupList = regexp.MustCompile(`\s*,\s*`).Split(securityGroups, -1)
	}

	tenantSpec := &photon.TenantCreateSpec{
		Name:           name,
		SecurityGroups: securityGroupList,
	}

	var err error
	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	createTask, err := client.Esxclient.Tenants.Create(tenantSpec)

	if err != nil {
		return err
	}

	id, err := waitOnTaskOperation(createTask.ID, c)
	if err != nil {
		return err
	}

	if utils.NeedsFormatting(c) {
		tenant, err := client.Esxclient.Tenants.Get(id)
		if err != nil {
			return err
		}
		utils.FormatObject(tenant, w, c)
	}

	return nil
}
Ejemplo n.º 18
0
// Sends a "create cluster" request to the API client based on the cli.Context
// Returns an error if one occurred
func createCluster(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "cluster create [<options>]")
	if err != nil {
		return err
	}

	tenantName := c.String("tenant")
	projectName := c.String("project")
	name := c.String("name")
	cluster_type := c.String("type")
	vm_flavor := c.String("vm_flavor")
	disk_flavor := c.String("disk_flavor")
	network_id := c.String("network_id")
	worker_count := c.Int("worker_count")
	dns := c.String("dns")
	gateway := c.String("gateway")
	netmask := c.String("netmask")
	master_ip := c.String("master-ip")
	container_network := c.String("container-network")
	zookeeper1 := c.String("zookeeper1")
	zookeeper2 := c.String("zookeeper2")
	zookeeper3 := c.String("zookeeper3")
	etcd1 := c.String("etcd1")
	etcd2 := c.String("etcd2")
	etcd3 := c.String("etcd3")
	batch_size := c.Int("batchSize")
	ssh_key := c.String("ssh-key")

	wait_for_ready := c.IsSet("wait-for-ready")

	const DEFAULT_WORKER_COUNT = 1

	client.Esxclient, err = client.GetClient(c.GlobalIsSet("non-interactive"))
	if err != nil {
		return err
	}

	tenant, err := verifyTenant(tenantName)
	if err != nil {
		return err
	}

	project, err := verifyProject(tenant.ID, projectName)
	if err != nil {
		return err
	}

	if !utils.IsNonInteractive(c) {
		name, err = askForInput("Cluster name: ", name)
		if err != nil {
			return err
		}
		cluster_type, err = askForInput("Cluster type: ", cluster_type)
		if err != nil {
			return err
		}
		if worker_count == 0 {
			worker_count_string, err := askForInput("Worker count: ", "")
			if err != nil {
				return err
			}
			worker_count, err = strconv.Atoi(worker_count_string)
			if err != nil {
				return fmt.Errorf("Please supply a valid worker count")
			}
		}
	}

	if len(name) == 0 || len(cluster_type) == 0 {
		return fmt.Errorf("Provide a valid cluster name and type")
	}

	if worker_count == 0 {
		worker_count = DEFAULT_WORKER_COUNT
	}

	if !utils.IsNonInteractive(c) {
		dns, err = askForInput("Cluster DNS server: ", dns)
		if err != nil {
			return err
		}
		gateway, err = askForInput("Cluster network gateway: ", gateway)
		if err != nil {
			return err
		}
		netmask, err = askForInput("Cluster network netmask: ", netmask)
		if err != nil {
			return err
		}
		ssh_key, err = askForInput("Cluster ssh key file path (leave blank for none): ", ssh_key)
		if err != nil {
			return err
		}
	}

	if len(dns) == 0 || len(gateway) == 0 || len(netmask) == 0 {
		return fmt.Errorf("Provide a valid DNS, gateway, and netmask")
	}

	extended_properties := make(map[string]string)
	extended_properties[photon.ExtendedPropertyDNS] = dns
	extended_properties[photon.ExtendedPropertyGateway] = gateway
	extended_properties[photon.ExtendedPropertyNetMask] = netmask
	if len(ssh_key) != 0 {
		ssh_key_content, err := readSSHKey(ssh_key)
		if err == nil {
			extended_properties[photon.ExtendedPropertySSHKey] = ssh_key_content
		} else {
			return err
		}
	}

	cluster_type = strings.ToUpper(cluster_type)
	switch cluster_type {
	case "KUBERNETES":
		if !utils.IsNonInteractive(c) {
			master_ip, err = askForInput("Kubernetes master static IP address: ", master_ip)
			if err != nil {
				return err
			}
			container_network, err = askForInput("Kubernetes worker network ID: ", container_network)
			if err != nil {
				return err
			}
			etcd1, err = askForInput("etcd server 1 static IP address: ", etcd1)
			if err != nil {
				return err
			}
			etcd2, err = askForInput("etcd server 2 static IP address (leave blank for none): ", etcd2)
			if err != nil {
				return err
			}
			if len(etcd2) != 0 {
				etcd3, err = askForInput("etcd server 3 static IP address (leave blank for none): ", etcd3)
				if err != nil {
					return err
				}
			}
		}

		extended_properties[photon.ExtendedPropertyMasterIP] = master_ip
		extended_properties[photon.ExtendedPropertyContainerNetwork] = container_network
		extended_properties[photon.ExtendedPropertyETCDIP1] = etcd1
		if len(etcd2) != 0 {
			extended_properties[photon.ExtendedPropertyETCDIP2] = etcd2
			if len(etcd3) != 0 {
				extended_properties[photon.ExtendedPropertyETCDIP3] = etcd3
			}
		}
	case "MESOS":
		if !utils.IsNonInteractive(c) {
			zookeeper1, err = askForInput("Zookeeper server 1 static IP address: ", zookeeper1)
			if err != nil {
				return err
			}
			zookeeper2, err = askForInput("Zookeeper server 2 static IP address (leave blank for none): ", zookeeper2)
			if err != nil {
				return err
			}
			if len(zookeeper2) != 0 {
				zookeeper3, err = askForInput("Zookeeper server 3 static IP address (leave blank for none): ", zookeeper3)
				if err != nil {
					return err
				}
			}
		}

		extended_properties[photon.ExtendedPropertyZookeeperIP1] = zookeeper1
		if len(zookeeper2) != 0 {
			extended_properties[photon.ExtendedPropertyZookeeperIP2] = zookeeper2
			if len(zookeeper3) != 0 {
				extended_properties[photon.ExtendedPropertyZookeeperIP3] = zookeeper3
			}
		}
	case "SWARM":
		if !utils.IsNonInteractive(c) {
			etcd1, err = askForInput("etcd server 1 static IP address: ", etcd1)
			if err != nil {
				return err
			}
			etcd2, err = askForInput("etcd server 2 static IP address (leave blank for none): ", etcd2)
			if err != nil {
				return err
			}
			if len(etcd2) != 0 {
				etcd3, err = askForInput("etcd server 3 static IP address (leave blank for none): ", etcd3)
				if err != nil {
					return err
				}
			}
		}

		extended_properties[photon.ExtendedPropertyETCDIP1] = etcd1
		if len(etcd2) != 0 {
			extended_properties[photon.ExtendedPropertyETCDIP2] = etcd2
			if len(etcd3) != 0 {
				extended_properties[photon.ExtendedPropertyETCDIP3] = etcd3
			}
		}
	default:
		return fmt.Errorf("Unsupported cluster type: %s", cluster_type)
	}

	clusterSpec := photon.ClusterCreateSpec{}
	clusterSpec.Name = name
	clusterSpec.Type = cluster_type
	clusterSpec.VMFlavor = vm_flavor
	clusterSpec.DiskFlavor = disk_flavor
	clusterSpec.NetworkID = network_id
	clusterSpec.WorkerCount = worker_count
	clusterSpec.BatchSizeWorker = batch_size
	clusterSpec.ExtendedProperties = extended_properties

	if !utils.IsNonInteractive(c) {
		fmt.Printf("\n")
		fmt.Printf("Creating cluster: %s (%s)\n", clusterSpec.Name, clusterSpec.Type)
		if len(clusterSpec.VMFlavor) != 0 {
			fmt.Printf("  VM flavor: %s\n", clusterSpec.VMFlavor)
		}
		if len(clusterSpec.DiskFlavor) != 0 {
			fmt.Printf("  Disk flavor: %s\n", clusterSpec.DiskFlavor)
		}
		fmt.Printf("  Worker count: %d\n", clusterSpec.WorkerCount)
		if clusterSpec.BatchSizeWorker != 0 {
			fmt.Printf("  Batch size: %d\n", clusterSpec.BatchSizeWorker)
		}
		fmt.Printf("\n")
	}

	if confirmed(utils.IsNonInteractive(c)) {
		createTask, err := client.Esxclient.Projects.CreateCluster(project.ID, &clusterSpec)
		if err != nil {
			return err
		}

		_, err = waitOnTaskOperation(createTask.ID, c)
		if err != nil {
			return err
		}

		if wait_for_ready {
			if !utils.NeedsFormatting(c) {
				fmt.Printf("Waiting for cluster %s to become ready\n", createTask.Entity.ID)
			}
			cluster, err := waitForCluster(createTask.Entity.ID)
			if err != nil {
				return err
			}

			if utils.NeedsFormatting(c) {
				utils.FormatObject(cluster, w, c)
			} else {
				fmt.Printf("Cluster %s is ready\n", cluster.ID)
			}

		} else {
			fmt.Println("Note: the cluster has been created with minimal resources. You can use the cluster now.")
			fmt.Println("A background task is running to gradually expand the cluster to its target capacity.")
			fmt.Printf("You can run 'cluster show %s' to see the state of the cluster.\n", createTask.Entity.ID)
		}
	} else {
		fmt.Println("Cancelled")
	}

	return nil
}
Ejemplo n.º 19
0
// Sends a create resource-ticket task to client based on the cli.Context
// Returns an error if one occurred
func createResourceTicket(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "resource-ticket create [<options>]")
	if err != nil {
		return err
	}
	tenantName := c.String("tenant")
	name := c.String("name")
	limits := c.String("limits")

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	tenant, err := verifyTenant(tenantName)
	if err != nil {
		return err
	}

	limitsList, err := parseLimitsListFromFlag(limits)
	if err != nil {
		return err
	}

	if !utils.IsNonInteractive(c) {
		name, err = askForInput("Resource ticket name: ", name)
		if err != nil {
			return err
		}
		limitsList, err = askForLimitList(limitsList)
		if err != nil {
			return err
		}
	}

	rtSpec := photon.ResourceTicketCreateSpec{}
	rtSpec.Name = name
	rtSpec.Limits = limitsList

	if !utils.IsNonInteractive(c) {
		fmt.Printf("\nTenant name: %s\n", tenant.Name)
		fmt.Printf("Creating resource ticket name: %s\n\n", name)
		fmt.Println("Please make sure limits below are correct:")
		for i, l := range limitsList {
			fmt.Printf("%d: %s, %g, %s\n", i+1, l.Key, l.Value, l.Unit)
		}
	}

	if confirmed(utils.IsNonInteractive(c)) {
		createTask, err := client.Esxclient.Tenants.CreateResourceTicket(tenant.ID, &rtSpec)
		if err != nil {
			return err
		}

		_, err = waitOnTaskOperation(createTask.ID, c)
		if err != nil {
			return err
		}

		if utils.NeedsFormatting(c) {
			options := &photon.ResourceTicketGetOptions{
				Name: name,
			}
			tickets, err := client.Esxclient.Tenants.GetResourceTickets(tenant.ID, options)
			if err != nil {
				return err
			}
			utils.FormatObject(tickets.Items[0], w, c)
		}
	} else {
		fmt.Println("OK. Canceled")
	}

	return nil
}
Ejemplo n.º 20
0
// Create an image
func createImage(c *cli.Context, w io.Writer) error {
	if len(c.Args()) > 1 {
		return fmt.Errorf("Unknown argument: %v", c.Args()[1:])
	}
	path := c.Args().First()
	name := c.String("name")
	replicationType := c.String("image_replication")

	if !utils.IsNonInteractive(c) {
		var err error
		path, err = askForInput("Image path: ", path)
		if err != nil {
			return err
		}
	}

	if len(path) == 0 {
		return fmt.Errorf("Please provide image path")
	}

	path, err := filepath.Abs(path)
	if err != nil {
		return err
	}

	_, err = os.Stat(path)
	if err != nil {
		return fmt.Errorf("No such image file at that path")
	}

	if !c.GlobalIsSet("non-interactive") {
		defaultName := path
		name, err = askForInput("Image name (default: "+defaultName+"): ", name)
		if err != nil {
			return err
		}

		if len(name) == 0 {
			name = defaultName
		}

		defaultReplication := "EAGER"
		replicationType, err = askForInput("Image replication type (default: "+defaultReplication+"): ", replicationType)
		if err != nil {
			return err
		}
		if len(replicationType) == 0 {
			replicationType = defaultReplication
		}
	}

	file, err := os.Open(path)
	if err != nil {
		return err
	}

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	options := &photon.ImageCreateOptions{
		ReplicationType: replicationType,
	}
	if len(replicationType) == 0 {
		options = nil
	}

	uploadTask, err := client.Esxclient.Images.Create(file, name, options)
	if err != nil {
		return err
	}

	imageID, err := waitOnTaskOperation(uploadTask.ID, c)
	if err != nil {
		return err
	}

	err = file.Close()
	if err != nil {
		return err
	}

	if utils.NeedsFormatting(c) {
		image, err := client.Esxclient.Images.Get(imageID)
		if err != nil {
			return err
		}
		utils.FormatObject(image, w, c)
	}

	return nil
}
Ejemplo n.º 21
0
// Sends a create flavor task to client
func createFlavor(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "flavor create [<options>]")
	if err != nil {
		return err
	}
	name := c.String("name")
	kind := c.String("kind")
	cost := c.String("cost")

	costList, err := parseLimitsListFromFlag(cost)
	if err != nil {
		return err
	}

	if !utils.IsNonInteractive(c) {
		name, err = askForInput("Flavor name: ", name)
		if err != nil {
			return err
		}
		kind, err = askForInput("Flavor kind (persistent-disk, ephemeral-disk, or vm): ", kind)
		if err != nil {
			return err
		}
		costList, err = askForLimitList(costList)
		if err != nil {
			return err
		}
	}

	if len(name) == 0 {
		return fmt.Errorf("Please provide flavor name")
	}

	if len(kind) == 0 || (kind != "persistent-disk" && kind != "ephemeral-disk" && kind != "vm") {
		return fmt.Errorf("Please provide flavor kind: persistent-disk, ephemeral-disk, or vm")
	}

	createSpec := &photon.FlavorCreateSpec{
		Name: name,
		Kind: kind,
		Cost: costList,
	}

	if !utils.IsNonInteractive(c) {
		fmt.Printf("Creating flavor: '%s', Kind: '%s'\n\n", name, kind)
		fmt.Printf("Please make sure limits below are correct: \n")
		for i, l := range costList {
			fmt.Printf("%d: %s, %g, %s\n", i+1, l.Key, l.Value, l.Unit)
		}
	}

	if confirmed(utils.IsNonInteractive(c)) {
		var err error
		client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
		if err != nil {
			return err
		}

		createTask, err := client.Esxclient.Flavors.Create(createSpec)
		if err != nil {
			return err
		}
		flavorId, err := waitOnTaskOperation(createTask.ID, c)
		if err != nil {
			return err
		}
		if utils.NeedsFormatting(c) {
			flavor, err := client.Esxclient.Flavors.Get(flavorId)
			if err != nil {
				return err
			}
			utils.FormatObject(flavor, w, c)
		}
	} else {
		fmt.Println("OK. Canceled")
	}

	return nil
}
Ejemplo n.º 22
0
func createNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "network create [<options>]")
	if err != nil {
		return err
	}

	name := c.String("name")
	description := c.String("description")
	portGroups := c.String("portgroups")

	if !utils.IsNonInteractive(c) {
		name, err = askForInput("Network name: ", name)
		if err != nil {
			return err
		}
		description, err = askForInput("Description of network: ", description)
		if err != nil {
			return err
		}
		portGroups, err = askForInput("PortGroups of network: ", portGroups)
		if err != nil {
			return err
		}
	}

	if len(name) == 0 {
		return fmt.Errorf("Please provide network name")
	}
	if len(portGroups) == 0 {
		return fmt.Errorf("Please provide portgroups")
	}

	portGroupList := regexp.MustCompile(`\s*,\s*`).Split(portGroups, -1)
	createSpec := &photon.SubnetCreateSpec{
		Name:        name,
		Description: description,
		PortGroups:  portGroupList,
	}

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	task, err := client.Esxclient.Subnets.Create(createSpec)
	if err != nil {
		return err
	}

	id, err := waitOnTaskOperation(task.ID, c)
	if err != nil {
		return err
	}

	if utils.NeedsFormatting(c) {
		network, err := client.Esxclient.Subnets.Get(id)
		if err != nil {
			return err
		}
		utils.FormatObject(network, w, c)
	}

	return nil
}
Ejemplo n.º 23
0
// Sends a create project task to client based on the cli.Context
// Returns an error if one occurred
func createProject(c *cli.Context, w io.Writer) error {
	err := checkArgNum(c.Args(), 0, "project create [<options>]")
	if err != nil {
		return err
	}
	tenantName := c.String("tenant")
	rtName := c.String("resource-ticket")
	name := c.String("name")
	limits := c.String("limits")
	percent := c.Float64("percent")
	securityGroups := c.String("security-groups")

	client.Esxclient, err = client.GetClient(utils.IsNonInteractive(c))
	if err != nil {
		return err
	}

	tenant, err := verifyTenant(tenantName)
	if err != nil {
		return err
	}

	var limitsList []photon.QuotaLineItem
	if c.IsSet("limits") && c.IsSet("percent") {
		return fmt.Errorf("Error: Can only specify one of '--limits' or '--percent'")
	}
	if c.IsSet("limits") {
		limitsList, err = parseLimitsListFromFlag(limits)
		if err != nil {
			return err
		}
	}
	if c.IsSet("percent") {
		limitsList = []photon.QuotaLineItem{
			{Key: "subdivide.percent", Value: percent, Unit: "COUNT"}}
	}

	if !utils.IsNonInteractive(c) {
		name, err = askForInput("Project name: ", name)
		if err != nil {
			return err
		}
		rtName, err = askForInput("Resource-ticket name: ", rtName)
		if err != nil {
			return err
		}
		limitsList, err = askForLimitList(limitsList)
		if err != nil {
			return err
		}
	}

	projectSpec := photon.ProjectCreateSpec{}
	projectSpec.Name = name
	projectSpec.ResourceTicket = photon.ResourceTicketReservation{Name: rtName, Limits: limitsList}

	if !utils.IsNonInteractive(c) {
		fmt.Printf("\nTenant name: %s\n", tenant.Name)
		fmt.Printf("Resource ticket name: %s\n", rtName)
		fmt.Printf("Creating project name: %s\n\n", name)
		fmt.Println("Please make sure limits below are correct:")
		for i, l := range limitsList {
			fmt.Printf("%d: %s, %g, %s\n", i+1, l.Key, l.Value, l.Unit)
		}
	}
	if confirmed(utils.IsNonInteractive(c)) {
		if len(securityGroups) > 0 {
			projectSpec.SecurityGroups = regexp.MustCompile(`\s*,\s*`).Split(securityGroups, -1)
		}
		createTask, err := client.Esxclient.Tenants.CreateProject(tenant.ID, &projectSpec)
		if err != nil {
			return err
		}

		id, err := waitOnTaskOperation(createTask.ID, c)
		if err != nil {
			return err
		}

		if utils.NeedsFormatting(c) {
			project, err := client.Esxclient.Projects.Get(id)
			if err != nil {
				return err
			}
			utils.FormatObject(project, w, c)
		}
	} else {
		fmt.Println("OK. Canceled")
	}

	return nil
}