github.com/openshift-online/ocm-sdk-go@v0.1.473/README.md (about) 1 # OCM SDK 2 3 [](https://pkg.go.dev/github.com/openshift-online/ocm-sdk-go) 4 [](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.