github.com/smugmug/godynamo@v0.0.0-20151122084750-7913028f6623/conf/conf.go (about)

     1  // Manages reading the configuration file format into our shared conf state.
     2  // The AWS SDKs utilize a conf file format that this package attempts compatibility with while
     3  // supporting extra fields. This is why the type detailing the file and internal formats differ.
     4  // See SAMPLE-aws-config.json in the source repository for a sample.
     5  //
     6  // This package will eventually feature code to interoperate with the "official" SDK once it
     7  // settles.
     8  package conf
     9  
    10  import (
    11  	"errors"
    12  	roles "github.com/smugmug/goawsroles/roles"
    13  	"sync"
    14  )
    15  
    16  const (
    17  	CONF_NAME          = "aws-config.json"
    18  	ROLE_PROVIDER_FILE = "file"
    19  )
    20  
    21  // SDK_conf_File roughly matches the format as used by recent amazon SDKs, plus some additions.
    22  // These are correlated to the fields you would fill in the conf file
    23  type SDK_conf_file struct {
    24  	Extends  []string
    25  	Services struct {
    26  		Default_settings struct {
    27  			Params struct {
    28  				// Traditional AWS access/secret authentication pair.
    29  				Access_key_id     string
    30  				Secret_access_key string
    31  				// If you use syslogd (a linux or *bsd system), you may set this to "true".
    32  				// (this is currently unused)
    33  				Use_sys_log bool
    34  			}
    35  		}
    36  		Dynamo_db struct {
    37  			// Your dynamo hostname.
    38  			Host string
    39  			// Typically http or https, will have "://" appended.
    40  			Scheme string
    41  			// Port should correspond to the scheme.
    42  			Port int
    43  			// If set to true, programs that are written with godynamo may
    44  			// opt to launch the keepalive goroutine to keep conns open.
    45  			KeepAlive bool
    46  			// Your aws zone.
    47  			Zone string
    48  			IAM  struct {
    49  				// Set to true to use IAM authentication.
    50  				Use_iam bool
    51  				// The role provider is described in the goawsroles package.
    52  				// See: https://github.com/smugmug/goawsroles/
    53  				// Currently the only support is for the "file" provider, whereby
    54  				// roles data is written to local files.
    55  				Role_provider string
    56  				// The identifier (filename, etc) for the IAM Access Key
    57  				Access_key string
    58  				// The identifier (filename, etc) for the IAM Secret Key
    59  				Secret_key string
    60  				// The identifier (filename, etc) for the IAM Token
    61  				Token string
    62  				// If using the "file" role provider, the base dir to read IAM files.
    63  				Base_dir string
    64  				// Set to true if you would like the roles resource watched for changes
    65  				// and automatically (and atomically) updated.
    66  				Watch bool
    67  			}
    68  		}
    69  	}
    70  }
    71  
    72  // AWS_Conf is the structure used internally in godynamo.
    73  type AWS_Conf struct {
    74  	// Set to true if this struct is populated correctly.
    75  	Initialized bool
    76  	// Traditional AWS authentication pair.
    77  	Auth struct {
    78  		AccessKey string
    79  		Secret    string
    80  	}
    81  	// Dynamo connection data.
    82  	Network struct {
    83  		DynamoDB struct {
    84  			Host   string
    85  			Scheme string
    86  			// Port is converted into a string for internal use, typically
    87  			// stitching together URL path strings.
    88  			Port      string
    89  			KeepAlive bool
    90  			IP        string
    91  			Zone      string
    92  			URL       string
    93  		}
    94  	}
    95  	// If using syslogd
    96  	UseSysLog bool
    97  	// If using IAM
    98  	UseIAM bool
    99  	// The IAM role provider info
   100  	IAM struct {
   101  		RoleProvider string
   102  		Watch        bool
   103  		// Tells you where the credentials can be read from
   104  		File struct {
   105  			AccessKey string
   106  			Secret    string
   107  			Token     string
   108  			BaseDir   string
   109  		}
   110  		// The credentials themselves, once loaded from Files.* above
   111  		// these are kept distinct from the global AccessKey and Secret
   112  		// in the event a caller wants a mixed model
   113  		Credentials struct {
   114  			AccessKey string
   115  			Secret    string
   116  			Token     string
   117  		}
   118  	}
   119  	// Lock used when accessing IAM values, which will change during execution.
   120  	// other values will persist for program duration so they can be read without locking.
   121  	ConfLock sync.RWMutex
   122  }
   123  
   124  // Copy will safely copy the values from one conf struct to another.
   125  func (c *AWS_Conf) Copy(s *AWS_Conf) error {
   126  	if c == nil || s == nil {
   127  		return errors.New("conf.Copy: one of c or s is nil")
   128  	}
   129  	c.ConfLock.Lock()
   130  	s.ConfLock.RLock()
   131  	c.Initialized = s.Initialized
   132  	c.Auth = s.Auth
   133  	c.Network = s.Network
   134  	c.UseSysLog = s.UseSysLog
   135  	c.UseIAM = s.UseIAM
   136  	c.IAM = s.IAM
   137  	s.ConfLock.RUnlock()
   138  	c.ConfLock.Unlock()
   139  	return nil
   140  }
   141  
   142  // CredentialsFromRoles will copy the accessKey,secret, and optionally the token
   143  // from the Roles instance and set the IAM flag appropriately.
   144  func (c *AWS_Conf) CredentialsFromRoles(r roles.RolesReader) error {
   145  	if c == nil {
   146  		return errors.New("conf.CredentialsFromRoles: c is nil")
   147  	}
   148  	c.ConfLock.Lock()
   149  	defer c.ConfLock.Unlock()
   150  	accessKey, accessKey_err := r.GetAccessKey()
   151  	if accessKey_err != nil {
   152  		c.Initialized = false
   153  		return accessKey_err
   154  	}
   155  	secret, secret_err := r.GetSecret()
   156  	if secret_err != nil {
   157  		c.Initialized = false
   158  		return secret_err
   159  	}
   160  	if r.UsingIAM() {
   161  		// we are using IAM temporary credentials, we must get the Token
   162  		token, token_err := r.GetToken()
   163  		if token_err != nil {
   164  			c.Initialized = false
   165  			return token_err
   166  		}
   167  		c.IAM.Credentials.AccessKey = accessKey
   168  		c.IAM.Credentials.Secret = secret
   169  		c.IAM.Credentials.Token = token
   170  		c.Auth.AccessKey = ""
   171  		c.Auth.Secret = ""
   172  		c.UseIAM = true
   173  	} else {
   174  		// just using master credentials
   175  		c.Auth.AccessKey = accessKey
   176  		c.Auth.Secret = secret
   177  		c.IAM.Credentials.AccessKey = ""
   178  		c.IAM.Credentials.Secret = ""
   179  		c.IAM.Credentials.Token = ""
   180  		c.UseIAM = false
   181  	}
   182  	c.Initialized = true
   183  	return nil
   184  }
   185  
   186  // IsValid returns true of the conf pointer passed is not nil and references an initialized struct.
   187  func IsValid(c *AWS_Conf) bool {
   188  	return c != nil && c.Initialized
   189  }
   190  
   191  // Vals is the global conf vals struct. It is shared throughout the duration of program execution.
   192  // Use the embedded ConfLock mutex to use it safely.
   193  // It is preferred now that developers avoid this and instead use methods that take a configuration parameter.
   194  var (
   195  	Vals AWS_Conf
   196  )