github.com/openshift-online/ocm-sdk-go@v0.1.473/README.md (about)

     1  # OCM SDK
     2  
     3  [![Go Reference](https://pkg.go.dev/badge/github.com/openshift-online/ocm-sdk-go.svg)](https://pkg.go.dev/github.com/openshift-online/ocm-sdk-go)
     4  [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
     5  
     6  This project contains a Go library that simplifies the use of the _OCM_
     7  API, available in `api.openshift.com`.
     8  
     9  ## Usage
    10  
    11  To use it import the `github.com/openshift-online/ocm-sdk-go` package, and then
    12  use it to send requests to the API.
    13  
    14  Note that the name of the directory is `ocm-sdk-go` but the name of the package
    15  is just `sdk`, so to use it you will have to import it and then use `sdk` as
    16  the package selector.
    17  
    18  For example, if you need to create a cluster you can use the following code:
    19  
    20  ```go
    21  package main
    22  
    23  import (
    24          "fmt"
    25          "os"
    26  
    27          sdk "github.com/openshift-online/ocm-sdk-go"
    28  	cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
    29  )
    30  
    31  func main() {
    32  	// Create a logger that has the debug level enabled:
    33  	logger, err := sdk.NewGoLoggerBuilder().
    34  		Debug(true).
    35  		Build()
    36  	if err != nil {
    37  		fmt.Fprintf(os.Stderr, "Can't build logger: %v\n", err)
    38  		os.Exit(1)
    39  	}
    40  
    41  	// Create the connection, and remember to close it:
    42  	token := os.Getenv("OCM_TOKEN")
    43  	connection, err := sdk.NewConnectionBuilder().
    44  		Logger(logger).
    45  		Tokens(token).
    46  		Build()
    47  	if err != nil {
    48  		fmt.Fprintf(os.Stderr, "Can't build connection: %v\n", err)
    49  		os.Exit(1)
    50  	}
    51  	defer connection.Close()
    52  
    53  	// Get the client for the resource that manages the collection of clusters:
    54  	collection := connection.ClustersMgmt().V1().Clusters()
    55  
    56  	// Prepare the description of the cluster to create:
    57  	cluster, err := cmv1.NewCluster().
    58  		Name("mycluster").
    59  		CloudProvider(
    60  			cmv1.NewCloudProvider().
    61  				ID("aws"),
    62  		).
    63  		Region(
    64  			cmv1.NewCloudRegion().
    65  				ID("us-east-1"),
    66  		).
    67  		Version(
    68  			cmv1.NewVersion().
    69  				ID("openshift-v4.0-beta4"),
    70  		).
    71  		Build()
    72  	if err != nil {
    73  		fmt.Fprintf(os.Stderr, "Can't create cluster description: %v\n", err)
    74  		os.Exit(1)
    75  	}
    76  
    77  	// Send a request to create the cluster:
    78  	response, err := collection.Add().
    79  		Body(cluster).
    80  		Send()
    81  	if err != nil {
    82  		fmt.Fprintf(os.Stderr, "Can't create cluster: %v\n", err)
    83  		os.Exit(1)
    84  	}
    85  
    86  	// Print the result:
    87  	cluster = response.Body()
    88  	fmt.Printf("%s - %s\n", cluster.ID(), cluster.Name())
    89  }
    90  ```
    91  
    92  There are more examples in the [examples](examples) directory.
    93  
    94  ### Packages
    95  
    96  The following are the packages that are most frequently needed in order to use
    97  the SDK:
    98  
    99  **main**
   100  
   101  This is the top level package. The most important element is the `Connection`
   102  type, as it is the mechanism to connect to the server and to get the reference
   103  to the clients for the services that are part of the API.
   104  
   105  **errors**
   106  
   107  Contains the `Error` type that is used by the SDK to report errors.
   108  
   109  **accesstransparency/v1** 
   110  
   111  This package contains the types and clients for version 1 of the access
   112  transparency service.
   113  
   114  **accountsmgmt/v1**
   115  
   116  This package contains the types and clients for version 1 of the accounts
   117  management service.
   118  
   119  **authorizations/v1**
   120  
   121  This package contains the types and clients for version 1 of the
   122  authorizations service.
   123  
   124  **clustersmgmt/v1**
   125  
   126  This package contains the types and clients for version 1 of the clusters
   127  management service.
   128  
   129  There are other packages, like `helpers` and `internal`.  Those contain
   130  internal implementation details of the SDK. Refrain from using them, as they
   131  may change in the future: backwards compatibility isn't guaranteed.
   132  
   133  ### Connecting to the server
   134  
   135  To connect to the server import the `sdk` package. That contains the
   136  `Connection` type, which is the entry point of the SDK, and gives you access to
   137  the clients for the services that are part of the API:
   138  
   139  ```go
   140  import (
   141  	"github.com/openshift-online/ocm-sdk-go"
   142  )
   143  
   144  // Create the connection:
   145  connection, err := sdk.NewConnectionBuilder().
   146  	Tokens(token).
   147  	Build()
   148  if err != nil {
   149          fmt.Fprintf(os.Stderr, "Can't build connection: %v\n", err)
   150          os.Exit(1)
   151  }
   152  ```
   153  
   154  The connection holds expensive resources, including a pool of HTTP connections
   155  to the server and an authentication token. It is important to release those
   156  resources when they are no longer in use:
   157  
   158  ```go
   159  // Close the connection:
   160  connection.Close()
   161  ```
   162  
   163  Consider using the _defer_ mechanism to ensure that the connection is always
   164  closed when no longer needed.
   165  
   166  ### Using _types_
   167  
   168  The Go types that correspond to the API data types live in the
   169  `accountsmgmt/v1`, `authorizations/v1`, and `clustersmgmt/v1` packages. These types are pure data
   170  containers, they don't have any logic or operation.  Instances can be created
   171  at will.
   172  
   173  Creation of objects of these types does *not* have any effect in the server
   174  side, unless the object is explicitly passed to a call to one of the resource
   175  methods described below. Changes in the server side are *not* automatically
   176  reflected in the instances that already exist in memory.
   177  
   178  Creation of objects of these types is done using the corresponding _builder_
   179  type. For example, to create an object of the `Cluster` type create an object of
   180  the `ClusterBuilder` type (using the `NewCluster` function) populate and then
   181  build the object calling the `Build` method:
   182  
   183  ```go
   184  // Create a new object of the `Cluster` type:
   185  cluster, err := cmv1.NewCluster().
   186  	Name("mycluster").
   187  	CloudProvider(
   188  		cmv1.NewCloudProvider().
   189  			ID("aws"),
   190  	).
   191  	Region(
   192  		cmv1.NewCloudRegion().
   193  			ID("us-east-1"),
   194  	).
   195  	Version(
   196  		cmv1.NewVersion().
   197  			ID("openshift-v4.9.7"),
   198  	).
   199  	Build()
   200  if err != nil {
   201  	fmt.Fprintf(os.Stderr, "Can't create cluster object: %v\n", err)
   202  	os.Exit(1)
   203  }
   204  ```
   205  
   206  Once created objects are immutable.
   207  
   208  The fields containing the values of the attributes of these types are private.
   209  To read them use the _access methods_. For example, to read the value of the
   210  `name` attribute of a cluster:
   211  
   212  ```go
   213  // Get the value of the `name` attribute:
   214  name := cluster.Name()
   215  fmt.Printf("Cluster name is '%s'\n", name)
   216  ```
   217  
   218  The access methods return the value of the attribute, if it has a value, or the
   219  zero value of the type (`""` for strings, `false` for booleans, `0` for
   220  integers, etc) if the attribute doesn't have a value. That makes it impossible
   221  to know if the attribute has a value or not. If you need that, use the `Get...`
   222  variant of the accessor. For example, to get the value of the `name` attribute
   223  and also check if the attribute has a value:
   224  
   225  ```go
   226  // Get the value of the `name` attribute, and check if it has a value:
   227  name, ok := cluster.GetName()
   228  if !ok {
   229  	fmt.Printf("Cluster has no name\n")
   230  } else {
   231  	fmt.Printf("Cluster name is '%s'\n", name)
   232  }
   233  ```
   234  
   235  Attributes that are defined as list of objects in the specification of the API
   236  are implemented as objects of a `...List` type. For example, the value of the
   237  `groups` attribute of the `Cluster` type is implemented as the `GroupList` type.
   238  These list types provide methods to process the elements of the list. For
   239  example, to print the names of a list of groups:
   240  
   241  ```go
   242  // Get the list of groups:
   243  groups := ...
   244  
   245  // Print the name of each group:
   246  groups.Each(func(group *cmv1.Group) bool {
   247  	fmt.Printf("Group name is '%s'\n", group.Name())
   248  	return true
   249  })
   250  ```
   251  
   252  The function passed to the `Each` method will be called once for each item of
   253  the list. If it returns `true` the iteration will continue, otherwise will stop.
   254  This is intended to mimic a `for` loop with an optional `break`.
   255  
   256  If it is necessary to have access to the index of the item, then it is better to
   257  use the `Range` method:
   258  
   259  ```go
   260  // Get the list of groups:
   261  groups := ...
   262  
   263  // Print index and name of each group:
   264  groups.Range(func(int i, group *cmv1.Group) bool {
   265  	fmt.Printf("Group index is %d and is '%s'\n", i, group.Name())
   266  	return true
   267  })
   268  ```
   269  
   270  It is also possible to convert the list to an slice, using the `Slice` method,
   271  and the process it as usual:
   272  
   273  ```go
   274  // Get the list of groups:
   275  groups := ...
   276  
   277  // Print the name of each group:
   278  slice := groups.Slice()
   279  for _, group := range slice {
   280  	fmt.Printf("Group name is '%s'\n", group.Name())
   281  }
   282  ```
   283  
   284  It is in general better to use the `Each` or `Range` methods instead of the
   285  `Slice` method, because `Slice` has the additional cost of allocating that slice
   286  and copying the internal representation into it.
   287  
   288  ## CLI
   289  
   290  See also the command-line tool https://github.com/openshift-online/ocm-cli built
   291  on top of this SDK.
   292  
   293  ## FedRAMP
   294  
   295  The OCM SDK fully supports the OCM FedRAMP environment. Additional `TokenURL`, `URL`, and `Client` configuration is required in order to make the connection. An example implementation for the OCM FedRAMP environment can be found in the [examples](examples/fedramp_auth.go) directory.