ocm-sdk-go

module
v0.1.21 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2019 License: Apache-2.0

README

= UHC SDK

ifdef::env-github[]
image:https://godoc.org/github.com/openshift-online/uhc-sdk-go?status.svg[GoDoc,
link=https://godoc.org/github.com/openshift-online/uhc-sdk-go/pkg/client]
image:https://img.shields.io/badge/License-Apache%202.0-blue.svg[License,
link=https://opensource.org/licenses/Apache-2.0]
endif::[]

This project contains a Go library that simplifies the use of the _UHC_
API, available in `api.openshift.com`.

== Usage

To use it import the `github.com/openshift-online/uhc-sdk-go/pkg/client` package,
and then use it to send requests to the API. For example, if you need to create
a cluster you can use the following code:

[source,go]
----
package main

import (
        "fmt"
        "os"

        "github.com/openshift-online/uhc-sdk-go/pkg/client"
	"github.com/openshift-online/uhc-sdk-go/pkg/client/clustersmgmt/v1"
)

func main() {
	// Create a logger that has the debug level enabled:
	logger, err := client.NewGoLoggerBuilder().
		Debug(true).
		Build()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Can't build logger: %v\n", err)
		os.Exit(1)
	}

	// Create the connection, and remember to close it:
	token := os.Getenv("UHC_TOKEN")
	connection, err := client.NewConnectionBuilder().
		Logger(logger).
		Tokens(token).
		Build()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Can't build connection: %v\n", err)
		os.Exit(1)
	}
	defer connection.Close()

	// Get the client for the resource that manages the collection of clusters:
	collection := connection.ClustersMgmt().V1().Clusters()

	// Prepare the description of the cluster to create:
	cluster, err := v1.NewCluster().
		Name("mycluster").
		Flavour(
			v1.NewFlavour().
				ID("4"),
		).
		Region(
			v1.NewCloudRegion().
				ID("us-east-1"),
		).
		DNS(
			v1.NewDNS().
				BaseDomain("example.com"),
		).
		AWS(
			v1.NewAWS().
				AccessKeyID("...").
				SecretAccessKey("..."),
		).
		Version(
			v1.NewVersion().
				ID("openshift-v4.0-beta4"),
		).
		Build()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Can't create cluster description: %v\n", err)
		os.Exit(1)
	}

	// Send a request to create the cluster:
	response, err := collection.Add().
		Body(cluster).
		Send()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Can't create cluster: %v\n", err)
		os.Exit(1)
	}

	// Print the result:
	cluster = response.Body()
	fmt.Printf("%s - %s\n", cluster.ID(), cluster.Name())
}
----

There are more examples in the link:examples[examples] directory.

=== Packages

The following are the packages that are most frequently needed in order to use
the SDK:

pkg/client::

This is the top level package. The most important element is the `Connection`
type, as it is the mechanism to connect to the server and to get the reference
to the clients for the services that are part of the API.

pkg/client/errors::

Contains the `Error` type that is used by the SDK to report errors.

pkg/client/accountsmgmt/v1::

This package contains the types and clients for version 1 of the accounts
management service.

pkg/client/clustersmgmt/v1::

This package contains the types and clients for version 1 of the clusters
management service.

There are other packages, like `pkg/client/helpers` and `pkg/client/internal`.
Those contain internal implementation details of the SDK. Refrain from using
them, as they may change in the future: backwards compatibility isn't guaranteed.

=== Connecting to the server

To connect to the server import the `pkg/client` package. That contains the
`Connection` type, which is the entry point of the SDK, and gives you access to
the clients for the services that are part of the API:

[source,go]
----
import (
	"github.com/openshift-online/pkg/client"
)

// Create the connection:
connection, err := client.NewConnectionBuilder().
	Tokens(token).
	Build()
if err != nil {
        fmt.Fprintf(os.Stderr, "Can't build client: %v\n", err)
        os.Exit(1)
}
----

The connection holds expensive resources, including a pool of HTTP connections
to the server and an authentication token. It is important to release those
resources whey they are no longer in use:

[source,go]
----
// Close the connection:
connection.Close()
----

Consider using the _defer_ mechanism to ensure that the connection is always
closed when no longer needed.

=== Using _types_

The Go types that correspond to the API data types live in the
`pkg/client/accountsmgmt/v1` and `pkg/client/clustersmgmt/v1` packages. These
types are pure data containers, they don't have any logic or operation.
Instances can be created at will.

Creating of objects of these types does *not* have any effect in the server
side, unless the object is explicitly passed to a call to one of the resource
methods described below. Changes in the server side are *not* automatically
reflected in the instances that already exist in memory.

Creation of objects of these types is done using the corresponding _builder_
type. For example, to create an object of the `Cluster` type create an object of
the `ClusterBuilder` type (using the `NewCluster` function) populate and then
build the object calling the `Build` method:

[source,go]
----
// Create a new object of the `Cluster` type:
cluster, err := v1.NewCluster().
	Name("mycluster").
	Flavour(
		v1.NewFlavour().
			ID("4"),
	).
	Region(
		v1.NewCloudRegion().
			ID("us-east-1"),
	).
	DNS(
		v1.NewDNS().
			BaseDomain("example.com"),
	).
	AWS(
		v1.NewAWS().
			AccessKeyID("...").
			SecretAccessKey("..."),
	).
	Version(
		v1.NewVersion().
			ID("openshift-v4.0-beta4"),
	).
	Build()
if err != nil {
	fmt.Fprintf(os.Stderr, "Can't create cluster object: %v\n", err)
	os.Exit(1)
}
----

Once created objects are immutable.

The fields containing the values of the attributes of these types are private.
To read them use the _access methods_. For example, to read the value of the
`name` attribute of a cluster:

[source,go]
----
// Get the value of the `name` attribute:
name := cluster.Name()
fmt.Printf("Cluster name is '%s'\n", name)
----

The access methods return the value of the attribute, if it has a value, or the
zero value of the type (`""` for strings, `false` for booleans, `0` for
integers, etc) if the attribute doesn't have a value. That makes it impossible
to know if the attribute has a value or not. If you need that, use the `Get...`
variant of the accessor. For example, to get the value of the `name` attribute
and also check if the attribute has a value:

[source,go]
----
// Get the value of the `name` attribute, and check if it has a value:
name, ok := cluster.GetName()
if !ok {
	fmt.Printf("Cluster has no name\n")
} else {
	fmt.Printf("Cluster name is '%s'\n", name)
}
----

Attributes that are defined as list of objects in the specification of the API
are implemented as objects of a `...List` type. For example, the value of the
`groups` attribute of the `Cluster` type is implemented as the `GroupList` type.
These list types provide methods to process the elements of the list. For
example, to print the names of a list of groups:

[source,go]
----
// Get the list of groups:
groups := ...

// Print the name of each group:
groups.Each(func(group *v1.Group) bool {
	fmt.Printf("Group name is '%s'\n", group.Name())
	return true
})
----

The function passed to the `Each` method will be called once for each item of
the list. If it returns `true` the iteration will continue, otherwise will stop.
This is intended to mimic a `for` loop with an optional `break`.

If it is necessary to have access to the index of the item, then it is better to
use the `Range` method:

[source,go]
----
// Get the list of groups:
groups := ...

// Print index and name of each group:
groups.Range(func(int i, group *v1.Group) bool {
	fmt.Printf("Group index is %d and is '%s'\n", i, group.Name())
	return true
})
----

It is also possible to convert the list to an slice, using the `Slice` method,
and the process it as usual:

[source,go]
----
// Get the list of groups:
groups := ...

// Print the name of each group:
slice := groups.Slice()
for _, group := range slice {
	fmt.Printf("Group name is '%s'\n", group.Name())
}
----

It is in general better to use the `Each` or `Range` methods instead of the
`Slice` method, because `Slice` has the additional cost of allocating that slice
and copying the internal representation into it.

== CLI

See also the command-line tool https://github.com/openshift-online/uhc-cli built
on top of this SDK.

Directories

Path Synopsis
pkg
client
Package client contains a set of objects that simplify usage of `api.openshift.com`.
Package client contains a set of objects that simplify usage of `api.openshift.com`.

Jump to

Keyboard shortcuts

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