コード例 #1
0
ファイル: snapshot_take.go プロジェクト: grrtrr/clcv2
func main() {
	var days = flag.Int("days", 10, "Number of days to keep the snapshot for")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	statusId, err := client.CreateSnapshot(flag.Arg(0), *days)
	if err != nil {
		exit.Fatalf("failed to take snapshot of server %s: %s", flag.Arg(0), err)
	}

	fmt.Println("Request ID for taking server snapshot:", statusId)
}
コード例 #2
0
ファイル: show_account_policy.go プロジェクト: grrtrr/clcv2
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Account-Policy-ID>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(0)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	p, err := client.SBSgetPolicy(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to list SBS account policy %s: %s", flag.Arg(0), err)
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoFormatHeaders(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetAutoWrapText(false)
	table.SetHeader([]string{"Name", "Policy ID", "OS", "Status", "Freq/h", "Ret/d", "Paths"})

	table.Append([]string{p.Name, p.PolicyID, p.OsType, p.Status, fmt.Sprint(p.BackupIntervalHours),
		fmt.Sprint(p.RetentionDays), strings.Join(p.Paths, ", ")})
	table.Render()
}
コード例 #3
0
ファイル: set_memory.go プロジェクト: grrtrr/clcv2
func main() {
	var memory = flag.Int("mem", 0, "The amount of memory (in GB) to set for this server")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 || *memory == 0 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	statusId, err := client.ServerSetMemory(flag.Arg(0), fmt.Sprint(*memory))
	if err != nil {
		exit.Fatalf("failed to change the amount of Memory on %q: %s", flag.Arg(0), err)
	}

	fmt.Printf("Status Id for changing the memory on %s: %s\n", flag.Arg(0), statusId)
}
コード例 #4
0
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  Location-Alias\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
		os.Exit(0)
	}
	flag.Parse()

	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	capa, err := client.GetBareMetalCapabilities(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to query bare-metal capabilities of %s: %s", flag.Arg(0), err)
	}

	fmt.Printf("Datacenter %s:\n", flag.Arg(0))
	pretty.Println(capa)
}
コード例 #5
0
ファイル: snapshot_list.go プロジェクト: grrtrr/clcv2
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()

	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	snapshot, err := client.GetServerSnapshot(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to query snapshots of %s: %s", flag.Arg(0), err)
	}

	if snapshot == nil {
		fmt.Printf("Server %s does not have any snapshots.\n", flag.Arg(0))
	} else {
		fmt.Printf("Snapshot of %s: %s\n", flag.Arg(0), snapshot.Name)
	}
}
コード例 #6
0
ファイル: get_credentials.go プロジェクト: grrtrr/clcv2
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()

	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	credentials, err := client.GetServerCredentials(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to obtain the credentials of server %q: %s", flag.Arg(0), err)
	}

	fmt.Printf("Credentials for %s:\n", flag.Arg(0))
	fmt.Printf("User:     %s\n", credentials.Username)
	fmt.Printf("Password: \"%s\"\n", credentials.Password)
}
コード例 #7
0
ファイル: disk_resize.go プロジェクト: grrtrr/clcv2
func main() {
	var size = flag.Uint("size", 0, "New size of the disk in GB")
	// Allow the same ID types as in disk_remove.go
	var reMajMin = regexp.MustCompile(`^\d+:\d+$`)
	var reMin = regexp.MustCompile(`^\d+$`)
	var id string

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Server-Name>  <Disk-ID>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 2 || *size == 0 {
		flag.Usage()
		os.Exit(1)
	} else if reMajMin.MatchString(flag.Arg(1)) {
		id = flag.Arg(1)
	} else if reMin.MatchString(flag.Arg(1)) {
		id = fmt.Sprintf("0:%s", flag.Arg(1))
	} else {
		exit.Errorf("invalid disk ID %q", flag.Arg(1))
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	server, err := client.GetServer(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to list details of server %q: %s", flag.Arg(0), err)
	}

	disks := make([]clcv2.ServerAdditionalDisk, len(server.Details.Disks))
	for i := range server.Details.Disks {
		disks[i] = clcv2.ServerAdditionalDisk{
			Id:     server.Details.Disks[i].Id,
			SizeGB: server.Details.Disks[i].SizeGB,
		}
		if disks[i].Id == id {
			// The API does not allow to reduce the size of an existing disk.
			if uint32(*size) <= disks[i].SizeGB {
				fmt.Printf("Disk %s size is already at %d GB.\n", id, disks[i].SizeGB)
				os.Exit(0)
			}
			fmt.Printf("Changing disk %s size from %d to %d GB ...\n",
				id, disks[i].SizeGB, *size)
			disks[i].SizeGB = uint32(*size)
		}
	}

	reqID, err := client.ServerSetDisks(flag.Arg(0), disks)
	if err != nil {
		exit.Fatalf("failed to update the disk configuration on %q: %s", flag.Arg(0), err)
	}

	log.Printf("Status Id for resizing the disk on %s: %s", flag.Arg(0), reqID)
	client.PollStatus(reqID, 10*time.Second)
}
コード例 #8
0
ファイル: ip.go プロジェクト: grrtrr/clcv2
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Server Name> [<Server Name> ...]\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	for _, srv := range flag.Args() {
		ips, err := client.GetServerIPs(srv)
		if err != nil {
			exit.Fatalf("failed to list details of server %q: %s", srv, err)
		}

		fmt.Printf("%-20s %s\n", srv+":", strings.Join(ips, ", "))
	}
}
コード例 #9
0
ファイル: create.go プロジェクト: grrtrr/clcv2
func main() {
	var location = flag.String("l", "", "Location alias of data centre to host load balancer")
	var desc = flag.String("desc", "", "Textual description of the load balancer")
	var status = flag.String("status", "enabled", "Whether to an 'enabled' or 'disabled' load balancer")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Load Balancer Name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	fmt.Println(flag.NArg())
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	lb, err := client.CreateSharedLoadBalancer(flag.Arg(0), *desc, *status, *location)
	if err != nil {
		exit.Fatalf("failed to create shared load balancer %q: %s", flag.Arg(0), err)
	}

	fmt.Printf("Created %s load balancer %s, %q with IP %s\n", *location, lb.ID, lb.Name, lb.IpAddress)
}
コード例 #10
0
ファイル: find_server_by_ip.go プロジェクト: grrtrr/clcv2
func main() {
	var location = flag.String("l", "", "Alias of the data centre the server resides in")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <IP Address>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 || *location == "" {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	iad, err := client.GetNetworkDetailsByIp(flag.Arg(0), *location)
	if err != nil {
		exit.Fatalf("failed to look up %s: %s", flag.Arg(0), err)
	} else if iad == nil {
		exit.Errorf("No match found for %s in %s", flag.Arg(0), *location)
	}

	// The 'Server' field is not necessarily filled in, hence we need to test here.
	if iad.Server != "" {
		fmt.Printf("%s is used by %s.\n", iad.Address, iad.Server)
	} else {
		fmt.Printf("%s is in %s use in %s, but the server name is not disclosed.\n", iad.Address, iad.Type, *location)
	}
}
コード例 #11
0
ファイル: set_cpu.go プロジェクト: grrtrr/clcv2
func main() {
	var cpus = flag.Int("cpu", 0, "The number of CPU cores to set for this server")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 || *cpus == 0 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	statusId, err := client.ServerSetCpus(flag.Arg(0), fmt.Sprint(*cpus))
	if err != nil {
		exit.Fatalf("failed to change the number of CPUs on %q: %s", flag.Arg(0), err)
	}

	fmt.Printf("Status Id for changing the #CPUs on %s: %s\n", flag.Arg(0), statusId)
}
コード例 #12
0
ファイル: set_description.go プロジェクト: grrtrr/clcv2
func main() {
	var description = flag.String("desc", "", "New description to use for the server")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 || *description == "" {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	err = client.ServerSetDescription(flag.Arg(0), *description)
	if err != nil {
		exit.Fatalf("failed to change the description on %q: %s", flag.Arg(0), err)
	}

	fmt.Printf("Successfully changed the description on %s.\n", flag.Arg(0))
}
コード例 #13
0
ファイル: maintenance_toggle.go プロジェクト: grrtrr/clcv2
func main() {
	var maintenance = flag.Bool("m", true, "Turn maintenance mode on (-m) or off (-m=false)")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	statusId, err := client.ServerSetMaintenance(flag.Arg(0), *maintenance)
	if err != nil {
		exit.Fatalf("failed to modify maintenance mode on server %s: %s", flag.Arg(0), err)
	}

	fmt.Println("Request ID for maintenance mode status change:", statusId)
}
コード例 #14
0
ファイル: list_account_policies.go プロジェクト: grrtrr/clcv2
func main() {
	flag.Parse()

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	policies, err := client.SBSgetPolicies()
	if err != nil {
		exit.Fatalf("failed to list SBS policies: %s", err)
	}

	if len(policies) == 0 {
		fmt.Println("No Account Policies defined.")
	} else {
		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_LEFT)
		table.SetAutoWrapText(false)
		table.SetHeader([]string{"Name", "Policy ID", "OS", "Status", "Freq/h", "Ret/d", "Paths"})

		for _, p := range policies {
			table.Append([]string{p.Name, p.PolicyID, p.OsType, p.Status, fmt.Sprint(p.BackupIntervalHours),
				fmt.Sprint(p.RetentionDays), strings.Join(p.Paths, ", ")})
		}
		table.Render()
	}
}
コード例 #15
0
ファイル: show.go プロジェクト: grrtrr/clcv2
func main() {
	var simple = flag.Bool("simple", false, "Use simple (debugging) output format")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <VPN ID>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	vpn, err := client.GetVPN(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to query VPN %s: %s", flag.Arg(0), err)
	}

	if *simple {
		pretty.Println(vpn)
	} else {
		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_LEFT)
		table.SetAutoWrapText(false)

		//		table.SetHeader([]string{"CLC => Remote", "CLC Nets",			"Remote", "Remote Nets", "ID", "Last Change",		})

		modifiedStr := humanize.Time(vpn.ChangeInfo.ModifiedDate)
		// The ModifiedBy field can be an email address, or an API Key (hex string)
		if _, err := hex.DecodeString(vpn.ChangeInfo.ModifiedBy); err == nil {
			modifiedStr += " via API Key"
		} else {
			modifiedStr += ", by " + vpn.ChangeInfo.ModifiedBy
		}

		table.Append([]string{fmt.Sprintf("%s subnets:", vpn.Local.LocationAlias), strings.Join(vpn.Local.Subnets, ", ")})
		table.Append([]string{fmt.Sprintf("%s endpoint:", vpn.Local.LocationAlias), vpn.Local.Address})
		table.Append([]string{fmt.Sprintf("%s endpoint:", vpn.Remote.SiteName), vpn.Remote.Address})
		table.Append([]string{fmt.Sprintf("%s subnets:", vpn.Remote.SiteName), strings.Join(vpn.Remote.Subnets, ", ")})
		table.Append([]string{"IKE configuration:", fmt.Sprintf("%s, %s/%s, Key: %q, NAT traversal: %t, Lifetime: %s",
			vpn.IKE.DiffieHellmanGroup,
			vpn.IKE.Encryption, vpn.IKE.Hashing, vpn.IKE.PreSharedKey,
			vpn.IKE.NatTraversal,
			time.Duration(vpn.IKE.Lifetime)*time.Second)})
		table.Append([]string{"IPsec configuration:", fmt.Sprintf("%s, %s/%s, %s, Lifetime: %s",
			vpn.IPsec.Pfs, vpn.IPsec.Encryption, vpn.IPsec.Hashing,
			strings.ToUpper(vpn.IPsec.Protocol), time.Duration(vpn.IPsec.Lifetime)*time.Second)})
		table.Append([]string{"Last change:", modifiedStr})

		table.Render()
	}
}
コード例 #16
0
func main() {
	var policies []clcv2.SBSServerPolicy
	var day = time.Now()
	var date = flag.String("start", day.Format("2006-01-02"), "Day to query storage usage for")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Server-Policy-ID | Server-Name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(0)
	}

	day, err := time.Parse("2006-01-02", *date)
	if err != nil {
		exit.Error("invalid backup query date %s (expected format: YYYY-MM-DD)", *date)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	// First look up the corresponding Server Policy or Policies, since the query needs the Account Policy ID.
	if utils.LooksLikeServerName(flag.Arg(0)) {
		policies, err = client.SBSgetServerPolicyDetails(flag.Arg(0))
		if err != nil {
			exit.Fatalf("failed to list SBS policies for server %s: %s", flag.Arg(0), err)
		}
	} else {
		p, err := client.SBSgetServerPolicy(flag.Arg(0))
		if err != nil {
			exit.Fatalf("failed to list SBS Server Policy %s: %s", flag.Arg(0), err)
		}
		policies = []clcv2.SBSServerPolicy{*p}
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoFormatHeaders(false)
	table.SetAlignment(tablewriter.ALIGN_CENTRE)
	table.SetAutoWrapText(false)
	table.SetHeader([]string{"Server",
		fmt.Sprintf("Usage on %s", day.Format("Mon, Jan 2 2006")),
		"Server Policy ID", "Account Policy ID",
	})

	for _, p := range policies {
		usage, err := client.SBSgetServerStorageUsage(p.AccountPolicyID, p.ID, day)
		if err != nil {
			exit.Fatalf("failed to obtain server %s storage use on %s: %s", p.ServerID, day.Format("2006-01-02"), err)
		}
		table.Append([]string{p.ServerID, humanize.Bytes(usage), p.ID, p.AccountPolicyID})
	}
	table.Render()
}
コード例 #17
0
ファイル: disk_remove.go プロジェクト: grrtrr/clcv2
func main() {
	// Allow two types of ID: (a) <major>:<minor> syntax, (b) <minor> syntax
	var reMajMin = regexp.MustCompile(`^\d+:\d+$`)
	var reMin = regexp.MustCompile(`^\d+$`)
	var ids []string

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Server Name> <diskId> [<diskId> ...]\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() < 2 {
		flag.Usage()
		os.Exit(1)
	}

	for i := 1; i < flag.NArg(); i++ {
		if reMajMin.MatchString(flag.Arg(i)) {
			ids = append(ids, flag.Arg(i))
		} else if reMin.MatchString(flag.Arg(i)) {
			ids = append(ids, fmt.Sprintf("0:%s", flag.Arg(i)))
		} else {
			exit.Errorf("invalid disk ID %q", flag.Arg(i))
		}
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	server, err := client.GetServer(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to list details of server %q: %s", flag.Arg(0), err)
	}

	disks := make([]clcv2.ServerAdditionalDisk, 0)
	for i := range server.Details.Disks {
		if inStringArray(server.Details.Disks[i].Id, ids...) {
			fmt.Printf("Deleting disk %s (%d GB) ...\n", server.Details.Disks[i].Id, server.Details.Disks[i].SizeGB)
		} else {
			disks = append(disks, clcv2.ServerAdditionalDisk{
				Id:     server.Details.Disks[i].Id,
				SizeGB: server.Details.Disks[i].SizeGB,
			})
		}
	}

	reqID, err := client.ServerSetDisks(flag.Arg(0), disks)
	if err != nil {
		exit.Fatalf("failed to update the disk configuration on %q: %s", flag.Arg(0), err)
	}

	log.Printf("Status Id for updating the disks on %s: %s", flag.Arg(0), reqID)
	client.PollStatus(reqID, 5*time.Second)
}
コード例 #18
0
ファイル: set_parent.go プロジェクト: grrtrr/clcv2
func main() {
	var child string /* UUID of the group to relocate */
	var parent = flag.String("g", "", "UUID or name of the new parent group")
	var location = flag.String("l", "", "Location to use if using Group Name instead of UUID")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Group Name or UUID>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 || *parent == "" {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	if _, err := hex.DecodeString(flag.Arg(0)); err == nil {
		child = flag.Arg(0)
	} else if *location == "" {
		exit.Errorf("Need a location argument (-l) if not using Group UUID (%s)", flag.Arg(0))
	} else {
		if grp, err := client.GetGroupByName(flag.Arg(0), *location); err != nil {
			exit.Errorf("failed to resolve group name %q: %s", flag.Arg(0), err)
		} else if grp == nil {
			exit.Errorf("No group named %q was found in %s", flag.Arg(0), *location)
		} else {
			child = grp.Id
		}
	}

	if _, err := hex.DecodeString(*parent); err == nil {
		/* Looks like a Group UUID */
	} else if *location == "" {
		exit.Errorf("Need a location argument (-l) if parent (-g %s) is not a UUID", *parent)
	} else {
		if grp, err := client.GetGroupByName(*parent, *location); err != nil {
			exit.Errorf("failed to resolve group name %q: %s", *parent, err)
		} else if grp == nil {
			exit.Errorf("No group named %q was found in %s", *parent, *location)
		} else {
			*parent = grp.Id
		}
	}

	err = client.GroupSetParent(child, *parent)
	if err != nil {
		exit.Fatalf("failed to change the parent group of %q: %s", flag.Arg(0), err)
	}

	fmt.Printf("Successfully changed the parent group of %s to %s.\n", flag.Arg(0), *parent)
}
コード例 #19
0
ファイル: invoice_data.go プロジェクト: grrtrr/clcv2
func main() {
	var now = time.Now()
	var pricingAcct = flag.String("pricing", "", "Pricing account (to use instead of default account alias)")
	var invoiceYear = flag.Int("y", now.Year(), "Year of the invoice date")
	var invoiceMonth = flag.Int("m", int(now.Month())-1, "Month of the invoice date")
	var itemDetails = flag.Bool("details", false, "Print individual line item details also")

	flag.Parse()

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	id, err := client.GetInvoiceData(*invoiceYear, *invoiceMonth, *pricingAcct)
	if err != nil {
		exit.Fatalf("failed to obtain invoice data: %s", err)
	}

	fmt.Printf("Details of invoice %q for %s (%s):\n", id.Id, id.PricingAccountAlias, id.CompanyName)
	fmt.Printf("Address:               %s, %s, %s, %s\n", id.Address1, id.City, id.StateProvince, id.PostalCode)
	fmt.Printf("Parent account alias:  %s\n", id.ParentAccountAlias)
	fmt.Printf("Billing contact email: %s\n", id.BillingContactEmail)
	fmt.Printf("Invoice date:          %s\n", id.InvoiceDate.Format("January 2006"))
	fmt.Printf("Terms:                 %s\n", id.Terms)
	fmt.Printf("Total amount:          $%.2f\n", id.TotalAmount)

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoFormatHeaders(false)
	table.SetAutoWrapText(false)
	table.SetAlignment(tablewriter.ALIGN_RIGHT)

	table.SetHeader([]string{
		"Description", "Location", "Quantity", "Unit Cost", "Total",
	})

	for _, li := range id.LineItems {
		table.Append([]string{
			li.Description, li.ServiceLocation, fmt.Sprint(li.Quantity),
			fmt.Sprintf("%.2f", li.UnitCost), fmt.Sprintf("%.2f", li.ItemTotal),
		})
	}
	table.Render()

	if *itemDetails {
		fmt.Println("\n\nIndividual details:")
		for _, li := range id.LineItems {
			if len(li.ItemDetails) != 0 {
				fmt.Printf("%s ($%.2f total):\n", li.Description, li.ItemTotal)
				for _, det := range li.ItemDetails {
					fmt.Printf("\t%-20.20s $%.2f\n", det.Description, det.Cost)
				}
			}
		}
	}
}
コード例 #20
0
ファイル: list.go プロジェクト: grrtrr/clcv2
func main() {
	var simple = flag.Bool("simple", false, "Use simple (debugging) output format")
	var dst = flag.String("dst", "", "Destination account to filter policies by")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Location>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}
	flag.Parse()

	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	fwpl, err := client.GetCrossDataCenterFirewallPolicyList(flag.Arg(0), *dst)
	if err != nil {
		exit.Fatalf("failed to list firewall policies at %s: %s", flag.Arg(0), err)
	}

	if len(fwpl) == 0 {
		fmt.Printf("Empty result - nothing listed at %s.\n", flag.Arg(0))
	} else if *simple {
		pretty.Println(fwpl)
	} else {
		fmt.Printf("Cross-Datacenter Firewall Policies at %s:\n", strings.ToUpper(flag.Arg(0)))

		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_CENTRE)
		table.SetAutoWrapText(false)

		table.SetHeader([]string{"Data Center", "Network", "Account", "Status", "ID"})
		for _, p := range fwpl {
			var enabledStr = "*"

			if !p.Enabled {
				enabledStr = "-"
			}
			table.Append([]string{
				strings.ToUpper(fmt.Sprintf("%s => %s", p.SourceLocation, p.DestLocation)),
				fmt.Sprintf("%18s => %-18s", p.SourceCIDR, p.DestCIDR),
				strings.ToUpper(fmt.Sprintf("%-4s => %4s", p.SourceAccount, p.DestAccount)),
				fmt.Sprintf("%s%s", enabledStr, p.Status),
				p.ID,
			})
		}
		table.Render()
	}
}
コード例 #21
0
ファイル: details.go プロジェクト: grrtrr/clcv2
func main() {
	var (
		query    = flag.String("q", "none", "Filter IP addresses; one of 'none', 'claimed', 'free', or 'all'")
		location = flag.String("l", os.Getenv("CLC_LOCATION"), "Data centre alias (needed to resolve IDs)")
		simple   = flag.Bool("simple", false, "Use simple (debugging) output format")
	)

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options] -l <Location>  <Network-ID (hex)>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	/* Location is required (despite hex id), an empty location leads to a "404 Not Found" response. */
	if flag.NArg() != 1 || *location == "" {
		flag.Usage()
		os.Exit(1)
	} else if !inStringArray(*query, "none", "claimed", "free", "all") {
		exit.Errorf("Invalid IP query %q. Try -h")
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	details, err := client.GetNetworkDetails(*location, flag.Arg(0), *query)
	if err != nil {
		exit.Fatalf("failed to query network details of %s: %s", flag.Arg(0), err)
	}

	if *simple {
		pretty.Println(details)
	} else {
		fmt.Printf("Details of %s (%s):\n", details.Name, details.Description)
		fmt.Printf("CIDR:    %s\n", details.Cidr)
		fmt.Printf("Gateway: %s\n", details.Gateway)
		fmt.Printf("Type:    %s\n", details.Type)
		fmt.Printf("VLAN:    %d\n", details.Vlan)

		if len(details.IpAddresses) > 0 {
			table := tablewriter.NewWriter(os.Stdout)
			table.SetAutoFormatHeaders(false)
			table.SetAlignment(tablewriter.ALIGN_RIGHT)
			table.SetAutoWrapText(false)

			table.SetHeader([]string{"Address", "Claimed", "Server", "Type"})
			for _, i := range details.IpAddresses {
				table.Append([]string{i.Address, fmt.Sprint(i.Claimed), i.Server, i.Type})
			}
			table.Render()
		}
	}
}
コード例 #22
0
ファイル: list.go プロジェクト: grrtrr/clcv2
func main() {
	var simple = flag.Bool("simple", false, "Use simple (debugging) output format")
	var dst = flag.String("dst", "", "Destination account to filter policies by")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Location>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}
	flag.Parse()

	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	fwpl, err := client.GetIntraDataCenterFirewallPolicyList(flag.Arg(0), *dst)
	if err != nil {
		exit.Fatalf("failed to list intra-datacenter firewall policies at %s: %s", flag.Arg(0), err)
	}

	if len(fwpl) == 0 {
		fmt.Printf("Empty result - nothing listed at %s.\n", flag.Arg(0))
	} else if *simple {
		pretty.Println(fwpl)
	} else {
		fmt.Printf("Intra-Datacenter Firewall Policies for %s at %s:\n", client.AccountAlias, strings.ToUpper(flag.Arg(0)))

		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_CENTRE)
		table.SetAutoWrapText(true)

		table.SetHeader([]string{"Source", "Destination", "Ports",
			"Dst Account", "Enabled", "State", "Id",
		})

		for _, p := range fwpl {
			table.Append([]string{
				strings.Join(p.Source, ", "),
				strings.Join(p.Destination, ", "),
				strings.Join(p.Ports, ", "),
				strings.ToUpper(p.DestinationAccount),
				fmt.Sprint(p.Enabled), p.Status, p.ID,
			})
		}
		table.Render()
	}
}
コード例 #23
0
ファイル: show_server_policy.go プロジェクト: grrtrr/clcv2
func main() {
	var policies []clcv2.SBSServerPolicy

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Server-Policy-ID | Server-Name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(0)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	if utils.LooksLikeServerName(flag.Arg(0)) {
		// Note: when using the server name instead of the Server Policy ID, sometimes the Status field is empty.
		policies, err = client.SBSgetServerPolicyDetails(flag.Arg(0))
		if err != nil {
			exit.Fatalf("failed to list SBS policies for server %s: %s", flag.Arg(0), err)
		}
	} else {
		// Query by Server Policy ID
		p, err := client.SBSgetServerPolicy(flag.Arg(0))
		if err != nil {
			exit.Fatalf("failed to list SBS Server Policy %s: %s", flag.Arg(0), err)
		}
		policies = []clcv2.SBSServerPolicy{*p}
	}

	if len(policies) == 0 {
		fmt.Printf("Nothing found for %s.\n", flag.Arg(0))
	} else {
		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_LEFT)
		table.SetAutoWrapText(false)
		table.SetHeader([]string{"Server", "Server Policy ID", "Account Policy ID",
			"Status", "Region", "Account", "Unsubscribe Date", "Expiration Date"})

		for _, p := range policies {
			table.Append([]string{p.ServerID, p.ID, p.AccountPolicyID,
				p.Status, p.StorageRegion, p.ClcAccountAlias,
				fmt.Sprint(p.UnsubscribedDate), fmt.Sprint(p.ExpirationDate)})
		}
		table.Render()
	}
}
コード例 #24
0
ファイル: list.go プロジェクト: grrtrr/clcv2
func main() {
	var links = flag.Bool("l", false, "List the Link References as well")

	flag.Parse()

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	datacenters, err := client.GetLocations()
	if err != nil {
		exit.Fatalf("failed to get datacenter information: %s", err)
	}

	if *links {
		for _, ctr := range datacenters {
			fmt.Println("\n", ctr.Name)

			table := tablewriter.NewWriter(os.Stdout)
			table.SetAutoFormatHeaders(false)
			table.SetAlignment(tablewriter.ALIGN_LEFT)
			table.SetAutoWrapText(false)

			// See https://www.ctl.io/api-docs/v2/#getting-started-api-v20-links-framework
			table.SetHeader([]string{"Rel", "Href", "Verbs"})
			for _, link := range ctr.Links {
				var verbs string

				if len(link.Verbs) == 0 {
					verbs = "GET"
				} else {
					verbs = strings.Join(link.Verbs, ", ")
				}
				table.Append([]string{link.Rel, link.Href, verbs})
			}
			table.Render()
		}
	} else {
		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_LEFT)
		table.SetAutoWrapText(false)
		table.SetHeader([]string{"Id", "Name"})

		for _, ctr := range datacenters {
			table.Append([]string{ctr.Id, ctr.Name})
		}
		table.Render()
	}
}
コード例 #25
0
ファイル: servers.go プロジェクト: grrtrr/clcv2
func main() {
	// By default, the scripts outputs a space-separated list of servers on a single line (for scripting).
	var pretty = flag.Bool("pretty", false, "Pretty-print the server list (uses tabular output)")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  '<data centre name>'\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(0)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	servers, err := client.SBSgetServersByDatacenter(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to list SBS servers in %q: %s", flag.Arg(0), err)
	}

	if len(servers) == 0 {
		fmt.Printf("No servers found in %s.\n", flag.Arg(0))
	} else {

		// The query returns servers in lower-case format. Upper-case them for consistency with CLC naming.
		for i := range servers {
			servers[i] = strings.ToUpper(servers[i])
		}

		if *pretty {
			table := tablewriter.NewWriter(os.Stdout)
			table.SetAutoFormatHeaders(false)
			table.SetAlignment(tablewriter.ALIGN_LEFT)
			table.SetAutoWrapText(false)
			table.SetHeader([]string{"Server Name"})

			for _, server := range servers {
				table.Append([]string{server})
			}
			table.Render()
		} else {
			fmt.Println(strings.Join(servers, " "))
		}
	}

}
コード例 #26
0
ファイル: list.go プロジェクト: grrtrr/clcv2
func main() {
	var simple = flag.Bool("simple", false, "Use simple (debugging) output format")
	flag.Parse()

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	vpns, err := client.GetVPNs()
	if err != nil {
		exit.Fatalf("failed to list VPNs: %s", err)
	}

	if len(vpns) == 0 {
		fmt.Printf("No VPNs registered for account %s.\n", client.AccountAlias)
	} else if *simple {
		pretty.Println(vpns)
	} else {
		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_LEFT)
		table.SetAutoWrapText(true)

		table.SetHeader([]string{"CLC => Remote", "CLC Nets",
			"Remote", "Remote Nets", "ID", "Last Change",
		})

		for _, v := range vpns {
			modifiedStr := humanize.Time(v.ChangeInfo.ModifiedDate)
			// The ModifiedBy field can be an email address, or an API Key (hex string)
			if _, err := hex.DecodeString(v.ChangeInfo.ModifiedBy); err == nil {
				modifiedStr += " via API Key"
			} else if len(v.ChangeInfo.ModifiedBy) > 6 {
				modifiedStr += " by " + v.ChangeInfo.ModifiedBy[:6]
			} else {
				modifiedStr += " by " + v.ChangeInfo.ModifiedBy
			}

			table.Append([]string{
				fmt.Sprintf("%s => %-15s", v.Local.LocationAlias, v.Remote.Address),
				strings.Join(v.Local.Subnets, ", "),
				v.Remote.SiteName,
				strings.Join(v.Remote.Subnets, ", "),
				v.ID,
				modifiedStr,
			})
		}
		table.Render()
	}
}
コード例 #27
0
ファイル: os_types.go プロジェクト: grrtrr/clcv2
func main() {
	flag.Parse()

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	osTypes, err := client.SBSgetOsTypes()
	if err != nil {
		exit.Fatalf("failed to retrieve the list of OS Types supported by SBS: %s", err)
	}
	fmt.Printf("Supported SBS OS Types: %s\n", strings.Join(osTypes, " and "))
}
コード例 #28
0
ファイル: disk_add.go プロジェクト: grrtrr/clcv2
func main() {
	var size = flag.Int("size", 0, "Size of the disk in GB")
	var mount = flag.String("path", "", "Optional mountpoint (otherwise disk type defaults to 'raw')")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <Server Name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 || *size <= 0 {
		flag.Usage()
		os.Exit(1)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	/* First get the list of disks */
	server, err := client.GetServer(flag.Arg(0))
	if err != nil {
		exit.Fatalf("failed to list details of server %q: %s", flag.Arg(0), err)
	}

	disks := make([]clcv2.ServerAdditionalDisk, len(server.Details.Disks))
	for i := range server.Details.Disks {
		disks[i] = clcv2.ServerAdditionalDisk{
			Id:     server.Details.Disks[i].Id,
			SizeGB: server.Details.Disks[i].SizeGB,
		}
	}

	/* Add disk at end - if path is specified, type must be set to 'partitioned'. */
	newDisk := clcv2.ServerAdditionalDisk{SizeGB: uint32(*size), Type: "raw"}
	if *mount != "" {
		newDisk.Path = *mount
		newDisk.Type = "partitioned"
	}

	reqID, err := client.ServerSetDisks(flag.Arg(0), append(disks, newDisk))
	if err != nil {
		exit.Fatalf("failed to update the disk configuration on %q: %s", flag.Arg(0), err)
	}

	log.Printf("Status Id for adding disk to %s: %s", flag.Arg(0), reqID)
	client.PollStatus(reqID, 5*time.Second)
}
コード例 #29
0
ファイル: create.go プロジェクト: grrtrr/clcv2
func main() {
	var src, dst clcv2.CIDRs
	var ports clcv2.PortSpecs

	var acct = flag.String("da", "", "Destination account (defaults to source account)")
	flag.Var(&src, "src", "Source network(s) in CIDR notation (option may be repeated)")
	flag.Var(&dst, "dst", "Destination network(s) in CIDR notation (option may be repeated)")
	flag.Var(&ports, "p", "Port spec(s), number(s) or service name(s) (option may be repeated)\n"+
		"        - ping:      use ping or icmp\n"+
		"        - full spec: tcp/20081-20083, udp/554, udp/6080-7000, ...\n"+
		"        - tcp names: rdp, http, https, http-alt, ssh, ftp, ftps, ...\n"+
		"        - tcp ports: 22, 443, 80, 20081-20083, ...\n"+
		"        - DEFAULTS:  ping, ssh, http")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options] -src <SrcCIDR> -dst <DstCIDR>  <Location>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 || len(src) == 0 || len(dst) == 0 {
		flag.Usage()
		os.Exit(0)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	if *acct == "" {
		*acct = client.AccountAlias
	}

	req := clcv2.IntraDataCenterFirewallPolicyReq{
		SourceCIDR:  src,
		DestCIDR:    dst,
		DestAccount: *acct,
		Ports:       clcv2.PortSpecString(ports),
	}

	id, err := client.CreateIntraDataCenterFirewallPolicy(flag.Arg(0), &req)
	if err != nil {
		exit.Fatalf("failed to create intra-datacenter firewall policy in %s: %s", flag.Arg(0), err)
	}
	fmt.Printf("Successfully created intra-datacenter firewall policy %s in %s.\n", id, strings.ToUpper(flag.Arg(0)))
}
コード例 #30
0
ファイル: add.go プロジェクト: grrtrr/clcv2
func main() {
	var srcRes clcv2.SrcRestrictions
	var portSp clcv2.PortSpecs

	flag.Var(&srcRes, "src", "Restrict source traffic to given CIDR range(s)")
	flag.Var(&portSp, "p", "Port spec(s), number(s) or service name(s) (option can be repeated)\n"+
		"        - ping:      use ping or icmp\n"+
		"        - full spec: tcp/20081-20083, udp/554, udp/6080-7000, ...\n"+
		"        - tcp names: rdp, http, https, http-alt, ssh, ftp, ftps, ...\n"+
		"        - tcp ports: 22, 443, 80, 20081-20083, ...\n"+
		"        - DEFAULTS:  ping, ssh, http")
	var ipAddr = flag.String("i", "", "Use this existing internal IP on the server")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [options]  <server-name>\n", path.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	} else if len(portSp) == 0 { /* default port settings */
		portSp.Set("ping")
		portSp.Set("ssh")
		portSp.Set("http")
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	req := clcv2.PublicIPAddress{
		InternalIPAddress:  *ipAddr,
		Ports:              portSp,
		SourceRestrictions: srcRes,
	}

	reqId, err := client.AddPublicIPAddress(flag.Arg(0), &req)
	if err != nil {
		exit.Fatalf("failed to add a public IP address to %q: %s", flag.Arg(0), err)
	}

	client.PollStatus(reqId, 1*time.Second)
}