diff --git a/doppler/api.go b/doppler/api.go index a18fa05..b9877c2 100644 --- a/doppler/api.go +++ b/doppler/api.go @@ -915,6 +915,34 @@ func (client APIClient) UpdateConfigInheritable(ctx context.Context, project str return &result.Config, nil } +func (client APIClient) UpdateConfigInherits(ctx context.Context, project string, config string, inherits []ConfigDescriptor) (*Config, error) { + payload := map[string]interface{}{ + "project": project, + "config": config, + "inherits": inherits, + } + + if len(inherits) == 0 { + // If we don't manually instantiate an empty array here, go will marshal the inherits property as nil instead of [] + payload["inherits"] = []ConfigDescriptor{} + } + + body, err := json.Marshal(payload) + + if err != nil { + return nil, &APIError{Err: err, Message: "Unable to serialize config"} + } + response, err := client.PerformRequestWithRetry(ctx, "POST", "/v3/configs/config/inherits", []QueryParam{}, body) + if err != nil { + return nil, err + } + var result ConfigResponse + if err = json.Unmarshal(response.Body, &result); err != nil { + return nil, &APIError{Err: err, Message: "Unable to parse config"} + } + return &result.Config, nil +} + func (client APIClient) DeleteConfig(ctx context.Context, project string, name string) error { payload := map[string]interface{}{ "project": project, diff --git a/doppler/resource_config.go b/doppler/resource_config.go index bf90e08..e786878 100644 --- a/doppler/resource_config.go +++ b/doppler/resource_config.go @@ -41,10 +41,32 @@ func resourceConfig() *schema.Resource { Type: schema.TypeBool, Optional: true, }, + "inherits": { + Description: "A list of other Doppler config IDs that this config inherits from. IDs match the format \"projectSlug.environmentSlug.configName\" (e.g. backend.stg.stg), which is most easily retrieved as the id of a doppler_config resource (e.g. doppler_config.backend_stg.id)", + Optional: true, + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, }, } } +func inheritsArgToDescriptor(inherits []interface{}) ([]ConfigDescriptor, error) { + var descriptors []ConfigDescriptor + + for _, id := range inherits { + proj, _, conf, err := parseConfigResourceId(id.(string)) + if err != nil { + return nil, err + } + descriptors = append(descriptors, ConfigDescriptor{ProjectSlug: proj, ConfigName: conf}) + } + + return descriptors, nil +} + func resourceConfigCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(APIClient) @@ -53,6 +75,7 @@ func resourceConfigCreate(ctx context.Context, d *schema.ResourceData, m interfa environment := d.Get("environment").(string) name := d.Get("name").(string) inheritable := d.Get("inheritable").(bool) + inherits := d.Get("inherits").([]interface{}) var config *Config var err error @@ -79,6 +102,14 @@ func resourceConfigCreate(ctx context.Context, d *schema.ResourceData, m interfa } } + if len(inherits) > 0 { + descriptors, nil := inheritsArgToDescriptor(inherits) + if err != nil { + return diag.FromErr(err) + } + config, err = client.UpdateConfigInherits(ctx, project, name, descriptors) + } + d.SetId(config.getResourceId()) return diags @@ -94,11 +125,39 @@ func resourceConfigUpdate(ctx context.Context, d *schema.ResourceData, m interfa } newName := d.Get("name").(string) - config, err := client.RenameConfig(ctx, project, currentName, newName) - if err != nil { - return diag.FromErr(err) + if d.HasChange("name") { + config, err := client.RenameConfig(ctx, project, currentName, newName) + if err != nil { + return diag.FromErr(err) + } + d.SetId(config.getResourceId()) } - d.SetId(config.getResourceId()) + + if d.HasChange("inheritable") { + _, err = client.UpdateConfigInheritable(ctx, project, newName, d.Get("inheritable").(bool)) + if err != nil { + oldValue, _ := d.GetChange("inheritable") + d.Set("inheritable", oldValue) + return diag.FromErr(err) + } + } + + if d.HasChange("inherits") { + inherits := d.Get("inherits").([]interface{}) + + descriptors, nil := inheritsArgToDescriptor(inherits) + if err != nil { + return diag.FromErr(err) + } + + _, err = client.UpdateConfigInherits(ctx, project, newName, descriptors) + if err != nil { + oldValue, _ := d.GetChange("inherits") + d.Set("inherits", oldValue) + return diag.FromErr(err) + } + } + return diags }