upcloud-go-api

module
v4.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2022 License: MIT

README

UpCloud Go API client library

Build Status Go Report Card GoDoc

This is the official client for interfacing with UpCloud's API using the Go programming language. The features allows for easy and quick development and integration when using Go.

Installation and requirements

You'll need Go 1.15 or higher to use the client. You can use the following command to retrieve the client:

go get github.com/UpCloudLtd/upcloud-go-api

Usage

The general usage of the client adheres to the following pattern:

  • Authenticate by creating a client.Client
  • Create a service.Service by passing the newly created client object to it
  • Interface with the API using the various methods of the service object. Methods that take parameters wrap them in request objects.

We recommend setting up a separate subaccount for API usage to allow better access control and security. You can find out more about creating subaccounts at the following support article for Server Tags and Group Accounts. We strongly recommend limiting the connections to a specific address or address range for security purposes.

The examples here only deal with how to use the client itself. For information on how to use the API in general, please consult the UpCloud API documentation.

Creating the client and the service
// Authenticate by passing your account login credentials to the client
c := client.New(user, password)

// It is generally a good idea to override the default timeout of the underlying HTTP client since some requests block for longer periods of time
c.SetTimeout(time.Second * 30)

// Create the service object
svc := service.New(c)
Context support

Use client.NewWithContext and service.NewWithContext to create context-aware service object.
Context-aware service methods accepts context.Context as a first argument which is passed to underlying HTTP request.

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
defer cancel()
svc := service.NewWithContext(client.NewWithContext(user, password))
zones, err := svc.GetZones(ctx)
Validating credentials

The easiest way to check whether the client credentials are correct is to issue a call to GetAccount().

username := "completely"
password := "invalid"

svc := service.New(client.New(username, password))

_, err := svc.GetAccount()

if err != nil {
	panic("Invalid credentials")
}
Error handling

All Service methods return a result and an error object. You can differentiate between generic connection errors (like the API not being reachable) and service errors, which are errors returned in the response body by the API. This is useful for gracefully recovering from certain types of errors.

username := "completely"
password := "invalid"

svc := service.New(client.New(username, password))

_, err := svc.GetAccount()

// Handle errors in general
if (err != nil) {
	// Handle service errors specifically
	if serviceError, ok := err.(*upcloud.Error); ok {
		fmt.Println(serviceError.ErrorCode)
		fmt.Println(serviceError.ErrorMessage)
	}
}

This snippet would print the following:

AUTHENTICATION_FAILED
Authentication failed using the given username and password.

The rest of these examples assume you already have a service object configured and named svc.

Retrieving a list of servers

The following example will retrieve a list of servers the account has access to.

// Retrieve the list of servers
servers, err := svc.GetServers()

if err != nil {
	panic(err)
}

// Print the UUID and hostname of each server
for _, server := range servers.Servers {
	fmt.Println(fmt.Sprintf("UUID: %s, hostname: %s", server.UUID, server.Hostname))
}
Creating a new server

Since the request for creating a new server is asynchronous, the server will report its status as "maintenance" until the deployment has been fully completed.

// Create the server
serverDetails, err := svc.CreateServer(&request.CreateServerRequest{
	Zone:             "fi-hel2",
	Title:            "My new server",
	Hostname:         "server.example.com",
	PasswordDelivery: request.PasswordDeliveryNone,
	StorageDevices: []request.CreateServerStorageDevice{
		{
			Action:  request.CreateStorageDeviceActionClone,
			Storage: "01000000-0000-4000-8000-000020060100",
			Title:   "disk1",
			Size:    10,
			Tier:    upcloud.StorageTierMaxIOPS,
		},
	},
	IPAddresses: []request.CreateServerIPAddress{
		{
			Access: upcloud.IPAddressAccessPrivate,
			Family: upcloud.IPAddressFamilyIPv4,
		},
		{
			Access: upcloud.IPAddressAccessPublic,
			Family: upcloud.IPAddressFamilyIPv4,
		},
		{
			Access: upcloud.IPAddressAccessPublic,
			Family: upcloud.IPAddressFamilyIPv6,
		},
	},
})

if err != nil {
	panic(err)
}

fmt.Println(fmt.Sprintf("Server %s with UUID %s created", serverDetails.Title, serverDetails.UUID))

// Block for up to five minutes until the server has entered the "started" state
err = svc.WaitForServerState(&request.WaitForServerStateRequest{
	UUID:         serverDetails.UUID,
	DesiredState: upcloud.ServerStateStarted,
	Timeout:      time.Minute * 5,
})

if err != nil {
	panic(err)
}

fmt.Println("Server is now started")
Templatizing a server's storage device

In this example, we assume that there is a server represented by the variable serverDetails and that the server state is stopped. The next piece of code allows you to templatize the first storage device of the server.

// Loop through the storage devices
for i, storage := range serverDetails.StorageDevices {
	// Find the first device
	if i == 0 {
		// Templatize the storage
		storageDetails, err := svc.TemplatizeStorage(&request.TemplatizeStorageRequest{
			UUID:  storage.UUID,
			Title: "Templatized storage",
		})

		if err != nil {
			panic(err)
		}

		fmt.Println(fmt.Sprintf("Storage templatized as %s", storageDetails.UUID))
		break
	}
}
Create a manual backup

In this example, we assume that there is a storage device represented by storageDetails and that if it is attached to any server, the server is stopped.

backupDetails, err := svc.CreateBackup(&request.CreateBackupRequest{
	UUID:  storageDetails.UUID,
	Title: "Backup",
})

if err != nil {
    panic(err)
}

fmt.Println(fmt.Sprintf("Backup of %s created as %s", storageDetails.UUID, backupDetails.UUID))
Create a new firewall rule

In this example, we assume that there is a server represented by the variable serverDetails.

firewallRule, err := svc.CreateFirewallRule(&request.CreateFirewallRuleRequest{
	ServerUUID: serverDetails.UUID,
	FirewallRule: upcloud.FirewallRule{
		Direction: upcloud.FirewallRuleDirectionIn,
		Action:    upcloud.FirewallRuleActionAccept,
		Family:    upcloud.IPAddressFamilyIPv4,
		Protocol:  upcloud.FirewallRuleProtocolTCP,
		Position:  1,
		Comment:   "Accept all TCP input on IPv4",
	},
})

if err != nil {
    panic(err)
}

For more examples, please consult the service integration test suite (upcloud/service/service_test.go).

Testing

To be able to run the test suite you'll need to export the following environment variables with their corresponding values:

  • UPCLOUD_GO_SDK_TEST_USER (the API username)
  • UPCLOUD_GO_SDK_TEST_PASSWORD (the API password)
  • UPCLOUD_GO_SDK_TEST_DELETE_RESOURCES (either yes or no)

To run the test suite, run go test ./... -v -parallel 8. If UPCLOUD_GO_SDK_TEST_DELETE_RESOURCES is set to yes, all resources will be stopped and/or deleted after the test suite has run. Be careful which account you use for testing so you don't accidentally delete or your production resources!

You can skip running the integration tests and just run the unit tests by passing -short to the test command.

Debugging

Environment variables UPCLOUD_DEBUG_API_BASE_URL and UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY can be used for HTTP client debugging purposes.

  • UPCLOUD_DEBUG_API_BASE_URL overrides static base URL. This can be used with local server to debug request problems.
    E.g. UPCLOUD_DEBUG_API_BASE_URL=http://127.0.0.1:8080
  • UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY skips server's certificate verification. If set to 1, API client accepts any certificate presented by the server and any host name in that certificate.
    E.g. UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY=1

License

This client is distributed under the MIT License, see LICENSE.txt for more information.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL