Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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 join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants