Skip to content
Snippets Groups Projects
Commit f067a456 authored by Michael Irwin's avatar Michael Irwin
Browse files

Merge branch 'service-managers-admins' into 'main'

#6 Support services on admins/managers

See merge request !3
parents 286f7f23 1e0ae32c
Branches 0.3.1
Tags 0.3.0
1 merge request!3#6 Support services on admins/managers
Pipeline #341696 passed with stage
in 6 minutes and 9 seconds
example/
.idea/
build/terraform*
**/*.swp
# Binaries for programs and plugins
*.exe
......
......@@ -12,9 +12,15 @@ resource "vted_group" "my_group" {
suppress_display = true
suppress_members = true
admins = ["mikesir"]
admins {
people = ["mikesir"]
services = ["gateway"]
}
contacts = ["mikesir", "ceharris"]
managers = ["mikesir", "ceharris"]
managers {
people = ["mikesir", "ceharris"]
services = ["gateway"]
}
members {
people = ["mikesir", "ceharris"]
......@@ -29,9 +35,9 @@ The following arguments are supported:
- `name` - (Required) The name of the group.
- `expiration_date` - (Optional) The expiration date of the group. Supported formats are RFC3339 and `YYYY-MM-DD`. Note that when using `YYYY-MM-DD`, the time is set to 00:00 UTC, which might cause date display differences.
- `admins` - (Required) A collection of PIDs that are allowed to administer the group.
- `admins` - (Required) A map of the `people` (PIDs) and `services` (uusids) that are allowed to administer the group. **Note**: The TF provider service account is always a service admin for the group.
- `contacts` - (Required) A collection of PIDs that are contacts for the group.
- `managers` - (Optional) A collection of PIDs that are allowed to manage the group membership.
- `managers` - (Optional) A map of the `people` (PIDs) and `services` (uusids) that are allowed to manage the group membership.
- `members` - (Optional) A map of the `people` (PIDs) and `groups` (uusids) that are members of this group
- `suppress_display` - (Optional) Boolean, defaults to true. Is this group visible in public listings?
- `suppress_members` - (Optional) Boolean, defaults to true. Is this group's membership visible in public queries?
......
......@@ -52,8 +52,8 @@ func dataSourceVtEdGroup() *schema.Resource {
},
"managers": {
Type: schema.TypeList,
Description: "The contacts of the group",
MinItems: 1,
Description: "The managers of the group",
MinItems: 0,
Computed: true,
Elem: PersonResource(),
},
......
......@@ -58,12 +58,28 @@ func resourceVtEdGroup() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString},
},
"admins": &schema.Schema{
Type: schema.TypeSet,
Description: "PIDs of administrators for the group",
Type: schema.TypeList,
Description: "Administrators for the group",
Required: true,
MinItems: 1,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"people": {
Type: schema.TypeSet,
Description: "PIDs of the person administrators of the group",
Optional: true,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
},
"services": {
Type: schema.TypeSet,
Description: "UUSIDs of the service administrators of the group",
Optional: true,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"contacts": &schema.Schema{
Type: schema.TypeSet,
......@@ -74,11 +90,27 @@ func resourceVtEdGroup() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString},
},
"managers": &schema.Schema{
Type: schema.TypeSet,
Description: "PIDs of managers for the group",
Type: schema.TypeList,
Description: "Managers for the group",
Optional: true,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"people": {
Type: schema.TypeSet,
Description: "PIDs of the person managers of the group",
Optional: true,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
},
"services": {
Type: schema.TypeSet,
Description: "UUSIDs of the service managers of the group",
Optional: true,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"members": &schema.Schema{
Type: schema.TypeList,
......@@ -113,10 +145,12 @@ func resourceVtEdGroupCreate(d *schema.ResourceData, meta interface{}) error {
groupName := d.Get("name").(string)
err := validateAdminsAndContacts(d.Get("admins").(*schema.Set), d.Get("contacts").(*schema.Set))
err := validateAdminsAndContacts(d.Get("admins").([]interface{}), d.Get("contacts").(*schema.Set))
if err != nil {
return err
}
// provider service ID always gets added as a service admin for the group
d.Get("admins").([]interface{})[0].(map[string]interface{})["services"].(*schema.Set).Add(providerConfig.serviceId)
_, err = edClient.Post("/groups", groupConfigToFormBody(d))
if err != nil {
......@@ -130,12 +164,12 @@ func resourceVtEdGroupCreate(d *schema.ResourceData, meta interface{}) error {
return err
}
err = syncReplicationTargets(groupName, d.Get("replication_targets").(*schema.Set), nil, edClient)
err = syncManagersAdmins(groupName, "managers", d.Get("managers").([]interface{}), nil, edClient)
if err != nil {
return err
}
err = syncRole(groupName, "managers", d.Get("managers").(*schema.Set), nil, edClient, "person")
err = syncManagersAdmins(groupName, "administrators", d.Get("admins").([]interface{}), nil, edClient)
if err != nil {
return err
}
......@@ -145,9 +179,51 @@ func resourceVtEdGroupCreate(d *schema.ResourceData, meta interface{}) error {
return err
}
err = syncReplicationTargets(groupName, d.Get("replication_targets").(*schema.Set), nil, edClient)
if err != nil {
return err
}
return resourceVtEdGroupRead(d, meta)
}
func syncManagersAdmins(groupName string, roleName string, newCollection []interface{}, oldCollection []interface{}, client *EdClient) error {
var newPeopleSet *schema.Set
var oldPeopleSet *schema.Set
var newServicesSet *schema.Set
var oldServicesSet *schema.Set
if len(newCollection) > 0 && newCollection[0] != nil {
newMembers := newCollection[0].(map[string]interface{})
newPeopleSet = newMembers["people"].(*schema.Set)
newServicesSet = newMembers["services"].(*schema.Set)
} else {
newPeopleSet = schema.NewSet(schema.HashString, []interface{}{})
newServicesSet = schema.NewSet(schema.HashString, []interface{}{})
}
if len(oldCollection) > 0 {
oldMembers := oldCollection[0].(map[string]interface{})
oldPeopleSet = oldMembers["people"].(*schema.Set)
oldServicesSet = oldMembers["services"].(*schema.Set)
} else {
oldPeopleSet = schema.NewSet(schema.HashString, []interface{}{})
oldServicesSet = schema.NewSet(schema.HashString, []interface{}{})
}
err := syncRole(groupName, roleName, newPeopleSet, oldPeopleSet, client, "person")
if err != nil {
return err
}
err = syncRole(groupName, roleName, newServicesSet, oldServicesSet, client, "service")
if err != nil {
return err
}
return nil
}
func syncMembers(groupName string, newMemberCollection []interface{}, oldMemberCollection []interface{}, client *EdClient) error {
var newPeopleSet *schema.Set
var oldPeopleSet *schema.Set
......@@ -198,10 +274,10 @@ func resourceVtEdGroupRead(d *schema.ResourceData, meta interface{}) error {
d.Set("creation_date", groupInfo.Get("creationDate").String())
d.Set("suppress_members", groupInfo.Get("suppressMembers").Bool())
d.Set("suppress_display", groupInfo.Get("suppressDisplay").Bool())
d.Set("admins", convertManagersAdmins(groupInfo.Get("administrators").Array()))
d.Set("replication_targets", groupInfo.Get("targets").Array())
d.Set("admins", convertFlattenedPeople(groupInfo.Get("administrators").Array()))
d.Set("contacts", convertFlattenedPeople(groupInfo.Get("contacts").Array()))
d.Set("managers", convertFlattenedPeople(groupInfo.Get("managers").Array()))
d.Set("managers", convertManagersAdmins(groupInfo.Get("managers").Array()))
d.Set("viewers", convertViewers(groupInfo.Get("viewers").Array()))
d.Set("members", convertMembers(groupInfo.Get("members").Array()))
......@@ -227,9 +303,12 @@ func resourceVtEdGroupUpdate(d *schema.ResourceData, meta interface{}) error {
}
}
// provider service ID always gets added as a service admin for the group
d.Get("admins").([]interface{})[0].(map[string]interface{})["services"].(*schema.Set).Add(providerConfig.serviceId)
if d.HasChange("admins") {
oldValue, newValue := d.GetChange("admins")
err := syncRole(groupName, "administrators", newValue.(*schema.Set), oldValue.(*schema.Set), edClient, "person")
err := syncManagersAdmins(groupName, "administrators", newValue.([]interface{}), oldValue.([]interface{}), edClient)
if err != nil {
return err
}
......@@ -245,7 +324,7 @@ func resourceVtEdGroupUpdate(d *schema.ResourceData, meta interface{}) error {
if d.HasChange("managers") {
oldValue, newValue := d.GetChange("managers")
err := syncRole(groupName, "managers", newValue.(*schema.Set), oldValue.(*schema.Set), edClient, "person")
err := syncManagersAdmins(groupName, "managers", newValue.([]interface{}), oldValue.([]interface{}), edClient)
if err != nil {
return err
}
......@@ -301,18 +380,29 @@ func suppressTimeChange() func(k string, old string, new string, d *schema.Resou
}
}
func validateAdminsAndContacts(admins *schema.Set, contacts *schema.Set) error {
func validateAdminsAndContacts(admins []interface{}, contacts *schema.Set) error {
var adminPeopleSet *schema.Set
var adminServicesSet *schema.Set
adminsAndContacts := make(map[string]bool)
for _, n := range admins.List() {
adminsAndContacts[n.(string)] = true
if len(admins) > 0 && admins[0] != nil {
adminMap := admins[0].(map[string]interface{})
adminPeopleSet = adminMap["people"].(*schema.Set)
adminServicesSet = adminMap["services"].(*schema.Set)
for _, n := range adminPeopleSet.List() {
adminsAndContacts[n.(string)] = true
}
for _, n := range adminServicesSet.List() {
adminsAndContacts[n.(string)] = true
}
}
for _, n := range contacts.List() {
adminsAndContacts[n.(string)] = true
}
if len(adminsAndContacts) == 1 {
if len(adminsAndContacts) <= 1 {
return errors.New("two distinct users are required for admins and contacts")
}
......@@ -324,7 +414,9 @@ func groupConfigToFormBody(d *schema.ResourceData) string {
formDataObj := url.Values{}
formDataObj.Set("uugid", d.Get("name").(string))
for _, name := range d.Get("admins").(*schema.Set).List() {
// Creation only supports people admins
adminMap := d.Get("admins").([]interface{})[0].(map[string]interface{})
for _, name := range adminMap["people"].(*schema.Set).List() {
formDataObj.Add("administrator", name.(string))
}
......@@ -469,6 +561,29 @@ func parseDateString(date string) (time.Time, error) {
return parsedDate, nil
}
func convertManagersAdmins(members []gjson.Result) []map[string]*schema.Set {
people := schema.NewSet(schema.HashString, []interface{}{})
services := schema.NewSet(schema.HashString, []interface{}{})
for _, member := range members {
memberKind := member.Get("kind").String()
if memberKind == "person" {
people.Add(member.Get("pid").String())
} else if memberKind == "service" {
services.Add(member.Get("uusid").String())
}
}
values := map[string]*schema.Set{
"people": people,
"services": services,
}
return []map[string]*schema.Set{
values,
}
}
func convertMembers(members []gjson.Result) []map[string]*schema.Set {
people := schema.NewSet(schema.HashString, []interface{}{})
groups := schema.NewSet(schema.HashString, []interface{}{})
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment