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

     1  // Manages reading the conf file into the global var as described in the `conf` package.
     2  package conf_file
     3  
     4  import (
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"github.com/smugmug/godynamo/aws_const"
     9  	"github.com/smugmug/godynamo/conf"
    10  	"io/ioutil"
    11  	"log"
    12  	"net"
    13  	"net/url"
    14  	"os"
    15  	"path/filepath"
    16  	"strconv"
    17  )
    18  
    19  // ReadConfFile will attempt to read in the conf file path passed as a parameter
    20  // and convert it into a conf.AWS_Conf struct pointer. You can use this to read in
    21  // a conf for a file of your own choosing.
    22  func ReadConfFile(conf_file string) (*conf.AWS_Conf, error) {
    23  	conf_bytes, conf_err := ioutil.ReadFile(conf_file)
    24  	if conf_err != nil {
    25  		e := fmt.Sprintf("conf_file.ReadConfFile: cannot read conf file %s", conf_file)
    26  		return nil, errors.New(e)
    27  	}
    28  
    29  	var cf conf.SDK_conf_file
    30  	um_err := json.Unmarshal(conf_bytes, &cf)
    31  	if um_err != nil {
    32  		e := fmt.Sprintf("conf_file.ReadConfFile: cannot unmarshal %s. json err %s",
    33  			conf_file, um_err.Error())
    34  		return nil, errors.New(e)
    35  	}
    36  
    37  	var c conf.AWS_Conf
    38  	// make sure the dynamo endpoint is available
    39  	addrs, addrs_err := net.LookupIP(cf.Services.Dynamo_db.Host)
    40  	if addrs_err != nil {
    41  		e := fmt.Sprintf("conf_file.ReadConfFile: cannot lookup hostname %s",
    42  			cf.Services.Dynamo_db.Host)
    43  		return nil, errors.New(e)
    44  	}
    45  	dynamo_ip := (addrs[0]).String()
    46  
    47  	// assign the values to our globally-available c struct instance
    48  	c.Auth.AccessKey = cf.Services.Default_settings.Params.Access_key_id
    49  	c.Auth.Secret = cf.Services.Default_settings.Params.Secret_access_key
    50  	c.UseSysLog = cf.Services.Default_settings.Params.Use_sys_log
    51  	c.Network.DynamoDB.Host = cf.Services.Dynamo_db.Host
    52  	c.Network.DynamoDB.IP = dynamo_ip
    53  	c.Network.DynamoDB.Zone = cf.Services.Dynamo_db.Zone
    54  	scheme := "http"
    55  	port := aws_const.PORT // already a string
    56  	if cf.Services.Dynamo_db.Scheme != "" {
    57  		scheme = cf.Services.Dynamo_db.Scheme
    58  	}
    59  	if cf.Services.Dynamo_db.Port != 0 {
    60  		port = strconv.Itoa(cf.Services.Dynamo_db.Port)
    61  	}
    62  	c.Network.DynamoDB.Port = port
    63  	c.Network.DynamoDB.Scheme = scheme
    64  	c.Network.DynamoDB.URL = scheme + "://" + c.Network.DynamoDB.Host +
    65  		":" + port
    66  	_, url_err := url.Parse(c.Network.DynamoDB.URL)
    67  	if url_err != nil {
    68  		return nil, errors.New("conf_file.ReadConfFile: conf.Network.DynamoDB.URL malformed")
    69  	}
    70  
    71  	// If set to true, programs that are written with godynamo may
    72  	// opt to launch the keepalive goroutine to keep conns open.
    73  	c.Network.DynamoDB.KeepAlive = cf.Services.Dynamo_db.KeepAlive
    74  
    75  	// read in flags for IAM support
    76  	if cf.Services.Dynamo_db.IAM.Use_iam == true {
    77  		// caller will have to check the RoleProvider to dispatch further Roles features
    78  		c.IAM.RoleProvider = cf.Services.Dynamo_db.IAM.Role_provider
    79  		c.IAM.File.BaseDir = cf.Services.Dynamo_db.IAM.Base_dir
    80  		c.IAM.File.AccessKey = cf.Services.Dynamo_db.IAM.Access_key
    81  		c.IAM.File.Secret = cf.Services.Dynamo_db.IAM.Secret_key
    82  		c.IAM.File.Token = cf.Services.Dynamo_db.IAM.Token
    83  		if cf.Services.Dynamo_db.IAM.Watch == true {
    84  			c.IAM.Watch = true
    85  		} else {
    86  			c.IAM.Watch = false
    87  		}
    88  		c.UseIAM = true
    89  	}
    90  	c.Initialized = true
    91  	return &c, nil
    92  }
    93  
    94  // ReadDefaultConfs will check the preset standard locations for conf files and
    95  // attempt to create a conf.AWS_Conf struct pointer with the first one found.
    96  // The order of precedence is:
    97  // 1. file in $GODYNAMO_CONF_FILE if you wish to set it.
    98  // 2. $HOME/.aws-config.json
    99  // 3. /etc/aws-config.json (note lack of prefix '.')
   100  // This function can be useful when moving back and forth between environments
   101  // where you wish to have a conf file in $HOME that precludes one in /etc.
   102  func ReadDefaultConfs() (*conf.AWS_Conf, error) {
   103  	local_conf := os.Getenv("HOME") + string(filepath.Separator) + "." + conf.CONF_NAME
   104  	etc_conf := string(filepath.Separator) + "etc" + string(filepath.Separator) + conf.CONF_NAME
   105  	conf_files := make([]string, 0)
   106  	// assumes that if set, this is a fully-qualified file path
   107  	const env_conf = "GODYNAMO_CONF_FILE"
   108  	// assumes that if set, this is a fully-qualified file path
   109  	if os.Getenv(env_conf) != "" {
   110  		conf_files = append(conf_files, os.Getenv(env_conf))
   111  	}
   112  	conf_files = append(conf_files, local_conf)
   113  	conf_files = append(conf_files, etc_conf)
   114  
   115  CONF_LOCATIONS:
   116  	for _, conf_file := range conf_files {
   117  		c, c_err := ReadConfFile(conf_file)
   118  		if c_err != nil {
   119  			e := fmt.Sprintf("conf_file.ReadDefaultConfs: problem with conf %s: %s",
   120  				conf_file, c_err.Error())
   121  			log.Printf(e)
   122  			continue CONF_LOCATIONS
   123  		} else {
   124  			return c, nil
   125  		}
   126  	}
   127  	e := fmt.Sprintf("conf_File.ReadDefaultConfs: no conf struct found in %v", conf_files)
   128  	return nil, errors.New(e)
   129  }
   130  
   131  // ReadGlobal will take a configuration and assign it to the global conf.Vals struct instance.
   132  func ReadGlobal() {
   133  	local_conf, conf_err := ReadDefaultConfs()
   134  	if conf_err != nil {
   135  		e := fmt.Sprintf("cannot locate a valid global configuration: %s", conf_err.Error())
   136  		panic(e)
   137  	}
   138  	conf.Vals.Copy(local_conf)
   139  }
   140  
   141  // Read assigns a configuration to the global conf.Vals struct instance.
   142  // This function exists as backwards compatibility only. Do not use it in new code,
   143  // instead use ReadLocal.
   144  func Read() {
   145  	ReadGlobal()
   146  }