660 lines
21 KiB
Go
660 lines
21 KiB
Go
// Copyright (c) 2016, 2018, 2021, Oracle and/or its affiliates. All rights reserved.
|
|
// This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
|
|
|
|
package common
|
|
|
|
import (
|
|
"crypto/rsa"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// AuthenticationType for auth
|
|
type AuthenticationType string
|
|
|
|
const (
|
|
// UserPrincipal is default auth type
|
|
UserPrincipal AuthenticationType = "user_principal"
|
|
// InstancePrincipal is used for instance principle auth type
|
|
InstancePrincipal AuthenticationType = "instance_principal"
|
|
// InstancePrincipalDelegationToken is used for instance principle delegation token auth type
|
|
InstancePrincipalDelegationToken AuthenticationType = "instance_principle_delegation_token"
|
|
// UnknownAuthenticationType is used for none meaningful auth type
|
|
UnknownAuthenticationType AuthenticationType = "unknown_auth_type"
|
|
)
|
|
|
|
// AuthConfig is used for getting auth related paras in config file
|
|
type AuthConfig struct {
|
|
AuthType AuthenticationType
|
|
// IsFromConfigFile is used to point out if the authConfig is from configuration file
|
|
IsFromConfigFile bool
|
|
OboToken *string
|
|
}
|
|
|
|
// ConfigurationProvider wraps information about the account owner
|
|
type ConfigurationProvider interface {
|
|
KeyProvider
|
|
TenancyOCID() (string, error)
|
|
UserOCID() (string, error)
|
|
KeyFingerprint() (string, error)
|
|
Region() (string, error)
|
|
// AuthType() is used for specify the needed auth type, like UserPrincipal, InstancePrincipal, etc.
|
|
AuthType() (AuthConfig, error)
|
|
}
|
|
|
|
// IsConfigurationProviderValid Tests all parts of the configuration provider do not return an error, this method will
|
|
// not check AuthType(), since authType() is not required to be there.
|
|
func IsConfigurationProviderValid(conf ConfigurationProvider) (ok bool, err error) {
|
|
baseFn := []func() (string, error){conf.TenancyOCID, conf.UserOCID, conf.KeyFingerprint, conf.Region, conf.KeyID}
|
|
for _, fn := range baseFn {
|
|
_, err = fn()
|
|
ok = err == nil
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
_, err = conf.PrivateRSAKey()
|
|
ok = err == nil
|
|
if err != nil {
|
|
return
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
// rawConfigurationProvider allows a user to simply construct a configuration provider from raw values.
|
|
type rawConfigurationProvider struct {
|
|
tenancy string
|
|
user string
|
|
region string
|
|
fingerprint string
|
|
privateKey string
|
|
privateKeyPassphrase *string
|
|
}
|
|
|
|
// NewRawConfigurationProvider will create a ConfigurationProvider with the arguments of the function
|
|
func NewRawConfigurationProvider(tenancy, user, region, fingerprint, privateKey string, privateKeyPassphrase *string) ConfigurationProvider {
|
|
return rawConfigurationProvider{tenancy, user, region, fingerprint, privateKey, privateKeyPassphrase}
|
|
}
|
|
|
|
func (p rawConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {
|
|
return PrivateKeyFromBytes([]byte(p.privateKey), p.privateKeyPassphrase)
|
|
}
|
|
|
|
func (p rawConfigurationProvider) KeyID() (keyID string, err error) {
|
|
tenancy, err := p.TenancyOCID()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
user, err := p.UserOCID()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
fingerprint, err := p.KeyFingerprint()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return fmt.Sprintf("%s/%s/%s", tenancy, user, fingerprint), nil
|
|
}
|
|
|
|
func (p rawConfigurationProvider) TenancyOCID() (string, error) {
|
|
if p.tenancy == "" {
|
|
return "", fmt.Errorf("tenancy OCID can not be empty")
|
|
}
|
|
return p.tenancy, nil
|
|
}
|
|
|
|
func (p rawConfigurationProvider) UserOCID() (string, error) {
|
|
if p.user == "" {
|
|
return "", fmt.Errorf("user OCID can not be empty")
|
|
}
|
|
return p.user, nil
|
|
}
|
|
|
|
func (p rawConfigurationProvider) KeyFingerprint() (string, error) {
|
|
if p.fingerprint == "" {
|
|
return "", fmt.Errorf("fingerprint can not be empty")
|
|
}
|
|
return p.fingerprint, nil
|
|
}
|
|
|
|
func (p rawConfigurationProvider) Region() (string, error) {
|
|
return canStringBeRegion(p.region)
|
|
}
|
|
|
|
func (p rawConfigurationProvider) AuthType() (AuthConfig, error) {
|
|
return AuthConfig{UnknownAuthenticationType, false, nil}, nil
|
|
}
|
|
|
|
// environmentConfigurationProvider reads configuration from environment variables
|
|
type environmentConfigurationProvider struct {
|
|
PrivateKeyPassword string
|
|
EnvironmentVariablePrefix string
|
|
}
|
|
|
|
// ConfigurationProviderEnvironmentVariables creates a ConfigurationProvider from a uniform set of environment variables starting with a prefix
|
|
// The env variables should look like: [prefix]_private_key_path, [prefix]_tenancy_ocid, [prefix]_user_ocid, [prefix]_fingerprint
|
|
// [prefix]_region
|
|
func ConfigurationProviderEnvironmentVariables(environmentVariablePrefix, privateKeyPassword string) ConfigurationProvider {
|
|
return environmentConfigurationProvider{EnvironmentVariablePrefix: environmentVariablePrefix,
|
|
PrivateKeyPassword: privateKeyPassword}
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) String() string {
|
|
return fmt.Sprintf("Configuration provided by environment variables prefixed with: %s", p.EnvironmentVariablePrefix)
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {
|
|
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "private_key_path")
|
|
var ok bool
|
|
var value string
|
|
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
|
return nil, fmt.Errorf("can not read PrivateKey from env variable: %s", environmentVariable)
|
|
}
|
|
|
|
expandedPath := expandPath(value)
|
|
pemFileContent, err := ioutil.ReadFile(expandedPath)
|
|
if err != nil {
|
|
Debugln("Can not read PrivateKey location from environment variable: " + environmentVariable)
|
|
return
|
|
}
|
|
|
|
key, err = PrivateKeyFromBytes(pemFileContent, &p.PrivateKeyPassword)
|
|
return
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) KeyID() (keyID string, err error) {
|
|
ocid, err := p.TenancyOCID()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
userocid, err := p.UserOCID()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
fingerprint, err := p.KeyFingerprint()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return fmt.Sprintf("%s/%s/%s", ocid, userocid, fingerprint), nil
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) TenancyOCID() (value string, err error) {
|
|
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "tenancy_ocid")
|
|
var ok bool
|
|
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
|
err = fmt.Errorf("can not read Tenancy from environment variable %s", environmentVariable)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) UserOCID() (value string, err error) {
|
|
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "user_ocid")
|
|
var ok bool
|
|
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
|
err = fmt.Errorf("can not read user id from environment variable %s", environmentVariable)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) KeyFingerprint() (value string, err error) {
|
|
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "fingerprint")
|
|
var ok bool
|
|
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
|
err = fmt.Errorf("can not read fingerprint from environment variable %s", environmentVariable)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) Region() (value string, err error) {
|
|
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "region")
|
|
var ok bool
|
|
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
|
err = fmt.Errorf("can not read region from environment variable %s", environmentVariable)
|
|
return value, err
|
|
}
|
|
|
|
return canStringBeRegion(value)
|
|
}
|
|
|
|
func (p environmentConfigurationProvider) AuthType() (AuthConfig, error) {
|
|
return AuthConfig{UnknownAuthenticationType, false, nil},
|
|
fmt.Errorf("unsupported, keep the interface")
|
|
}
|
|
|
|
// fileConfigurationProvider. reads configuration information from a file
|
|
type fileConfigurationProvider struct {
|
|
//The path to the configuration file
|
|
ConfigPath string
|
|
|
|
//The password for the private key
|
|
PrivateKeyPassword string
|
|
|
|
//The profile for the configuration
|
|
Profile string
|
|
|
|
//ConfigFileInfo
|
|
FileInfo *configFileInfo
|
|
}
|
|
|
|
// ConfigurationProviderFromFile creates a configuration provider from a configuration file
|
|
// by reading the "DEFAULT" profile
|
|
func ConfigurationProviderFromFile(configFilePath, privateKeyPassword string) (ConfigurationProvider, error) {
|
|
if configFilePath == "" {
|
|
return nil, fmt.Errorf("config file path can not be empty")
|
|
}
|
|
|
|
return fileConfigurationProvider{
|
|
ConfigPath: configFilePath,
|
|
PrivateKeyPassword: privateKeyPassword,
|
|
Profile: "DEFAULT"}, nil
|
|
}
|
|
|
|
// ConfigurationProviderFromFileWithProfile creates a configuration provider from a configuration file
|
|
// and the given profile
|
|
func ConfigurationProviderFromFileWithProfile(configFilePath, profile, privateKeyPassword string) (ConfigurationProvider, error) {
|
|
if configFilePath == "" {
|
|
return nil, fmt.Errorf("config file path can not be empty")
|
|
}
|
|
|
|
return fileConfigurationProvider{
|
|
ConfigPath: configFilePath,
|
|
PrivateKeyPassword: privateKeyPassword,
|
|
Profile: profile}, nil
|
|
}
|
|
|
|
type configFileInfo struct {
|
|
UserOcid, Fingerprint, KeyFilePath, TenancyOcid, Region, Passphrase, SecurityTokenFilePath, DelegationTokenFilePath,
|
|
AuthenticationType string
|
|
PresentConfiguration rune
|
|
}
|
|
|
|
const (
|
|
hasTenancy = 1 << iota
|
|
hasUser
|
|
hasFingerprint
|
|
hasRegion
|
|
hasKeyFile
|
|
hasPassphrase
|
|
hasSecurityTokenFile
|
|
hasDelegationTokenFile
|
|
hasAuthenticationType
|
|
none
|
|
)
|
|
|
|
var profileRegex = regexp.MustCompile(`^\[(.*)\]`)
|
|
|
|
func parseConfigFile(data []byte, profile string) (info *configFileInfo, err error) {
|
|
|
|
if len(data) == 0 {
|
|
return nil, fmt.Errorf("configuration file content is empty")
|
|
}
|
|
|
|
content := string(data)
|
|
splitContent := strings.Split(content, "\n")
|
|
|
|
//Look for profile
|
|
for i, line := range splitContent {
|
|
if match := profileRegex.FindStringSubmatch(line); match != nil && len(match) > 1 && match[1] == profile {
|
|
start := i + 1
|
|
return parseConfigAtLine(start, splitContent)
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("configuration file did not contain profile: %s", profile)
|
|
}
|
|
|
|
func parseConfigAtLine(start int, content []string) (info *configFileInfo, err error) {
|
|
var configurationPresent rune
|
|
info = &configFileInfo{}
|
|
for i := start; i < len(content); i++ {
|
|
line := content[i]
|
|
if profileRegex.MatchString(line) {
|
|
break
|
|
}
|
|
|
|
if !strings.Contains(line, "=") {
|
|
continue
|
|
}
|
|
|
|
splits := strings.Split(line, "=")
|
|
switch key, value := strings.TrimSpace(splits[0]), strings.TrimSpace(splits[1]); strings.ToLower(key) {
|
|
case "passphrase", "pass_phrase":
|
|
configurationPresent = configurationPresent | hasPassphrase
|
|
info.Passphrase = value
|
|
case "user":
|
|
configurationPresent = configurationPresent | hasUser
|
|
info.UserOcid = value
|
|
case "fingerprint":
|
|
configurationPresent = configurationPresent | hasFingerprint
|
|
info.Fingerprint = value
|
|
case "key_file":
|
|
configurationPresent = configurationPresent | hasKeyFile
|
|
info.KeyFilePath = value
|
|
case "tenancy":
|
|
configurationPresent = configurationPresent | hasTenancy
|
|
info.TenancyOcid = value
|
|
case "region":
|
|
configurationPresent = configurationPresent | hasRegion
|
|
info.Region = value
|
|
case "security_token_file":
|
|
configurationPresent = configurationPresent | hasSecurityTokenFile
|
|
info.SecurityTokenFilePath = value
|
|
case "delegation_token_file":
|
|
configurationPresent = configurationPresent | hasDelegationTokenFile
|
|
info.DelegationTokenFilePath = value
|
|
case "authentication_type":
|
|
configurationPresent = configurationPresent | hasAuthenticationType
|
|
info.AuthenticationType = value
|
|
}
|
|
}
|
|
info.PresentConfiguration = configurationPresent
|
|
return
|
|
|
|
}
|
|
|
|
// cleans and expands the path if it contains a tilde , returns the expanded path or the input path as is if not expansion
|
|
// was performed
|
|
func expandPath(filepath string) (expandedPath string) {
|
|
cleanedPath := path.Clean(filepath)
|
|
expandedPath = cleanedPath
|
|
if strings.HasPrefix(cleanedPath, "~") {
|
|
rest := cleanedPath[2:]
|
|
expandedPath = path.Join(getHomeFolder(), rest)
|
|
}
|
|
return
|
|
}
|
|
|
|
func openConfigFile(configFilePath string) (data []byte, err error) {
|
|
expandedPath := expandPath(configFilePath)
|
|
data, err = ioutil.ReadFile(expandedPath)
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read config file: %s due to: %s", configFilePath, err.Error())
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (p fileConfigurationProvider) String() string {
|
|
return fmt.Sprintf("Configuration provided by file: %s", p.ConfigPath)
|
|
}
|
|
|
|
func (p fileConfigurationProvider) readAndParseConfigFile() (info *configFileInfo, err error) {
|
|
if p.FileInfo != nil {
|
|
return p.FileInfo, nil
|
|
}
|
|
|
|
if p.ConfigPath == "" {
|
|
return nil, fmt.Errorf("configuration path can not be empty")
|
|
}
|
|
|
|
data, err := openConfigFile(p.ConfigPath)
|
|
if err != nil {
|
|
err = fmt.Errorf("error while parsing config file: %s. Due to: %s", p.ConfigPath, err.Error())
|
|
return
|
|
}
|
|
|
|
p.FileInfo, err = parseConfigFile(data, p.Profile)
|
|
return p.FileInfo, err
|
|
}
|
|
|
|
func presentOrError(value string, expectedConf, presentConf rune, confMissing string) (string, error) {
|
|
if presentConf&expectedConf == expectedConf {
|
|
return value, nil
|
|
}
|
|
return "", errors.New(confMissing + " configuration is missing from file")
|
|
}
|
|
|
|
func (p fileConfigurationProvider) TenancyOCID() (value string, err error) {
|
|
info, err := p.readAndParseConfigFile()
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
value, err = presentOrError(info.TenancyOcid, hasTenancy, info.PresentConfiguration, "tenancy")
|
|
return
|
|
}
|
|
|
|
func (p fileConfigurationProvider) UserOCID() (value string, err error) {
|
|
info, err := p.readAndParseConfigFile()
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
if value, err = presentOrError(info.UserOcid, hasUser, info.PresentConfiguration, "user"); err != nil {
|
|
// need to check if securityTokenPath is provided, if security token is provided, userOCID can be "".
|
|
if _, stErr := presentOrError(info.SecurityTokenFilePath, hasSecurityTokenFile, info.PresentConfiguration,
|
|
"securityTokenPath"); stErr == nil {
|
|
err = nil
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (p fileConfigurationProvider) KeyFingerprint() (value string, err error) {
|
|
info, err := p.readAndParseConfigFile()
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
|
return
|
|
}
|
|
value, err = presentOrError(info.Fingerprint, hasFingerprint, info.PresentConfiguration, "fingerprint")
|
|
return
|
|
}
|
|
|
|
func (p fileConfigurationProvider) KeyID() (keyID string, err error) {
|
|
info, err := p.readAndParseConfigFile()
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
|
return
|
|
}
|
|
if info.PresentConfiguration&hasUser == hasUser {
|
|
return fmt.Sprintf("%s/%s/%s", info.TenancyOcid, info.UserOcid, info.Fingerprint), nil
|
|
}
|
|
if filePath, err := presentOrError(info.SecurityTokenFilePath, hasSecurityTokenFile, info.PresentConfiguration, "securityTokenFilePath"); err == nil {
|
|
rawString, err := getTokenContent(filePath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return "ST$" + rawString, nil
|
|
}
|
|
err = fmt.Errorf("can not read SecurityTokenFilePath from configuration file due to: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
func (p fileConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {
|
|
info, err := p.readAndParseConfigFile()
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
filePath, err := presentOrError(info.KeyFilePath, hasKeyFile, info.PresentConfiguration, "key file path")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
expandedPath := expandPath(filePath)
|
|
pemFileContent, err := ioutil.ReadFile(expandedPath)
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read PrivateKey from configuration file due to: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
password := p.PrivateKeyPassword
|
|
|
|
if password == "" && ((info.PresentConfiguration & hasPassphrase) == hasPassphrase) {
|
|
password = info.Passphrase
|
|
}
|
|
|
|
key, err = PrivateKeyFromBytes(pemFileContent, &password)
|
|
return
|
|
}
|
|
|
|
func (p fileConfigurationProvider) Region() (value string, err error) {
|
|
info, err := p.readAndParseConfigFile()
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read region configuration due to: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
value, err = presentOrError(info.Region, hasRegion, info.PresentConfiguration, "region")
|
|
if err != nil {
|
|
val, error := getRegionFromEnvVar()
|
|
if error != nil {
|
|
err = fmt.Errorf("region configuration is missing from file, nor for OCI_REGION env var")
|
|
return
|
|
}
|
|
value = val
|
|
}
|
|
|
|
return canStringBeRegion(value)
|
|
}
|
|
|
|
func (p fileConfigurationProvider) AuthType() (AuthConfig, error) {
|
|
info, err := p.readAndParseConfigFile()
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
|
return AuthConfig{UnknownAuthenticationType, true, nil}, err
|
|
}
|
|
val, err := presentOrError(info.AuthenticationType, hasAuthenticationType, info.PresentConfiguration, "authentication_type")
|
|
|
|
if val == "instance_principal" {
|
|
if filePath, err := presentOrError(info.DelegationTokenFilePath, hasDelegationTokenFile, info.PresentConfiguration, "delegationTokenFilePath"); err == nil {
|
|
if delegationToken, err := getTokenContent(filePath); err == nil && delegationToken != "" {
|
|
Debugf("delegation token content is %s, and error is %s ", delegationToken, err)
|
|
return AuthConfig{InstancePrincipalDelegationToken, true, &delegationToken}, nil
|
|
}
|
|
return AuthConfig{UnknownAuthenticationType, true, nil}, err
|
|
|
|
}
|
|
// normal instance principle
|
|
return AuthConfig{InstancePrincipal, true, nil}, nil
|
|
}
|
|
|
|
// by default, if no "authentication_type" is provided, just treated as user principle type, and will not return error
|
|
return AuthConfig{UserPrincipal, true, nil}, nil
|
|
}
|
|
|
|
func getTokenContent(filePath string) (string, error) {
|
|
expandedPath := expandPath(filePath)
|
|
tokenFileContent, err := ioutil.ReadFile(expandedPath)
|
|
if err != nil {
|
|
err = fmt.Errorf("can not read token content from configuration file due to: %s", err.Error())
|
|
return "", err
|
|
}
|
|
return fmt.Sprintf("%s", tokenFileContent), nil
|
|
}
|
|
|
|
// A configuration provider that look for information in multiple configuration providers
|
|
type composingConfigurationProvider struct {
|
|
Providers []ConfigurationProvider
|
|
}
|
|
|
|
// ComposingConfigurationProvider creates a composing configuration provider with the given slice of configuration providers
|
|
// A composing provider will return the configuration of the first provider that has the required property
|
|
// if no provider has the property it will return an error.
|
|
func ComposingConfigurationProvider(providers []ConfigurationProvider) (ConfigurationProvider, error) {
|
|
if len(providers) == 0 {
|
|
return nil, fmt.Errorf("providers can not be an empty slice")
|
|
}
|
|
|
|
for i, p := range providers {
|
|
if p == nil {
|
|
return nil, fmt.Errorf("provider in position: %d is nil. ComposingConfiurationProvider does not support nil values", i)
|
|
}
|
|
}
|
|
return composingConfigurationProvider{Providers: providers}, nil
|
|
}
|
|
|
|
func (c composingConfigurationProvider) TenancyOCID() (string, error) {
|
|
for _, p := range c.Providers {
|
|
val, err := p.TenancyOCID()
|
|
if err == nil {
|
|
return val, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("did not find a proper configuration for tenancy")
|
|
}
|
|
|
|
func (c composingConfigurationProvider) UserOCID() (string, error) {
|
|
for _, p := range c.Providers {
|
|
val, err := p.UserOCID()
|
|
if err == nil {
|
|
return val, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("did not find a proper configuration for user")
|
|
}
|
|
|
|
func (c composingConfigurationProvider) KeyFingerprint() (string, error) {
|
|
for _, p := range c.Providers {
|
|
val, err := p.KeyFingerprint()
|
|
if err == nil {
|
|
return val, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("did not find a proper configuration for keyFingerprint")
|
|
}
|
|
func (c composingConfigurationProvider) Region() (string, error) {
|
|
for _, p := range c.Providers {
|
|
val, err := p.Region()
|
|
if err == nil {
|
|
return val, nil
|
|
}
|
|
}
|
|
if val, err := getRegionFromEnvVar(); err == nil {
|
|
return val, nil
|
|
}
|
|
return "", fmt.Errorf("did not find a proper configuration for region, nor for OCI_REGION env var")
|
|
}
|
|
|
|
func (c composingConfigurationProvider) KeyID() (string, error) {
|
|
for _, p := range c.Providers {
|
|
val, err := p.KeyID()
|
|
if err == nil {
|
|
return val, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("did not find a proper configuration for key id")
|
|
}
|
|
|
|
func (c composingConfigurationProvider) PrivateRSAKey() (*rsa.PrivateKey, error) {
|
|
for _, p := range c.Providers {
|
|
val, err := p.PrivateRSAKey()
|
|
if err == nil {
|
|
return val, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("did not find a proper configuration for private key")
|
|
}
|
|
|
|
func (c composingConfigurationProvider) AuthType() (AuthConfig, error) {
|
|
// only check the first default fileConfigProvider
|
|
authConfig, err := c.Providers[0].AuthType()
|
|
if err == nil && authConfig.AuthType != UnknownAuthenticationType {
|
|
return authConfig, nil
|
|
}
|
|
return AuthConfig{UnknownAuthenticationType, false, nil}, fmt.Errorf("did not find a proper configuration for auth type")
|
|
}
|
|
|
|
func getRegionFromEnvVar() (string, error) {
|
|
regionEnvVar := "OCI_REGION"
|
|
if region, existed := os.LookupEnv(regionEnvVar); existed {
|
|
return region, nil
|
|
}
|
|
return "", fmt.Errorf("did not find OCI_REGION env var")
|
|
}
|