Example #1
0
// GoIAMToConf is a convenience wrapper for callers using roles_files instantiation of the roles interface.
// First there is a blocking read on the roles files to get the initial roles information. Then the
// file notification watcher will run as a goroutine, and resetting conf c's roles
// values. If IAM Credentials are ready for use, the parameter chan `ready_chan` will receive a true
// value, otherwise false. A false value on this chan should indicate to a caller that another auth
// mechanism (for example, hardocded credentials) should be used.
func GoIAMToConf(c *conf.AWS_Conf, ready_chan chan bool) {
	if c == nil {
		log.Printf("conf_iam.GoIAMToConf: c is nil")
		ready_chan <- false
		return
	}
	use_iam := false
	c.ConfLock.RLock()
	use_iam = c.UseIAM
	c.ConfLock.RUnlock()
	if use_iam == true {
		rf := roles_files.NewRolesFiles()
		watching := false
		c.ConfLock.RLock()
		rf.BaseDir = c.IAM.File.BaseDir
		rf.AccessKeyFile = c.IAM.File.AccessKey
		rf.SecretFile = c.IAM.File.Secret
		rf.TokenFile = c.IAM.File.Token
		watching = c.IAM.Watch
		c.ConfLock.RUnlock()
		roles_read_err := ReadIAMToConf(rf, c)
		if roles_read_err != nil {
			e := fmt.Sprintf("conf_iam.GoIAMToConf:cannot perform initial roles read: %s",
				roles_read_err.Error())
			log.Printf(e)
			c.ConfLock.Lock()
			c.UseIAM = false
			c.ConfLock.Unlock()
			ready_chan <- false
			return
		}
		// signal to caller that iam roles are ready to use
		ready_chan <- true
		if watching == true {
			watch_err := make(chan error)
			go WatchIAMToConf(rf, c, watch_err)
			go func() {
				select {
				case err := <-watch_err:
					if err != nil {
						log.Printf(err.Error())
						// caller can fall back to hard-coded perms
						// or live with the panic
						c.ConfLock.Lock()
						c.UseIAM = false
						c.ConfLock.Unlock()
					}
				}
			}()
		}
	} else {
		// signal to the caller than iam roles are not selected as a auth mechanism
		e := fmt.Sprintf("conf_iam.GoIAMToConf: not using IAM")
		log.Printf(e)
		ready_chan <- false
	}
}
Example #2
0
// RawReqWithConf will sign and transmit the request to the AWS DynamoDB endpoint.
// reqJSON is the json request
// amzTarget is the dynamoDB endpoint
// c is the configuration struct
// returns []byte respBody, string aws reqID, int http code, error
func RawReqWithConf(reqJSON []byte, amzTarget string, c *conf.AWS_Conf) ([]byte, string, int, error) {
	if !conf.IsValid(c) {
		return nil, "", 0, errors.New("auth_v4.RawReqWithConf: conf not valid")
	}
	// shadow conf vars in a read lock to minimize contention
	var our_c conf.AWS_Conf
	cp_err := our_c.Copy(c)
	if cp_err != nil {
		return nil, "", 0, cp_err
	}
	return rawReqAll(
		reqJSON,
		amzTarget,
		our_c.UseIAM,
		our_c.Network.DynamoDB.URL,
		our_c.Network.DynamoDB.Host,
		our_c.Network.DynamoDB.Port,
		our_c.Network.DynamoDB.Zone,
		our_c.IAM.Credentials.Secret,
		our_c.IAM.Credentials.AccessKey,
		our_c.IAM.Credentials.Token,
		our_c.Auth.Secret,
		our_c.Auth.AccessKey)
}
Example #3
0
// ReadConfFile will attempt to read in the conf file path passed as a parameter
// and convert it into a conf.AWS_Conf struct pointer. You can use this to read in
// a conf for a file of your own choosing.
func ReadConfFile(conf_file string) (*conf.AWS_Conf, error) {
	conf_bytes, conf_err := ioutil.ReadFile(conf_file)
	if conf_err != nil {
		e := fmt.Sprintf("conf_file.ReadConfFile: cannot read conf file %s", conf_file)
		return nil, errors.New(e)
	}

	var cf conf.SDK_conf_file
	um_err := json.Unmarshal(conf_bytes, &cf)
	if um_err != nil {
		e := fmt.Sprintf("conf_file.ReadConfFile: cannot unmarshal %s. json err %s",
			conf_file, um_err.Error())
		return nil, errors.New(e)
	}

	var c conf.AWS_Conf
	// make sure the dynamo endpoint is available
	addrs, addrs_err := net.LookupIP(cf.Services.Dynamo_db.Host)
	if addrs_err != nil {
		e := fmt.Sprintf("conf_file.ReadConfFile: cannot lookup hostname %s",
			cf.Services.Dynamo_db.Host)
		return nil, errors.New(e)
	}
	dynamo_ip := (addrs[0]).String()

	// assign the values to our globally-available c struct instance
	c.Auth.AccessKey = cf.Services.Default_settings.Params.Access_key_id
	c.Auth.Secret = cf.Services.Default_settings.Params.Secret_access_key
	c.UseSysLog = cf.Services.Default_settings.Params.Use_sys_log
	c.Network.DynamoDB.Host = cf.Services.Dynamo_db.Host
	c.Network.DynamoDB.IP = dynamo_ip
	c.Network.DynamoDB.Zone = cf.Services.Dynamo_db.Zone
	scheme := "http"
	port := aws_const.PORT // already a string
	if cf.Services.Dynamo_db.Scheme != "" {
		scheme = cf.Services.Dynamo_db.Scheme
	}
	if cf.Services.Dynamo_db.Port != 0 {
		port = strconv.Itoa(cf.Services.Dynamo_db.Port)
	}
	c.Network.DynamoDB.Port = port
	c.Network.DynamoDB.Scheme = scheme
	c.Network.DynamoDB.URL = scheme + "://" + c.Network.DynamoDB.Host +
		":" + port
	_, url_err := url.Parse(c.Network.DynamoDB.URL)
	if url_err != nil {
		return nil, errors.New("conf_file.ReadConfFile: conf.Network.DynamoDB.URL malformed")
	}

	// If set to true, programs that are written with godynamo may
	// opt to launch the keepalive goroutine to keep conns open.
	c.Network.DynamoDB.KeepAlive = cf.Services.Dynamo_db.KeepAlive

	// read in flags for IAM support
	if cf.Services.Dynamo_db.IAM.Use_iam == true {
		// caller will have to check the RoleProvider to dispatch further Roles features
		c.IAM.RoleProvider = cf.Services.Dynamo_db.IAM.Role_provider
		c.IAM.File.BaseDir = cf.Services.Dynamo_db.IAM.Base_dir
		c.IAM.File.AccessKey = cf.Services.Dynamo_db.IAM.Access_key
		c.IAM.File.Secret = cf.Services.Dynamo_db.IAM.Secret_key
		c.IAM.File.Token = cf.Services.Dynamo_db.IAM.Token
		if cf.Services.Dynamo_db.IAM.Watch == true {
			c.IAM.Watch = true
		} else {
			c.IAM.Watch = false
		}
		c.UseIAM = true
	}
	c.Initialized = true
	return &c, nil
}