Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Feature Request: Get Groups by Custom Attribute #1617

Open
adrianliechti opened this issue Jan 3, 2023 · 12 comments
Open

Feature Request: Get Groups by Custom Attribute #1617

adrianliechti opened this issue Jan 3, 2023 · 12 comments

Comments

@adrianliechti
Copy link

According the GitLab Docs, there is a handy query to get groups by custom attributes:
You can filter by custom attributes](https://docs.gitlab.com/ee/api/custom_attributes.html with:
GET /groups?custom_attributes[key]=value&custom_attributes[other_key]=other_value

I have not found this option in the current version (of this amazing lib).
Could you consider an option to do it? Maybe using a map on the ListGroupsOptions? or by having a RequestOptionFunc WithCustomQuery(key, value)

In the meantime, I used this workaround:

func (g *GitLab) groupByAttribute(ctx context.Context, key, value string) (*gitlab.Group, error) {
	opt := &gitlab.ListGroupsOptions{
		WithCustomAttributes: gitlab.Bool(true),
	}

	withCustomAttribute := func() gitlab.RequestOptionFunc {
		return func(req *retryablehttp.Request) error {
			query := fmt.Sprintf("custom_attributes[%s]=%s", key, value)

			if req.URL.RawQuery != "" {
				query += "&" + req.URL.RawQuery
			}

			req.URL.RawQuery = query

			return nil
		}
	}

	groups, _, err := g.client.Groups.ListGroups(opt, gitlab.WithContext(ctx), withCustomAttribute())

	if err != nil {
		return nil, err
	}

	if len(groups) == 0 {
		return nil, errors.New("no group found with key: " + key)
	}

	if len(groups) > 1 {
		return nil, errors.New("multiple groups found with key: " + key)
	}

	return groups[0], nil
}
@theoriginalstove
Copy link
Contributor

Going with the RequestOptionFunc seems the most straightforward way to go about this imo.

@svanharmelen
Copy link
Member

If supported and documented it should probably become a field in the appropriate options struct.

@theoriginalstove
Copy link
Contributor

https://docs.gitlab.com/ee/api/groups.html#list-groups looks to be documented at the end of the list-groups section but only as a URL param. So then the new field could be a map on the ListGroupOptions like so?

type ListGroupsOptions struct {
	...
	CustomAttributes map[string]string `url:"custom_attributes,omitempty" json:"-"`
}

@theoriginalstove
Copy link
Contributor

theoriginalstove commented Feb 10, 2023

So this is turning out to be a little trickier to implement than I thought with adding the CustomAttributes as a field in the ListGroupsOptions struct. After trying out a few things, I think I discovered it won't work with CustomAttributes as a map[string]string lol.

I'm trying to follow the examples go-querystring has of using nested structs to encode nested values in order to get custom_attributes[key]=value but I think it could get messy for developers if they want to use this field.

Maybe my test is wrong (and I'm sure I'm making some dumb mistakes after a long day of writing code at work lol) but testing the params results in:

gitlab_test.go:89: Request query: custom_attributes=%7Bvalue%7D, want custom_attributes[key]=value

when the struct for ListGroupsOptions looks like:

type ListGroupsOptions struct {
    ...
    CustomAttributes interface{} `url:"custom_attributes,omitempty" json:"-"`
}

and in the tests ListGroupsOptions is declared as:

opts := &ListGroupsOptions{
	CustomAttributes: struct {
		Key string `url:"key"`
	}{
		Key: "value",
	},
}

the brackets [] are getting url encoded, and for some reason I can't think of at this moment. I'll have to come back to this when I find some time with fresh eyes as well.

@adrianliechti
Copy link
Author

adrianliechti commented Feb 10, 2023

not sure if this is any helpful, but i used this included helper in
the rest past

q := url.Values{}
q.Add("a", "value-a")
q.Add("b", "value-b")

encoded := q.Encode()
print(encoded)

@heidiberry
Copy link
Contributor

All the endpoints on https://docs.gitlab.com/ee/api/custom_attributes.html are covered within https://github.com/xanzy/go-gitlab/blob/main/custom_attributes.go, so this issue could be closed

@svanharmelen
Copy link
Member

Thanks for the heads up @heidiberry 👍🏻

@adrianliechti
Copy link
Author

@svanharmelen @heidiberry
I'm not sure how this API allows to list groups (other resouces) with specify custom attributes (filtering the list).
The API seems to list custom attributes for a resource; but this would result in: loading all groups, call for each group the custom attributes API and then check...

@heidiberry
Copy link
Contributor

@adrianliechti Ah I thought you were wanting the API from the docs linked in the description. Are you talking about the with_custom_attributes filter on some of the endpoints in the group API: https://docs.gitlab.com/ee/api/groups.html?

@heidiberry
Copy link
Contributor

I think I've found what you were meaning now, the custom_attributes[key]=value pattern. Yes you are right, this isn't currently supported

@theoriginalstove
Copy link
Contributor

I should still have the code that implements this, might be a little stale. I completely forgot to come back to finishing this lol

@svanharmelen
Copy link
Member

I'll reopen the issue 😏

@svanharmelen svanharmelen reopened this May 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants