func (provider) Transform(cfg map[string]interface{}) error { return config.ReplaceObjects(cfg, "abs", func(val map[string]interface{}) (interface{}, error) { p := val["$abs"].(string) result, err := filepath.Abs(filepath.FromSlash(p)) if err != nil { return nil, fmt.Errorf("Unable to resolve absolute path for: %s, error: %s", p, err) } return result, nil }) }
func (provider) Transform(cfg map[string]interface{}) error { metaURL, ok := cfg["packetMetaDataUrl"].(string) if !ok { metaURL = defaultPacketMetaDataURL } var data metadata return config.ReplaceObjects(cfg, "packet", func(val map[string]interface{}) (interface{}, error) { // Fetch packet metadata, if not already done if data.InstanceID == "" { g := got.New() res, err := g.Get(metaURL).Send() if err != nil { return nil, fmt.Errorf("Failed to fetch packet metadata, error: %s", err) } err = json.Unmarshal(res.Body, &data) if err != nil { return nil, fmt.Errorf("Failed to parse packet metadata, error: %s", err) } if data.InstanceID == "" { return nil, errors.New("Packet metadata isn't valid missing 'id' property") } } key := val["$packet"].(string) switch key { case "instance-id": return data.InstanceID, nil case "hostname": return data.Hostname, nil case "facility": return data.Facility, nil case "instance-type": return data.InstanceType, nil case "public-ipv4": for _, addr := range data.Network.Addresses { if addr.Family == 4 && addr.Public { return addr.Address, nil } } return nil, ErrNoPublicIPv4Address case "public-ipv6": for _, addr := range data.Network.Addresses { if addr.Family == 6 && addr.Public { return addr.Address, nil } } return nil, ErrNoPublicIPv6Address default: return nil, fmt.Errorf("Unknown $packet variable: %s", key) } }) }
func (provider) Transform(cfg map[string]interface{}) error { c, ok := cfg["credentials"].(map[string]interface{}) if !ok { return errors.New("Expected 'credentials' property to hold credentials") } creds := &tcclient.Credentials{} creds.ClientID, _ = c["clientId"].(string) creds.AccessToken, _ = c["accessToken"].(string) creds.Certificate, _ = c["certificate"].(string) if creds.ClientID == "" || creds.AccessToken == "" { return errors.New("Expected properties: credentials.clientId and credentials.accessToken") } // Create a secrets client s := secrets.New(creds) // Overwrite the baseUrl for secrets if one is given if baseURL, _ := cfg["secretsBaseUrl"].(string); baseURL != "" { s.BaseURL = baseURL } // Create a cache to avoid loading the same secret twice, we use the same // creds for all calls and we don't persistent the cache so there is no risk // of scope elevation here. cache := make(map[string]map[string]interface{}) return config.ReplaceObjects(cfg, "secret", func(val map[string]interface{}) (interface{}, error) { name := val["$secret"].(string) key, ok := val["key"].(string) if !ok || len(val) != 2 { return nil, errors.New("{$secret: ..., key: ...} object is missing key property") } // If secret isn't in the cache we try to load it if _, ok := cache[name]; !ok { secret, err := s.Get(name) if err != nil { return nil, err } value := map[string]interface{}{} err = json.Unmarshal(secret.Secret, &value) if err != nil { return nil, fmt.Errorf("Failed to parse response from secret, error: %s", err) } cache[name] = value } // Get secret from cache return cache[name][key], nil }) }
func (provider) Transform(cfg map[string]interface{}) error { return config.ReplaceObjects(cfg, "env", func(val map[string]interface{}) (interface{}, error) { env := val["$env"].(string) value := os.Getenv(env) typ, ok := val["type"] if !ok { typ = "string" } t, ok := typ.(string) if !ok { return nil, errors.New("'type' property in {$env, type} is not a string") } switch t { case "string": return value, nil case "number": v, err := strconv.ParseFloat(value, 64) if err != nil { return nil, fmt.Errorf( "Error parsing number from {$env: '%s'}, error: %s", env, err, ) } return v, nil case "json": var retval interface{} err := json.Unmarshal([]byte(value), &retval) if err != nil { return nil, fmt.Errorf( "Error parsing JSON from {$env: '%s'}, error: %s", env, err, ) } return retval, nil case "bool": return strings.ToLower(value) == "true", nil case "list": parts := strings.Split(value, " ") retval := make([]interface{}, len(parts)) for i, s := range parts { retval[i] = s } return retval, nil default: return nil, fmt.Errorf("Unsupported type: '%s' in {$env, type}", t) } }) }