|
1 | 1 |
|
2 | 2 | /*
|
3 |
| -Package oci This is a preview of the official go sdk for Oracle Cloud Infrastructure |
| 3 | +This is the official Go SDK for Oracle Cloud Infrastructure |
4 | 4 |
|
5 |
| - To avoid breaking changes please consider using https://github.com/golang/dep, or vendoring this sdk. |
6 |
| - Although we make a conscious effort to not push breaking changes, sometimes they are needed. This is particularly true at the current stage |
7 |
| - of development. |
| 5 | +Installation |
8 | 6 |
|
9 |
| -Working with the SDK |
| 7 | +Refer to https://github.com/oracle/oci-go-sdk/blob/master/README.md#installing for installation instructions. |
10 | 8 |
|
11 |
| -Generally speaking, you can start working with the sdk by importing the service package, creating a client, |
12 |
| -and making calls with client. |
| 9 | +Configuration |
13 | 10 |
|
14 |
| -Configuring |
| 11 | +Refer to https://github.com/oracle/oci-go-sdk/blob/master/README.md#configuring for configuration instructions. |
15 | 12 |
|
16 |
| -You can configure the sdk with your credentials by creating a settings file in: $HOME/.oci/config that looks like the following: |
17 |
| - [DEFAULT] |
18 |
| - user=[user ocid] |
19 |
| - fingerprint=[fingerprint] |
20 |
| - key_file=[path to pem file containing private key] |
21 |
| - tenancy=[tenancy ocid] |
22 |
| - region=[region for your tenancy] |
| 13 | +Quickstart |
23 | 14 |
|
24 |
| -and calling the common.DefaultConfigProvider() function like so: |
| 15 | +The following example shows how to get started with the SDK. The example belows creates an identityClient |
| 16 | +struct with the default configuration. It then utilizes the identityClient to list availability domains and prints |
| 17 | +them out to stdout |
| 18 | +
|
| 19 | + import ( |
| 20 | + "context" |
| 21 | + "fmt" |
25 | 22 |
|
26 |
| - // Do not forget to import the necessary packages |
27 |
| - import ( |
28 | 23 | "github.com/oracle/oci-go-sdk/common"
|
29 |
| - "github.com/oracle/oci-go-sdk/identity" // Identity or any other service you wish to call |
| 24 | + "github.com/oracle/oci-go-sdk/identity" |
30 | 25 | )
|
31 | 26 |
|
32 |
| - configProvider := common.DefaultConfigProvider() |
| 27 | + func main() { |
| 28 | + c, err := identity.NewIdentityClientWithConfigurationProvider(common.DefaultConfigProvider()) |
| 29 | + if err != nil { |
| 30 | + fmt.Println("Error:", err) |
| 31 | + return |
| 32 | + } |
| 33 | +
|
| 34 | + // The OCID of the tenancy containing the compartment. |
| 35 | + tenancyID, err := common.DefaultConfigProvider().TenancyOCID() |
| 36 | + if err != nil { |
| 37 | + fmt.Println("Error:", err) |
| 38 | + return |
| 39 | + } |
| 40 | +
|
| 41 | + request := identity.ListAvailabilityDomainsRequest{ |
| 42 | + CompartmentId: &tenancyID, |
| 43 | + } |
| 44 | +
|
| 45 | + r, err := c.ListAvailabilityDomains(context.Background(), request) |
| 46 | + if err != nil { |
| 47 | + fmt.Println("Error:", err) |
| 48 | + return |
| 49 | + } |
| 50 | +
|
| 51 | + fmt.Printf("List of available domains: %v", r.Items) |
| 52 | + return |
| 53 | + } |
| 54 | +
|
| 55 | +More examples can be found in the SDK Github repo: https://github.com/oracle/oci-go-sdk/tree/master/example |
| 56 | +
|
| 57 | +Optional fields in the SDK |
| 58 | +
|
| 59 | +Optional fields are represented with the `mandatory:"false"` tag on input structs. The SDK will omit all optional fields that are nil when making requests. |
| 60 | +In the case of enum-type fields, the SDK will omit fields whose value is an empty string. |
| 61 | +
|
| 62 | +Helper functions |
| 63 | +
|
| 64 | +The SDK uses pointers for primitive types in many input structs. To aid in the construction of such structs, the SDK provides |
| 65 | +functions that return a pointer for a given value. For example: |
| 66 | +
|
| 67 | + // Given the struct |
| 68 | + type CreateVcnDetails struct { |
33 | 69 |
|
34 |
| -You can also configure the sdk programmatically by implementing the `ConfigurationProvider` interface |
35 |
| - // ConfigurationProvider wraps information about the account owner |
36 |
| - type ConfigurationProvider interface { |
37 |
| - KeyProvider |
38 |
| - TenancyOCID() (string, error) |
39 |
| - UserOCID() (string, error) |
40 |
| - KeyFingerprint() (string, error) |
41 |
| - Region() (string, error) |
| 70 | + // Example: `172.16.0.0/16` |
| 71 | + CidrBlock *string `mandatory:"true" json:"cidrBlock"` |
| 72 | +
|
| 73 | + CompartmentId *string `mandatory:"true" json:"compartmentId"` |
| 74 | +
|
| 75 | + DisplayName *string `mandatory:"false" json:"displayName"` |
| 76 | +
|
| 77 | + } |
| 78 | +
|
| 79 | + // We can use the helper functions to build the struct |
| 80 | + details := core.CreateVcnDetails{ |
| 81 | + CidrBlock: common.String("172.16.0.0/16"), |
| 82 | + CompartmentId: common.String("someOcid"), |
| 83 | + DisplayName: common.String("myVcn"), |
42 | 84 | }
|
43 | 85 |
|
44 | 86 |
|
45 |
| -Making a request |
| 87 | +Signing custom requests |
46 | 88 |
|
47 |
| -Making request can be achieved by: creating a client for the service that you wish to work with, followed by calling |
48 |
| -the a function in the above client |
49 |
| -- Creating a client: all packages provide a function to create clients. It is of the form `NewXXXClientWithConfigurationProvider`. |
50 |
| -You can create a new client by passing a struct that conforms to the `ConfigurationProvider` interface. |
51 |
| -Here is a quick example that shows how to create a client |
52 |
| - config := common.DefaultConfigProvider() |
53 |
| - client, err := identity.NewIdentityClientWithConfigurationProvider(config) |
54 |
| - if err != nil { |
55 |
| - panic(err) |
| 89 | +The SDK exposes a stand-alone signer that can be used to signing custom requests. Related code can be found here: |
| 90 | +https://github.com/oracle/oci-go-sdk/blob/master/common/http_signer.go. |
| 91 | +
|
| 92 | +The example below shows how to create a default signer. |
| 93 | +
|
| 94 | + client := http.Client{} |
| 95 | + var request http.Request |
| 96 | + request = ... // some custom request |
| 97 | +
|
| 98 | + // Set the Date header |
| 99 | + request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) |
| 100 | +
|
| 101 | + // And a provider of cryptographic keys |
| 102 | + provider := common.DefaultConfigProvider() |
| 103 | +
|
| 104 | + // Build the signer |
| 105 | + signer := common.DefaultSigner(provider) |
| 106 | +
|
| 107 | + // Sign the request |
| 108 | + signer.Sign(&request) |
| 109 | +
|
| 110 | + // Execute the request |
| 111 | + client.Do(request) |
| 112 | +
|
| 113 | +
|
| 114 | +
|
| 115 | +The signer also allows more granular control on the headers used for signing. For example: |
| 116 | +
|
| 117 | + client := http.Client{} |
| 118 | + var request http.Request |
| 119 | + request = ... // some custom request |
| 120 | +
|
| 121 | + // Set the Date header |
| 122 | + request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) |
| 123 | +
|
| 124 | + // Mandatory headers to be used in the sign process |
| 125 | + defaultGenericHeaders = []string{"date", "(request-target)", "host"} |
| 126 | +
|
| 127 | + // Optional headers |
| 128 | + optionalHeaders = []string{"content-length", "content-type", "x-content-sha256"} |
| 129 | +
|
| 130 | + // A predicate that specifies when to use the optional signing headers |
| 131 | + optionalHeadersPredicate := func (r *http.Request) bool { |
| 132 | + return r.Method == http.MethodPost |
56 | 133 | }
|
57 | 134 |
|
58 |
| -- Making calls: after successfully creating client, you can now make calls to the service. Generally all operations |
59 |
| -functions take in a context.Context (https://golang.org/pkg/context/) and a struct that wraps all input parameters. The return is usually a response struct |
60 |
| -containing the desired data, and an error struct describing the error if there was one, eg: |
61 |
| - response, err := client.GetGroup(context.Background(), identity.GetGroupRequest{GroupId:id}) |
| 135 | + // And a provider of cryptographic keys |
| 136 | + provider := common.DefaultConfigProvider() |
| 137 | +
|
| 138 | + // Build the signer |
| 139 | + signer := common.RequestSigner(provider, defaultGenericHeaders, optionalHeaders, optionalHeadersPredicate) |
| 140 | +
|
| 141 | + // Sign the request |
| 142 | + signer.Sign(&request) |
| 143 | +
|
| 144 | + // Execute the request |
| 145 | + c.Do(request) |
| 146 | +
|
| 147 | +For more information on the signing algorithm refer to: https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/signingrequests.htm |
| 148 | +
|
| 149 | +Polymorphic json requests and responses |
| 150 | +
|
| 151 | +Some operations accept or return polymorphic json objects. The SDK models such objects as interfaces. Further the SDK provides |
| 152 | +structs that implement such interfaces. Thus, for all operations that expect interfaces as input, pass the struct in the SDK that satisfies |
| 153 | +such interface. For example: |
| 154 | +
|
| 155 | + c, err := identity.NewIdentityClientWithConfigurationProvider(common.DefaultConfigProvider()) |
62 | 156 | if err != nil {
|
63 |
| - //Something happened |
64 | 157 | panic(err)
|
65 | 158 | }
|
66 |
| - //Process the data in response struct |
67 |
| - fmt.Println("Group's name is:", response.Name) |
68 | 159 |
|
69 |
| -Organization of the SDK |
| 160 | + // The CreateIdentityProviderRequest takes a CreateIdentityProviderDetails interface as input |
| 161 | + rCreate := identity.CreateIdentityProviderRequest{} |
| 162 | +
|
| 163 | + // The CreateSaml2IdentityProviderDetails struct implements the CreateIdentityProviderDetails interface |
| 164 | + details := identity.CreateSaml2IdentityProviderDetails{} |
| 165 | + details.CompartmentId = common.String(getTenancyID()) |
| 166 | + details.Name = common.String("someName") |
| 167 | + //... more setup if needed |
| 168 | + // Use the above struct |
| 169 | + rCreate.CreateIdentityProviderDetails = details |
| 170 | +
|
| 171 | + // Make the call |
| 172 | + rspCreate, createErr := c.CreateIdentityProvider(context.Background(), rCreate) |
| 173 | +
|
| 174 | +In the case of a polymorphic response you can type assert the interface to the expected type. For example: |
| 175 | +
|
| 176 | + rRead := identity.GetIdentityProviderRequest{} |
| 177 | + rRead.IdentityProviderId = common.String("aValidId") |
| 178 | + response, err := c.GetIdentityProvider(context.Background(), rRead) |
| 179 | +
|
| 180 | + provider := response.IdentityProvider.(identity.Saml2IdentityProvider) |
| 181 | +
|
| 182 | +An example of polymorphic json request handling can be found here: https://github.com/oracle/oci-go-sdk/blob/master/example/example_core_test.go#L63 |
| 183 | +
|
| 184 | +
|
| 185 | +Pagination |
| 186 | +
|
| 187 | +When calling a list operation, the operation will retrieve a page of results. To retrieve more data, call the list operation again, |
| 188 | +passing in the value of the most recent response's OpcNextPage as the value of Page in the next list operation call. |
| 189 | +When there is no more data the OpcNextPage field will be nil. An example of pagination using this logic can be found here: https://github.com/oracle/oci-go-sdk/blob/master/example/example_core_test.go#L86 |
| 190 | +
|
| 191 | +Logging and Debugging |
| 192 | +
|
| 193 | +The SDK has a built-in logging mechanism used internally. The internal logging logic is used to record the raw http |
| 194 | +requests, responses and potential errors when (un)marshalling request and responses. |
| 195 | +
|
| 196 | +To expose debugging logs, set the environment variable "OCI_GO_SDK_DEBUG" to "1", or some other non empty string. |
| 197 | +
|
| 198 | +
|
| 199 | +Forward Compatibility |
| 200 | +
|
| 201 | +Some response fields are enum-typed. In the future, individual services may return values not covered by existing enums |
| 202 | +for that field. To address this possibility, every enum-type response field is a modeled as a type that supports any string. |
| 203 | +Thus if a service returns a value that is not recognized by your version of the SDK, then the response field will be set to this value. |
| 204 | +
|
| 205 | +When individual services return a polymorphic json response not available as a concrete struct, the SDK will return an implementation that only satisfies |
| 206 | +the interface modeling the polymorphic json response. |
| 207 | +
|
| 208 | +
|
| 209 | +Contributions |
| 210 | +
|
| 211 | +Got a fix for a bug, or a new feature you'd like to contribute? The SDK is open source and accepting pull requests on GitHub |
| 212 | +https://github.com/oracle/oci-go-sdk |
| 213 | +
|
| 214 | +License |
| 215 | +
|
| 216 | +Licensing information available at: https://github.com/oracle/oci-go-sdk/blob/master/LICENSE.txt |
| 217 | +
|
| 218 | +Notifications |
| 219 | +
|
| 220 | +To be notified when a new version of the Go SDK is released, subscribe to the following feed: https://github.com/oracle/oci-go-sdk/releases.atom |
| 221 | +
|
| 222 | +Questions or Feedback |
| 223 | +
|
| 224 | +Please refer to this link: https://github.com/oracle/oci-go-sdk#help |
70 | 225 |
|
71 |
| -The oci-go-sdk is broken down into: |
72 | 226 |
|
73 |
| -- service packages: all packages except `common` and any other package found inside `cmd`. They represent Oracle Cloud Infrastructure services supported by the go sdk. |
74 |
| -Each package represents a service. These packages include methods to interact with the service, structs that model |
75 |
| -input and output parameters and a client struct that acts as receiver for the above methods. All code in these packages |
76 |
| -is machine generated. |
77 | 227 |
|
78 |
| -- common package: found in the `common` directory. The common package provides supporting functions and structs used by service packages, |
79 |
| -including: http request/response (de)serialization, request signing, json parsing, pointer to reference and other helper functions. Thought |
80 |
| -there are some functions in this package that are meant for user consumption, most of them are meant to be used by the service packages. |
81 | 228 |
|
82 |
| -- cmd: internal tools used by the `oci-go-sdk` |
83 | 229 | */
|
84 | 230 | package oci
|
85 | 231 |
|
|
0 commit comments