diff --git a/port/cli/models.go b/port/cli/models.go index 9aa88b74..9ac2e332 100644 --- a/port/cli/models.go +++ b/port/cli/models.go @@ -47,10 +47,11 @@ type ( Blueprint struct { Meta - Identifier string `json:"identifier,omitempty"` - Title string `json:"title"` - Icon string `json:"icon"` - Schema BlueprintSchema `json:"schema"` + Identifier string `json:"identifier,omitempty"` + Title string `json:"title"` + Icon string `json:"icon"` + Schema BlueprintSchema `json:"schema"` + Relations map[string]Relation `json:"relations"` } Action struct { diff --git a/port/cli/relation.go b/port/cli/relation.go deleted file mode 100644 index 100171d0..00000000 --- a/port/cli/relation.go +++ /dev/null @@ -1,73 +0,0 @@ -package cli - -import ( - "context" - "fmt" -) - -func (c *PortClient) CreateRelation(ctx context.Context, bpID string, r *Relation) (string, error) { - url := "v1/blueprints/{identifier}/relations" - result := map[string]interface{}{} - resp, err := c.Client.R(). - SetBody(r). - SetContext(ctx). - SetResult(&result). - SetPathParam("identifier", bpID). - Post(url) - if err != nil { - return "", err - } - if resp.StatusCode() > 299 || resp.StatusCode() < 200 || !result["ok"].(bool) { - return "", fmt.Errorf("failed to create relation, got: %s", resp.Body()) - } - return result["identifier"].(string), nil -} - -func (c *PortClient) ReadRelations(ctx context.Context, blueprintID string) ([]*Relation, error) { - url := "v1/relations" - result := map[string]interface{}{} - resp, err := c.Client.R(). - SetContext(ctx). - SetResult(&result). - Get(url) - if err != nil { - return nil, err - } - if !result["ok"].(bool) { - return nil, fmt.Errorf("failed to create relation, got: %s", resp.Body()) - } - allRelations := result["relations"].([]interface{}) - bpRelations := make([]*Relation, 0) - for _, relation := range allRelations { - r := relation.(map[string]interface{}) - if r["source"] != blueprintID { - continue - } - bpRelations = append(bpRelations, &Relation{ - Target: r["target"].(string), - Required: r["required"].(bool), - Many: r["many"].(bool), - Title: r["title"].(string), - Identifier: r["identifier"].(string), - }) - } - return bpRelations, nil -} - -func (c *PortClient) DeleteRelation(ctx context.Context, blueprintID, relationID string) error { - url := "v1/blueprints/{blueprint_identifier}/relations/{relation_identifier}" - result := map[string]interface{}{} - resp, err := c.Client.R(). - SetContext(ctx). - SetResult(&result). - SetPathParam("blueprint_identifier", blueprintID). - SetPathParam("relation_identifier", relationID). - Delete(url) - if err != nil { - return err - } - if !result["ok"].(bool) { - return fmt.Errorf("failed to delete relation, got: %s", resp.Body()) - } - return nil -} diff --git a/port/resource_port_blueprint.go b/port/resource_port_blueprint.go index b346d2b5..d88d8be8 100644 --- a/port/resource_port_blueprint.go +++ b/port/resource_port_blueprint.go @@ -150,30 +150,8 @@ func readBlueprint(ctx context.Context, d *schema.ResourceData, m interface{}) d return diag.FromErr(err) } writeBlueprintFieldsToResource(d, b) - relations, err := c.ReadRelations(ctx, d.Id()) - if err != nil { - return diag.FromErr(err) - } - writeBlueprintRelationsToResource(d, relations) - return diags -} -func writeBlueprintRelationsToResource(d *schema.ResourceData, relations []*cli.Relation) { - rels := schema.Set{F: func(i interface{}) int { - id := (i.(map[string]interface{}))["identifier"].(string) - return schema.HashString(id) - }} - for _, v := range relations { - r := map[string]interface{}{ - "identifier": v.Identifier, - "title": v.Title, - "target": v.Target, - "required": v.Required, - "many": v.Many, - } - rels.Add(r) - } - d.Set("relations", &rels) + return diags } func writeBlueprintFieldsToResource(d *schema.ResourceData, b *cli.Blueprint) { @@ -237,96 +215,40 @@ func blueprintResourceToBody(d *schema.ResourceData) (*cli.Blueprint, error) { properties[p["identifier"].(string)] = propFields } - b.Schema = cli.BlueprintSchema{Properties: properties} - return b, nil -} - -func deleteBlueprint(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - var diags diag.Diagnostics - c := m.(*cli.PortClient) - err := c.DeleteBlueprint(ctx, d.Id()) - if err != nil { - return diag.FromErr(err) - } - return diags -} - -func getRelations(d *schema.ResourceData) (rel []*cli.Relation) { - relations, ok := d.GetOk("relations") - if !ok { - return nil - } - for _, relation := range relations.(*schema.Set).List() { - relation := relation.(map[string]interface{}) - r := &cli.Relation{} - if t, ok := relation["title"]; ok { - r.Title = t.(string) - } - if t, ok := relation["target"]; ok { - r.Target = t.(string) + rels := d.Get("relations").(*schema.Set) + relations := make(map[string]cli.Relation, props.Len()) + for _, rel := range rels.List() { + p := rel.(map[string]interface{}) + relationFields := cli.Relation{} + if t, ok := p["required"]; ok && t != "" { + relationFields.Required = t.(bool) } - if i, ok := relation["identifier"]; ok { - r.Identifier = i.(string) + if t, ok := p["many"]; ok && t != "" { + relationFields.Many = t.(bool) } - if req, ok := relation["required"]; ok { - r.Required = req.(bool) + if d, ok := p["title"]; ok && d != "" { + relationFields.Title = d.(string) } - if m, ok := relation["many"]; ok { - r.Many = m.(bool) + if d, ok := p["target"]; ok && d != "" { + relationFields.Target = d.(string) } - rel = append(rel, r) - } - return -} -func createRelations(ctx context.Context, d *schema.ResourceData, m interface{}) error { - c := m.(*cli.PortClient) - rels := getRelations(d) - for _, r := range rels { - _, err := c.CreateRelation(ctx, d.Id(), r) - if err != nil { - return err - } + relations[p["identifier"].(string)] = relationFields } - return nil -} -func contains(s []string, e string) bool { - for _, a := range s { - if a == e { - return true - } - } - return false + b.Schema = cli.BlueprintSchema{Properties: properties} + b.Relations = relations + return b, nil } -// patchDeleteDeprecatedRelations deletes relations that are no longer present in the resource. -// This is necessary because we bundled relations inside the blueprint resource. -// In the future, the API of blueprints should support getting the relations and then we can delete this patch. -func patchDeleteDeprecatedRelations(ctx context.Context, d *schema.ResourceData, m interface{}) error { +func deleteBlueprint(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + var diags diag.Diagnostics c := m.(*cli.PortClient) - rels := getRelations(d) - ids := make([]string, len(rels)) - for i, r := range rels { - ids[i] = r.Identifier - } - remoteRelations, err := c.ReadRelations(ctx, d.Id()) + err := c.DeleteBlueprint(ctx, d.Id()) if err != nil { - return err - } - toDel := make([]*cli.Relation, 0) - for _, r := range remoteRelations { - if !contains(ids, r.Identifier) { - toDel = append(toDel, r) - } - } - for _, r := range toDel { - err := c.DeleteRelation(ctx, d.Id(), r.Identifier) - if err != nil { - return err - } + return diag.FromErr(err) } - return nil + return diags } func createBlueprint(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -346,10 +268,7 @@ func createBlueprint(ctx context.Context, d *schema.ResourceData, m interface{}) return diag.FromErr(err) } writeBlueprintComputedFieldsToResource(d, bp) - err = createRelations(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } + return diags } @@ -370,14 +289,6 @@ func updateBlueprint(ctx context.Context, d *schema.ResourceData, m interface{}) return diag.FromErr(err) } writeBlueprintComputedFieldsToResource(d, bp) - err = patchDeleteDeprecatedRelations(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } - err = createRelations(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } return diags }