Skip to content

Commit

Permalink
feat: add keyed sections and fields
Browse files Browse the repository at this point in the history
  • Loading branch information
yordis committed Dec 15, 2023
1 parent ac9d006 commit 812f44e
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 67 deletions.
127 changes: 75 additions & 52 deletions onepassword/data_source_onepassword_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,66 @@ import (

func dataSourceOnepasswordItem() *schema.Resource {
exactlyOneOfUUIDAndTitle := []string{"uuid", "title"}
fieldResource := &schema.Resource{
Description: fieldDescription,
Schema: map[string]*schema.Schema{
"id": {
Description: fieldIDDescription,
Type: schema.TypeString,
Computed: true,
},
"label": {
Description: fieldLabelDescription,
Type: schema.TypeString,
Computed: true,
},
"purpose": {
Description: fmt.Sprintf(enumDescription, fieldPurposeDescription, fieldPurposes),
Type: schema.TypeString,
Computed: true,
},
"type": {
Description: fmt.Sprintf(enumDescription, fieldTypeDescription, fieldTypes),
Type: schema.TypeString,
Computed: true,
},
"value": {
Description: fieldValueDescription,
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
},
}
sectionResource := &schema.Resource{
Description: sectionDescription,
Schema: map[string]*schema.Schema{
"id": {
Description: sectionIDDescription,
Type: schema.TypeString,
Computed: true,
},
"label": {
Description: sectionLabelDescription,
Type: schema.TypeString,
Computed: true,
},
"keyed_field": {
Description: sectionFieldsDescription,
Type: schema.TypeMap,
Computed: true,
Elem: fieldResource,
},
"field": {
Deprecated: "Use `keyed_field` instead.", // bringing the conversation up
Description: sectionFieldsDescription,
Type: schema.TypeList,
Computed: true,
MinItems: 0,
Elem: fieldResource,
},
},
}

return &schema.Resource{
Description: "Use this data source to get details of an item by its vault uuid and either the title or the uuid of the item.",
Expand Down Expand Up @@ -96,63 +156,19 @@ func dataSourceOnepasswordItem() *schema.Resource {
Optional: true,
Sensitive: true,
},
"keyed_sections": {
Description: sectionsDescription,
Type: schema.TypeMap,
Computed: true,
Elem: sectionResource,
},
"section": {
Deprecated: "Use `keyed_sections` instead.", // bringing the conversation up
Description: sectionsDescription,
Type: schema.TypeList,
Computed: true,
MinItems: 0,
Elem: &schema.Resource{
Description: sectionDescription,
Schema: map[string]*schema.Schema{
"id": {
Description: sectionIDDescription,
Type: schema.TypeString,
Computed: true,
},
"label": {
Description: sectionLabelDescription,
Type: schema.TypeString,
Computed: true,
},
"field": {
Description: sectionFieldsDescription,
Type: schema.TypeList,
Computed: true,
MinItems: 0,
Elem: &schema.Resource{
Description: fieldDescription,
Schema: map[string]*schema.Schema{
"id": {
Description: fieldIDDescription,
Type: schema.TypeString,
Computed: true,
},
"label": {
Description: fieldLabelDescription,
Type: schema.TypeString,
Computed: true,
},
"purpose": {
Description: fmt.Sprintf(enumDescription, fieldPurposeDescription, fieldPurposes),
Type: schema.TypeString,
Computed: true,
},
"type": {
Description: fmt.Sprintf(enumDescription, fieldTypeDescription, fieldTypes),
Type: schema.TypeString,
Computed: true,
},
"value": {
Description: fieldValueDescription,
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
},
},
},
},
},
Elem: sectionResource,
},
},
}
Expand Down Expand Up @@ -181,13 +197,16 @@ func dataSourceOnepasswordItemRead(ctx context.Context, data *schema.ResourceDat
data.Set("category", strings.ToLower(string(item.Category)))

dataSections := []interface{}{}
dataKeyedSections := make(map[string]interface{}, len(item.Sections))

for _, s := range item.Sections {
section := map[string]interface{}{}

section["id"] = s.ID
section["label"] = s.Label

fields := []interface{}{}
keyedFields := make(map[string]interface{}, len(item.Fields))

for _, f := range item.Fields {
if f.Section != nil && f.Section.ID == s.ID {
Expand All @@ -199,14 +218,18 @@ func dataSourceOnepasswordItemRead(ctx context.Context, data *schema.ResourceDat
dataField["value"] = f.Value

fields = append(fields, dataField)
keyedFields[f.Label] = dataField
}
}
section["field"] = fields
section["keyed_field"] = keyedFields

dataSections = append(dataSections, section)
dataKeyedSections[s.Label] = section
}

data.Set("section", dataSections)
data.Set("keyed_sections", dataKeyedSections)

for _, f := range item.Fields {
switch f.Purpose {
Expand Down
78 changes: 63 additions & 15 deletions onepassword/data_source_onepassword_item_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,31 @@ func compareItemToSource(t *testing.T, dataSourceData *schema.ResourceData, item
}
compareStringSlice(t, getTags(dataSourceData), item.Tags)

for _, section := range item.Sections {
keyedSection := dataSourceData.Get(fmt.Sprintf("keyed_sections.%s", section.Label)).(map[string]interface{})

if keyedSection == nil {
t.Errorf("Expected keyed section %v to exist", section.Label)
}

if keyedSection["id"] != section.ID {
t.Errorf("Expected keyed section %v to have id %v got %v", section.Label, section.ID, keyedSection["id"])
}

for _, field := range item.Fields {
if field.Section != nil && field.Section.ID == section.ID {
keyedField := dataSourceData.Get(fmt.Sprintf("keyed_sections.%s.keyed_field.%s", section.Label, field.Label)).(map[string]interface{})

if keyedField == nil {
t.Errorf("Expected keyed field %v to exist", field.Label)
}
if keyedField["id"] != field.ID {
t.Errorf("Expected keyed field %v to have id %v got %v", field.Label, field.ID, keyedField["id"])
}
}
}
}

for _, f := range item.Fields {
path := f.Label
if f.Section != nil {
Expand Down Expand Up @@ -136,8 +161,10 @@ func generateDataSource(t *testing.T, item *onepassword.Item) *schema.ResourceDa
}

func generateItem() *onepassword.Item {
fields, sections := generateFields()
item := onepassword.Item{}
item.Fields = generateFields()
item.Sections = sections
item.Fields = fields
item.ID = "79841a98-dd4a-4c34-8be5-32dca20a7328"
item.Vault.ID = "df2e9643-45ad-4ff9-8b98-996f801afa75"
item.Category = "USERNAME"
Expand All @@ -151,34 +178,55 @@ func generateItem() *onepassword.Item {
return &item
}

func generateFields() []*onepassword.ItemField {
func generateFields() ([]*onepassword.ItemField, []*onepassword.ItemSection) {
sections := []*onepassword.ItemSection{
{
ID: "r9d6nt77oacycnjhp3tm3ihjka",
Label: "", // seems to be the default section name
},
{
ID: "hbvbe4469kak5njjuthnhszcae",
Label: "Section A",
},
}

// TODO: this is confusing, based on the JSON payload, fields live inside of sections there is only
// payload.details.sections and inside of that there is a payload.details.sections.fields
fields := []*onepassword.ItemField{
{
Label: "username",
Value: "test_user",
Label: "username",
Value: "test_user",
Section: sections[0],
},
{
Label: "password",
Value: "test_password",
Label: "password",
Value: "test_password",
Section: sections[0],
},
{
Label: "hostname",
Value: "test_host",
Label: "hostname",
Value: "test_host",
Section: sections[0],
},
{
Label: "database",
Value: "test_database",
Label: "database",
Value: "test_database",
Section: sections[0],
},
{
Label: "port",
Value: "test_port",
Label: "port",
Value: "test_port",
Section: sections[0],
//Section: nil, TODO: why is Section a pointer when there HAVE to be a section for the field?
},
{
Label: "type",
Value: "test_type",
Label: "type",
Value: "test_type",
Section: sections[1],
},
}
return fields

return fields, sections
}

func compareStringSlice(t *testing.T, actual, expected []string) {
Expand Down

0 comments on commit 812f44e

Please sign in to comment.