예제 #1
0
// Get endpoint in config file and its status
func getStatus(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 0)
	if err != nil {
		return err
	}
	client.Esxclient, err = client.GetClient(c)
	if err != nil {
		return err
	}

	status, err := client.Esxclient.Status.Get()
	if err != nil {
		return err
	}

	if !utils.NeedsFormatting(c) {
		err = printStatus(status)
	} else {
		utils.FormatObject(status, w, c)
	}
	if err != nil {
		return err
	}

	return nil
}
예제 #2
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 := checkArgCount(c, 2)
	if err != nil {
		return err
	}
	id := c.Args().First()
	availabilityZoneId := c.Args()[1]

	client.Esxclient, err = client.GetClient(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
}
// Retrieves availability zone against specified id.
func showAvailabilityZone(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(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
}
func showPhysicalNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(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
}
예제 #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 := checkArgCount(c, 2)
	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(c)
	if err != nil {
		return err
	}

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

	if confirmed(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
}
예제 #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 := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(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
}
예제 #7
0
func formatHelper(c *cli.Context, w io.Writer, client *photon.Client, id string) error {
	if utils.NeedsFormatting(c) {
		vm, err := client.VMs.Get(id)
		if err != nil {
			return err
		}
		utils.FormatObject(vm, w, c)
	}
	return nil
}
예제 #8
0
func deploymentJsonHelper(c *cli.Context, id string, client *photon.Client) error {
	if utils.NeedsFormatting(c) {
		deployment, err := client.Deployments.Get(id)
		if err != nil {
			return err
		}

		utils.FormatObject(deployment, os.Stdout, c)
	}
	return nil
}
예제 #9
0
// Shows an image based on id
func showImage(c *cli.Context, w io.Writer) error {
	id := c.Args().First()

	if !c.GlobalIsSet("non-interactive") {
		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(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
}
예제 #10
0
// 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 := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	name := c.Args().First()
	tenantName := c.String("tenant")

	client.Esxclient, err = client.GetClient(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 := checkArgCount(c, 0)
	if err != nil {
		return err
	}
	name := c.String("name")

	if !c.GlobalIsSet("non-interactive") {
		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(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
}
예제 #12
0
func setDefaultNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

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

	sdnEnabled, err := isSoftwareDefinedNetwork(c)
	if err != nil {
		log.Fatal("Error: ", err)
	}

	var task *photon.Task
	if sdnEnabled {
		task, err = client.Esxclient.VirtualSubnets.SetDefault(id)
	} else {
		task, err = client.Esxclient.Subnets.SetDefault(id)
	}

	if err != nil {
		return err
	}

	if confirmed(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
}
예제 #13
0
func getVMMksTicket(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}

	id := c.Args().First()

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

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

	if c.GlobalIsSet("non-interactive") {
		task, err := client.Esxclient.Tasks.Wait(task.ID)
		if err != nil {
			return err
		}
		mksTicket := task.ResourceProperties.(map[string]interface{})
		fmt.Printf("%s\t%v\n", task.Entity.ID, mksTicket["ticket"])
	} else if utils.NeedsFormatting(c) {
		task, err := client.Esxclient.Tasks.Wait(task.ID)
		if err != nil {
			return err
		}
		mksTicket := task.ResourceProperties.(map[string]interface{})
		utils.FormatObject(mksTicket, w, c)
	} else {
		task, err = pollTask(task.ID)
		if err != nil {
			return err
		}
		mksTicket := task.ResourceProperties.(map[string]interface{})
		fmt.Printf("VM ID: %s \nMks ticket ID is %v\n", task.Entity.ID, mksTicket["ticket"])
	}
	return nil
}
예제 #14
0
// Sends a show disk task to client based on the cli.Context
// Returns an error if one occurred
func showDisk(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

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

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

	if c.GlobalIsSet("non-interactive") {
		tag := strings.Trim(fmt.Sprint(disk.Tags), "[]")
		scriptTag := strings.Replace(tag, " ", ",", -1)
		vms := strings.Trim(fmt.Sprint(disk.VMs), "[]")
		scriptVMs := strings.Replace(vms, " ", ",", -1)
		fmt.Printf("%s\t%s\t%s\t%s\t%s\t%d\t%s\t%s\t%s\n", disk.ID, disk.Name,
			disk.State, disk.Kind, disk.Flavor, disk.CapacityGB, disk.Datastore, scriptTag, scriptVMs)
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(disk, w, c)
	} else {
		fmt.Println("Disk ID: ", disk.ID)
		fmt.Println("  Name:       ", disk.Name)
		fmt.Println("  Kind:       ", disk.Kind)
		fmt.Println("  Flavor:     ", disk.Flavor)
		fmt.Println("  CapacityGB: ", disk.CapacityGB)
		fmt.Println("  State:      ", disk.State)
		fmt.Println("  Datastore:  ", disk.Datastore)
		fmt.Println("  Tags:       ", disk.Tags)
		fmt.Println("  VMs:        ", disk.VMs)
	}

	return nil
}
예제 #15
0
func showVirtualNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

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

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

	if c.GlobalIsSet("non-interactive") {
		fmt.Printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", network.ID, network.Name, network.State,
			network.Description, network.RoutingType, network.IsDefault, network.Cidr, network.LowIpDynamic,
			network.HighIpDynamic, network.LowIpStatic, network.HighIpStatic, network.ReservedIpList)
	} 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("  Routing Type:     %s\n", network.RoutingType)
		fmt.Printf("  Is Default:       %s\n", network.IsDefault)
		fmt.Printf("  CIDR:             %s\n", network.Cidr)
		fmt.Printf("  Start Dynamic IP: %s\n", network.LowIpDynamic)
		fmt.Printf("  End Dynamic IP:   %s\n", network.HighIpDynamic)
		fmt.Printf("  Start Static IP:  %s\n", network.LowIpStatic)
		fmt.Printf("  End Static IP:    %s\n", network.HighIpStatic)
		fmt.Printf("  Reserved IP List: %s\n", network.ReservedIpList)
	}

	return nil
}
예제 #16
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 := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(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\n", host.ID, host.Username, host.Address,
			scriptTag, host.State, scriptMetadata, host.AvailabilityZone, host.EsxVersion)
	} else if utils.NeedsFormatting(c) {
		host.Password = ""
		utils.FormatObject(host, w, c)
	} else {
		fmt.Println("Host ID: ", host.ID)
		fmt.Println("  Username:          "******"  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
}
예제 #17
0
// Shows information about Photon Controller: version, etc.
func showInfo(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 0)
	if err != nil {
		return err
	}

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

	info, err := client.Esxclient.Info.Get()

	if utils.NeedsFormatting(c) {
		utils.FormatObject(info, w, c)
	} else {
		fmt.Printf("Version: '%s'\n", info.FullVersion)
		fmt.Printf("Network Type: '%s'\n", info.NetworkType)
	}

	return nil
}
예제 #18
0
func showTenant(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(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
}
예제 #19
0
// Outputs the set tenant otherwise informs user it is not set
func getTenant(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 0)
	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
}
예제 #20
0
// Retrieves information about a flavor
func showFlavor(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(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
}
예제 #21
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 := checkArgCount(c, 0)
	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
}
예제 #22
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:])
	}
	filePath := c.Args().First()
	name := c.String("name")
	replicationType := c.String("image_replication")

	if !c.GlobalIsSet("non-interactive") {
		var err error
		filePath, err = askForInput("Image path: ", filePath)
		if err != nil {
			return err
		}
	}

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

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

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

	if !c.GlobalIsSet("non-interactive") {
		defaultName := path.Base(filePath)
		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(filePath)
	if err != nil {
		return err
	}

	client.Esxclient, err = client.GetClient(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
}
예제 #23
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 := checkArgCount(c, 0)
	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")

	deploymentID, err = getDeploymentId(c)
	if err != nil {
		return err
	}

	if !c.GlobalIsSet("non-interactive") {
		var err error
		username, err = askForInput("Username: "******"Password: "******"\n")
		}
		address, err = askForInput("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
		}
	}

	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(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
}
예제 #24
0
// Retrieves information about a deployment
func showDeployment(c *cli.Context, w io.Writer) error {
	id, err := getDeploymentId(c)
	if err != nil {
		return err
	}

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

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

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

	var data []VM_NetworkIPs

	for _, vm := range vms.Items {
		networks, err := getVMNetworks(vm.ID, c)
		if err != nil {
			return err
		}
		ipAddr := "N/A"
		for _, nt := range networks {
			network := nt.(map[string]interface{})
			if len(network) != 0 && network["network"] != nil {
				if val, ok := network["ipAddress"]; ok && val != nil {
					ipAddr = val.(string)
					break
				}
			}

		}
		data = append(data, VM_NetworkIPs{vm, ipAddr})
	}
	if utils.NeedsFormatting(c) {
		utils.FormatObject(deployment, w, c)
	} else if c.GlobalIsSet("non-interactive") {
		imageDataStores := getCommaSeparatedStringFromStringArray(deployment.ImageDatastores)
		securityGroups := getCommaSeparatedStringFromStringArray(deployment.Auth.SecurityGroups)

		fmt.Printf("%s\t%s\t%s\t%t\t%s\t%s\t%t\t%s\n", deployment.ID, deployment.State,
			imageDataStores, deployment.UseImageDatastoreForVms, deployment.SyslogEndpoint,
			deployment.NTPEndpoint, deployment.LoadBalancerEnabled,
			deployment.LoadBalancerAddress)

		fmt.Printf("%t\t%s\t%s\t%d\t%s\n", deployment.Auth.Enabled, deployment.Auth.Endpoint,
			deployment.Auth.Tenant, deployment.Auth.Port, securityGroups)

	} else {
		syslogEndpoint := deployment.SyslogEndpoint
		if len(deployment.SyslogEndpoint) == 0 {
			syslogEndpoint = "-"
		}
		ntpEndpoint := deployment.NTPEndpoint
		if len(deployment.NTPEndpoint) == 0 {
			ntpEndpoint = "-"
		}

		fmt.Printf("\n")
		fmt.Printf("Deployment ID: %s\n", deployment.ID)
		fmt.Printf("  State:                       %s\n", deployment.State)
		fmt.Printf("\n  Image Datastores:            %s\n", deployment.ImageDatastores)
		fmt.Printf("  Use image datastore for vms: %t\n", deployment.UseImageDatastoreForVms)
		fmt.Printf("\n  Syslog Endpoint:             %s\n", syslogEndpoint)
		fmt.Printf("  Ntp Endpoint:                %s\n", ntpEndpoint)
		fmt.Printf("\n  LoadBalancer:\n")
		fmt.Printf("    Enabled:                   %t\n", deployment.LoadBalancerEnabled)
		if deployment.LoadBalancerEnabled {
			fmt.Printf("    Address:                   %s\n", deployment.LoadBalancerAddress)
		}

		fmt.Printf("\n  Auth:\n")
		fmt.Printf("    Enabled:                   %t\n", deployment.Auth.Enabled)
		if deployment.Auth.Enabled {
			fmt.Printf("    Endpoint:                  %s\n", deployment.Auth.Endpoint)
			fmt.Printf("    Tenant:                    %s\n", deployment.Auth.Tenant)
			fmt.Printf("    Port:                      %d\n", deployment.Auth.Port)
			fmt.Printf("    Securitygroups:            %v\n", deployment.Auth.SecurityGroups)
		}
	}

	if deployment.Stats != nil {
		stats := deployment.Stats
		if c.GlobalIsSet("non-interactive") {
			fmt.Printf("%t\t%s\t%d\n", stats.Enabled, stats.StoreEndpoint, stats.StorePort)
		} else if !utils.NeedsFormatting(c) {

			fmt.Printf("\n  Stats:\n")
			fmt.Printf("    Enabled:               %t\n", stats.Enabled)
			if stats.Enabled {
				fmt.Printf("    Store Endpoint:        %s\n", stats.StoreEndpoint)
				fmt.Printf("    Store Port:            %d\n", stats.StorePort)
			}
		}
	} else {
		if c.GlobalIsSet("non-interactive") {
			fmt.Printf("\n")
		}
	}

	if deployment.Migration != nil {
		migration := deployment.Migration
		if c.GlobalIsSet("non-interactive") {
			fmt.Printf("%d\t%d\t%d\t%d\t%d\n", migration.CompletedDataMigrationCycles, migration.DataMigrationCycleProgress,
				migration.DataMigrationCycleSize, migration.VibsUploaded, migration.VibsUploading+migration.VibsUploaded)
		} else if !utils.NeedsFormatting(c) {
			fmt.Printf("\n  Migration status:\n")
			fmt.Printf("    Completed data migration cycles:          %d\n", migration.CompletedDataMigrationCycles)
			fmt.Printf("    Current data migration cycles progress:   %d / %d\n", migration.DataMigrationCycleProgress,
				migration.DataMigrationCycleSize)
			fmt.Printf("    VIB upload progress:                      %d / %d\n", migration.VibsUploaded, migration.VibsUploading+migration.VibsUploaded)
		}
	} else {
		if c.GlobalIsSet("non-interactive") {
			fmt.Printf("\n")
		}
	}

	if deployment.ClusterConfigurations != nil && len(deployment.ClusterConfigurations) != 0 {
		if c.GlobalIsSet("non-interactive") {
			clusterConfigurations := []string{}
			for _, c := range deployment.ClusterConfigurations {
				clusterConfigurations = append(clusterConfigurations, fmt.Sprintf("%s\t%s", c.Type, c.ImageID))
			}
			scriptClusterConfigurations := strings.Join(clusterConfigurations, ",")
			fmt.Printf("%s\n", scriptClusterConfigurations)
		} else if !utils.NeedsFormatting(c) {
			fmt.Println("\n  Cluster Configurations:")
			for i, c := range deployment.ClusterConfigurations {
				fmt.Printf("    ClusterConfiguration %d:\n", i+1)
				fmt.Println("      Kind:     ", c.Kind)
				fmt.Println("      Type:     ", c.Type)
				fmt.Println("      ImageID:  ", c.ImageID)
			}
		}
	} else {
		if c.GlobalIsSet("non-interactive") {
			fmt.Printf("\n")
		} else if !utils.NeedsFormatting(c) {
			fmt.Println("\n  Cluster Configurations:")
			fmt.Printf("    No cluster is supported")
		}
	}

	if !utils.NeedsFormatting(c) {
		err = displayDeploymentSummary(data, c.GlobalIsSet("non-interactive"))
		if err != nil {
			return err
		}
	}

	return nil
}
예제 #25
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 := checkArgCount(c, 0)
	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(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 !c.GlobalIsSet("non-interactive") {
		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 !c.GlobalIsSet("non-interactive") {
		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(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
}
예제 #26
0
// Sends a show VM task to client based on the cli.Context
// Returns an error if one occurred
func showVM(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

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

	vm, err := client.Esxclient.VMs.Get(id)
	if err != nil {
		return err
	}
	var networks []interface{}
	if vm.State != "ERROR" {
		networks, err = getVMNetworks(id, c)
		if err != nil {
			return err
		}
	}

	if c.GlobalIsSet("non-interactive") {
		tag := strings.Trim(fmt.Sprint(vm.Tags), "[]")
		scriptTag := strings.Replace(tag, " ", ",", -1)
		metadata := strings.Trim(strings.TrimLeft(fmt.Sprint(vm.Metadata), "map"), "[]")
		scriptMetadata := strings.Replace(metadata, " ", ",", -1)
		disks := []string{}
		for _, d := range vm.AttachedDisks {
			disks = append(disks, fmt.Sprintf("%s\t%s\t%s\t%s\t%d\t%t", d.ID, d.Name, d.Kind, d.Flavor, d.CapacityGB, d.BootDisk))
		}
		scriptDisks := strings.Join(disks, ",")
		iso := []string{}
		for _, i := range vm.AttachedISOs {
			iso = append(iso, fmt.Sprintf("%s\t%s\t%s\t%d", i.ID, i.Name, i.Kind, i.Size))
		}
		scriptIso := strings.Join(iso, ",")
		fmt.Printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", vm.ID, vm.Name, vm.State, vm.Flavor,
			vm.SourceImageID, vm.Host, vm.Datastore, scriptMetadata, scriptTag, vm.FloatingIp)
		fmt.Printf("%s\n", scriptDisks)
		fmt.Printf("%s\n", scriptIso)

		err = printVMNetworks(networks, c.GlobalIsSet("non-interactive"))
		if err != nil {
			return err
		}
	} else if utils.NeedsFormatting(c) {
		utils.FormatObject(vm, w, c)
	} else {
		fmt.Println("VM ID: ", vm.ID)
		fmt.Println("  Name:        ", vm.Name)
		fmt.Println("  State:       ", vm.State)
		fmt.Println("  Floating IP: ", vm.FloatingIp)
		fmt.Println("  Flavor:      ", vm.Flavor)
		fmt.Println("  Source Image:", vm.SourceImageID)
		fmt.Println("  Host:        ", vm.Host)
		fmt.Println("  Datastore:   ", vm.Datastore)
		fmt.Println("  Metadata:    ", vm.Metadata)
		fmt.Println("  Disks:       ")
		for i, d := range vm.AttachedDisks {
			fmt.Printf("    Disk %d:\n", i+1)
			fmt.Println("      ID:       ", d.ID)
			fmt.Println("      Name:     ", d.Name)
			fmt.Println("      Kind:     ", d.Kind)
			fmt.Println("      Flavor:   ", d.Flavor)
			fmt.Println("      Capacity: ", d.CapacityGB)
			fmt.Println("      Boot:     ", d.BootDisk)
		}
		for i, iso := range vm.AttachedISOs {
			fmt.Printf("    ISO %d:\n", i+1)
			fmt.Println("      Name: ", iso.Name)
			fmt.Println("      Size: ", iso.Size)
		}
		for i, nt := range networks {
			network := nt.(map[string]interface{})
			fmt.Printf("    Networks: %d\n", i+1)
			networkName := ""
			ipAddr := ""
			if val, ok := network["network"]; ok && val != nil {
				networkName = val.(string)
			}
			if val, ok := network["ipAddress"]; ok && val != nil {
				ipAddr = val.(string)
			}
			fmt.Println("      Name:       ", networkName)
			fmt.Println("      IP Address: ", ipAddr)
		}
		for i, tag := range vm.Tags {
			fmt.Printf("    Tag %d:\n", i+1)
			fmt.Println("      Tag Info:     ", tag)
		}
	}

	return nil
}
예제 #27
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 := checkArgCount(c, 0)
	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")
	etcd1 := c.String("etcd1")
	etcd2 := c.String("etcd2")
	etcd3 := c.String("etcd3")
	batch_size := c.Int("batchSize")
	ssh_key := c.String("ssh-key")
	ca_cert := c.String("registry-ca-cert")
	admin_password := c.String("admin-password")

	if admin_password != "" {
		result := validateHarborPassword(admin_password)
		if result != true {
			return fmt.Errorf("The Harbor password is invalid. It should have at least 7 characters " +
				"with 1 lowercase letter, 1 capital letter and 1 numeric character.")
		}
	}

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

	const DEFAULT_WORKER_COUNT = 1

	client.Esxclient, err = client.GetClient(c)
	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 !c.GlobalIsSet("non-interactive") {
		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 && cluster_type != "HARBOR" {
			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 && cluster_type != "HARBOR" {
		worker_count = DEFAULT_WORKER_COUNT
	}

	if !c.GlobalIsSet("non-interactive") {
		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
		}
	}

	if len(ca_cert) != 0 {
		ca_cert_content, err := readCACert(ca_cert)
		if err == nil {
			extended_properties[photon.ExtendedPropertyRegistryCACert] = ca_cert_content
		} else {
			return err
		}
	}

	cluster_type = strings.ToUpper(cluster_type)
	switch cluster_type {
	case "KUBERNETES":
		if !c.GlobalIsSet("non-interactive") {
			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 "HARBOR":
		if !c.GlobalIsSet("non-interactive") {
			master_ip, err = askForInput("Harbor master static IP address: ", master_ip)
			if err != nil {
				return err
			}
			if len(admin_password) == 0 {
				fmt.Printf("Harbor registry admin password: "******"The Harbor password is invalid. It should have at least 7 " +
						"characters with 1 lowercase letter, 1 capital letter and 1 numeric " +
						"character.")
				}
				fmt.Printf("\n")
			}
		}
		extended_properties[photon.ExtendedPropertyMasterIP] = master_ip
		extended_properties[photon.ExtendedPropertyAdminPassword] = admin_password
	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 !c.GlobalIsSet("non-interactive") {
		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)
		}
		if clusterSpec.Type != "HARBOR" {
			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(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
}
예제 #28
0
func createVirtualNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 0)
	if err != nil {
		return err
	}

	name := c.String("name")
	description := c.String("description")
	routingType := c.String("routingType")
	sizeStr := c.String("size")
	staticIpSizeStr := c.String("staticIpSize")
	projectId := c.String("projectId")

	if len(projectId) == 0 {
		tenant, err := verifyTenant("")
		if err != nil {
			return err
		}

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

		projectId = project.ID
	}

	if !c.GlobalIsSet("non-interactive") {
		name, err = askForInput("Network name: ", name)
		if err != nil {
			return err
		}
		description, err = askForInput("Description of network: ", description)
		if err != nil {
			return err
		}
		routingType, err = askForInput("Routing type of network: ", routingType)
		if err != nil {
			return err
		}
		projectId, err = askForInput("Project ID that network belongs to: ", projectId)
		if err != nil {
			return err
		}
		sizeStr, err = askForInput("Size of IP pool of the network (must be power of 2, at least 8): ", sizeStr)
		if err != nil {
			return err
		}
		staticIpSizeStr, err = askForInput("Size of the static IP pool (must be less than size of IP pool): ",
			staticIpSizeStr)
		if err != nil {
			return err
		}
	}

	if len(name) == 0 {
		return fmt.Errorf("Please provide network name")
	}
	if routingType != ROUTED && routingType != ISOLATED {
		return fmt.Errorf("Please choose the correct routing type for network (ROUTED or ISOLATED)")
	}
	size, err := strconv.Atoi(sizeStr)
	if err != nil {
		return err
	}
	if size < 8 {
		return fmt.Errorf("Network size must be at least 8")
	}
	staticIpSize, err := strconv.Atoi(staticIpSizeStr)
	if err != nil {
		return err
	}

	createSpec := &photon.VirtualSubnetCreateSpec{
		Name:                 name,
		Description:          description,
		RoutingType:          routingType,
		Size:                 size,
		ReservedStaticIpSize: staticIpSize,
	}

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

	task, err := client.Esxclient.VirtualSubnets.Create(projectId, 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
}
예제 #29
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 := checkArgCount(c, 1)
	if err != nil {
		return err
	}
	id := c.Args().First()

	client.Esxclient, err = client.GetClient(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"), "[]")
		if cluster.ErrorReason != "" {
			fmt.Printf("%s\t%s\t%s\t%s\t%d\t%s\t%s\n", cluster.ID, cluster.Name, cluster.State, cluster.Type,
				cluster.WorkerCount, cluster.ErrorReason, extendedProperties)
		} else {
			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)
		if cluster.ErrorReason != "" {
			fmt.Println("  Error Reason:        ", cluster.ErrorReason)
		}
		fmt.Println("  Extended Properties: ", cluster.ExtendedProperties)
		fmt.Println()
	}

	err = printClusterVMs(master_vms, w, c)
	if err != nil {
		return err
	}

	return nil
}
func createPhysicalNetwork(c *cli.Context, w io.Writer) error {
	err := checkArgCount(c, 0)
	if err != nil {
		return err
	}

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

	if !c.GlobalIsSet("non-interactive") {
		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(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
}