@@ -11,12 +11,16 @@ import (
1111 "net/http"
1212 "os"
1313 "runtime"
14+ "strconv"
15+ "strings"
1416 "time"
1517
1618 "github.com/hashicorp/terraform/helper/schema"
19+ "github.com/hashicorp/terraform/helper/validation"
1720 "github.com/hashicorp/terraform/terraform"
1821
1922 oci_common "github.com/oracle/oci-go-sdk/common"
23+ oci_common_auth "github.com/oracle/oci-go-sdk/common/auth"
2024 oci_core "github.com/oracle/oci-go-sdk/core"
2125 oci_database "github.com/oracle/oci-go-sdk/database"
2226 oci_identity "github.com/oracle/oci-go-sdk/identity"
@@ -28,21 +32,31 @@ var descriptions map[string]string
2832var disableAutoRetries bool
2933
3034const (
31- defaultRequestTimeout = 0
32- defaultConnectionTimeout = 10 * time .Second
33- defaultTLSHandshakeTimeout = 5 * time .Second
35+ authAPIKeySetting = "ApiKey"
36+ authInstancePrincipalSetting = "InstancePrincipal"
37+ defaultRequestTimeout = 0
38+ defaultConnectionTimeout = 10 * time .Second
39+ defaultTLSHandshakeTimeout = 5 * time .Second
40+ userAgentFormatter = "Oracle-GoSDK/%s (go/%s; %s/%s; terraform/%s) Oracle-TerraformProvider/%s"
3441)
3542
43+ type oboTokenProviderFromEnv struct {}
44+
45+ func (p oboTokenProviderFromEnv ) OboToken () (string , error ) {
46+ return getEnvSetting ("obo_token" , "" ), nil
47+ }
48+
3649func init () {
3750 descriptions = map [string ]string {
38- "tenancy_ocid" : "(Required) The tenancy OCID for a user. The tenancy OCID can be found at the bottom of user settings in the Oracle Cloud Infrastructure console." ,
39- "user_ocid" : "(Required) The user OCID. This can be found in user settings in the Oracle Cloud Infrastructure console." ,
40- "fingerprint" : "(Required) The fingerprint for the user's RSA key. This can be found in user settings in the Oracle Cloud Infrastructure console." ,
51+ "auth" : fmt .Sprintf ("(Optional) The type of auth to use. Options are '%s' and '%s'. By default, '%s' will be used." , authAPIKeySetting , authInstancePrincipalSetting , authAPIKeySetting ),
52+ "tenancy_ocid" : fmt .Sprintf ("(Optional) The tenancy OCID for a user. The tenancy OCID can be found at the bottom of user settings in the Oracle Cloud Infrastructure console. Required if auth is set to '%s', ignored otherwise." , authAPIKeySetting ),
53+ "user_ocid" : fmt .Sprintf ("(Optional) The user OCID. This can be found in user settings in the Oracle Cloud Infrastructure console. Required if auth is set to '%s', ignored otherwise." , authAPIKeySetting ),
54+ "fingerprint" : fmt .Sprintf ("(Optional) The fingerprint for the user's RSA key. This can be found in user settings in the Oracle Cloud Infrastructure console. Required if auth is set to '%s', ignored otherwise." , authAPIKeySetting ),
4155 "region" : "(Required) The region for API connections (e.g. us-ashburn-1)." ,
4256 "private_key" : "(Optional) A PEM formatted RSA private key for the user.\n " +
43- "A private_key or a private_key_path must be provided." ,
57+ fmt . Sprintf ( "A private_key or a private_key_path must be provided if auth is set to '%s', ignored otherwise." , authAPIKeySetting ) ,
4458 "private_key_path" : "(Optional) The path to the user's PEM formatted private key.\n " +
45- "A private_key or a private_key_path must be provided." ,
59+ fmt . Sprintf ( "A private_key or a private_key_path must be provided if auth is set to '%s', ignored otherwise." , authAPIKeySetting ) ,
4660 "private_key_password" : "(Optional) The password used to secure the private key." ,
4761 "disable_auto_retries" : "(Optional) Disable Automatic retries for retriable errors.\n " +
4862 "Auto retries were introduced to solve some eventual consistency problems but it also introduced performance issues on destroy operations." ,
@@ -61,21 +75,28 @@ func Provider(configfn schema.ConfigureFunc) terraform.ResourceProvider {
6175
6276func schemaMap () map [string ]* schema.Schema {
6377 return map [string ]* schema.Schema {
78+ "auth" : {
79+ Type : schema .TypeString ,
80+ Optional : true ,
81+ Description : descriptions ["auth" ],
82+ DefaultFunc : schema .EnvDefaultFunc ("OCI_AUTH" , authAPIKeySetting ),
83+ ValidateFunc : validation .StringInSlice ([]string {authAPIKeySetting , authInstancePrincipalSetting }, true ),
84+ },
6485 "tenancy_ocid" : {
6586 Type : schema .TypeString ,
66- Required : true ,
87+ Optional : true ,
6788 Description : descriptions ["tenancy_ocid" ],
6889 DefaultFunc : schema .EnvDefaultFunc ("OCI_TENANCY_OCID" , nil ),
6990 },
7091 "user_ocid" : {
7192 Type : schema .TypeString ,
72- Required : true ,
93+ Optional : true ,
7394 Description : descriptions ["user_ocid" ],
7495 DefaultFunc : schema .EnvDefaultFunc ("OCI_USER_OCID" , nil ),
7596 },
7697 "fingerprint" : {
7798 Type : schema .TypeString ,
78- Required : true ,
99+ Optional : true ,
79100 Description : descriptions ["fingerprint" ],
80101 DefaultFunc : schema .EnvDefaultFunc ("OCI_FINGERPRINT" , nil ),
81102 },
@@ -246,12 +267,22 @@ func getRequiredEnvSetting(s string) string {
246267 return v
247268}
248269
270+ func validateConfigForAPIKeyAuth (d * schema.ResourceData ) error {
271+ _ , hasTenancyOCID := d .GetOkExists ("tenancy_ocid" )
272+ _ , hasUserOCID := d .GetOkExists ("user_ocid" )
273+ _ , hasFingerprint := d .GetOkExists ("fingerprint" )
274+ if ! hasTenancyOCID || ! hasUserOCID || ! hasFingerprint {
275+ return fmt .Errorf ("when auth is set to '%s', tenancy_ocid, user_ocid, and fingerprint are required" , authAPIKeySetting )
276+ }
277+ return nil
278+ }
279+
249280func ProviderConfig (d * schema.ResourceData ) (clients interface {}, err error ) {
250281 clients = & OracleClients {}
251282 disableAutoRetries = d .Get ("disable_auto_retries" ).(bool )
283+ auth := strings .ToLower (d .Get ("auth" ).(string ))
252284
253- userAgent := fmt .Sprintf ("Oracle-GoSDK/%s (go/%s; %s/%s; terraform/%s) Oracle-TerraformProvider/%s" ,
254- oci_common .Version (), runtime .Version (), runtime .GOOS , runtime .GOARCH , terraform .VersionString (), Version )
285+ userAgent := fmt .Sprintf (userAgentFormatter , oci_common .Version (), runtime .Version (), runtime .GOOS , runtime .GOARCH , terraform .VersionString (), Version )
255286
256287 httpClient := & http.Client {
257288 Timeout : defaultRequestTimeout ,
@@ -265,14 +296,31 @@ func ProviderConfig(d *schema.ResourceData) (clients interface{}, err error) {
265296 },
266297 }
267298
268- tfConfigProvider := ResourceDataConfigProvider {d }
299+ var configProviders []oci_common.ConfigurationProvider
300+
301+ switch auth {
302+ case strings .ToLower (authAPIKeySetting ):
303+ if err := validateConfigForAPIKeyAuth (d ); err != nil {
304+ return nil , err
305+ }
306+ case strings .ToLower (authInstancePrincipalSetting ):
307+ cfg , err := oci_common_auth .InstancePrincipalConfigurationProvider ()
308+ if err != nil {
309+ return nil , err
310+ }
311+ configProviders = append (configProviders , cfg )
312+ default :
313+ return nil , fmt .Errorf ("auth must be one of '%s' or '%s'" , authAPIKeySetting , authInstancePrincipalSetting )
314+ }
315+
316+ configProviders = append (configProviders , ResourceDataConfigProvider {d })
269317
270318 // TODO: DefaultConfigProvider will return us a composingConfigurationProvider that reads from SDK config files,
271319 // and then from the environment variables ("TF_VAR" prefix). References to "TF_VAR" prefix should be removed from
272320 // the SDK, since it's Terraform specific. When that happens, we need to update this to pass in the right prefix.
273- defaultConfigProvider := oci_common .DefaultConfigProvider ()
321+ configProviders = append ( configProviders , oci_common .DefaultConfigProvider () )
274322
275- officialSdkConfigProvider , err := oci_common .ComposingConfigurationProvider ([]oci_common. ConfigurationProvider { tfConfigProvider , defaultConfigProvider } )
323+ officialSdkConfigProvider , err := oci_common .ComposingConfigurationProvider (configProviders )
276324 if err != nil {
277325 return nil , err
278326 }
@@ -322,33 +370,39 @@ func setGoSDKClients(clients *OracleClients, officialSdkConfigProvider oci_commo
322370 return
323371 }
324372
325- clients .blockStorageClient = & blockStorageClient
326- clients .blockStorageClient .BaseClient .HTTPClient = httpClient
327- clients .blockStorageClient .UserAgent = userAgent
373+ useOboToken , err := strconv .ParseBool (getEnvSetting ("use_obo_token" , "false" ))
374+ if err != nil {
375+ return
376+ }
328377
329- clients .computeClient = & computeClient
330- clients .computeClient .BaseClient .HTTPClient = httpClient
331- clients .computeClient .UserAgent = userAgent
378+ var oboTokenProvider oci_common.OboTokenProvider
379+ if useOboToken {
380+ oboTokenProvider = oboTokenProviderFromEnv {}
381+ } else {
382+ oboTokenProvider = oci_common .NewEmptyOboTokenProvider ()
383+ }
332384
333- clients .databaseClient = & databaseClient
334- clients .databaseClient .BaseClient .HTTPClient = httpClient
335- clients .databaseClient .UserAgent = userAgent
385+ configureClient := func (client * oci_common.BaseClient ) {
386+ client .HTTPClient = httpClient
387+ client .UserAgent = userAgent
388+ client .Obo = oboTokenProvider
389+ }
336390
337- clients .identityClient = & identityClient
338- clients .identityClient .BaseClient .HTTPClient = httpClient
339- clients .identityClient .UserAgent = userAgent
391+ configureClient (& blockStorageClient .BaseClient )
392+ configureClient (& computeClient .BaseClient )
393+ configureClient (& databaseClient .BaseClient )
394+ configureClient (& identityClient .BaseClient )
395+ configureClient (& virtualNetworkClient .BaseClient )
396+ configureClient (& objectStorageClient .BaseClient )
397+ configureClient (& loadBalancerClient .BaseClient )
340398
399+ clients .blockStorageClient = & blockStorageClient
400+ clients .computeClient = & computeClient
401+ clients .databaseClient = & databaseClient
402+ clients .identityClient = & identityClient
341403 clients .virtualNetworkClient = & virtualNetworkClient
342- clients .virtualNetworkClient .BaseClient .HTTPClient = httpClient
343- clients .virtualNetworkClient .UserAgent = userAgent
344-
345404 clients .objectStorageClient = & objectStorageClient
346- clients .objectStorageClient .BaseClient .HTTPClient = httpClient
347- clients .objectStorageClient .UserAgent = userAgent
348-
349405 clients .loadBalancerClient = & loadBalancerClient
350- clients .loadBalancerClient .BaseClient .HTTPClient = httpClient
351- clients .loadBalancerClient .UserAgent = userAgent
352406
353407 return
354408}
@@ -375,28 +429,28 @@ func (p ResourceDataConfigProvider) TenancyOCID() (string, error) {
375429 if tenancyOCID , ok := p .D .GetOkExists ("tenancy_ocid" ); ok {
376430 return tenancyOCID .(string ), nil
377431 }
378- return "" , fmt .Errorf ("Can not get tenancy_ocid from Terraform configuration" )
432+ return "" , fmt .Errorf ("can not get tenancy_ocid from Terraform configuration" )
379433}
380434
381435func (p ResourceDataConfigProvider ) UserOCID () (string , error ) {
382436 if userOCID , ok := p .D .GetOkExists ("user_ocid" ); ok {
383437 return userOCID .(string ), nil
384438 }
385- return "" , fmt .Errorf ("Can not get user_ocid from Terraform configuration" )
439+ return "" , fmt .Errorf ("can not get user_ocid from Terraform configuration" )
386440}
387441
388442func (p ResourceDataConfigProvider ) KeyFingerprint () (string , error ) {
389443 if fingerprint , ok := p .D .GetOkExists ("fingerprint" ); ok {
390444 return fingerprint .(string ), nil
391445 }
392- return "" , fmt .Errorf ("Can not get fingerprint from Terraform configuration" )
446+ return "" , fmt .Errorf ("can not get fingerprint from Terraform configuration" )
393447}
394448
395449func (p ResourceDataConfigProvider ) Region () (string , error ) {
396450 if region , ok := p .D .GetOkExists ("region" ); ok {
397451 return region .(string ), nil
398452 }
399- return "" , fmt .Errorf ("Can not get region from Terraform configuration" )
453+ return "" , fmt .Errorf ("can not get region from Terraform configuration" )
400454}
401455
402456func (p ResourceDataConfigProvider ) KeyID () (string , error ) {
@@ -436,5 +490,5 @@ func (p ResourceDataConfigProvider) PrivateRSAKey() (key *rsa.PrivateKey, err er
436490 return oci_common .PrivateKeyFromBytes (pemFileContent , & password )
437491 }
438492
439- return nil , fmt .Errorf ("Can not get private_key or private_key_path from Terraform configuration" )
493+ return nil , fmt .Errorf ("can not get private_key or private_key_path from Terraform configuration" )
440494}
0 commit comments