IAM: Add role to User (#111256)

* codegen fix

* Return user role from the legacy store

* Lint

* Add tests, gen openapi

* make generate

* revert go.mod, go.sum, go.work.sum changes

* Update go.mod and go.sum
This commit is contained in:
Misi
2025-09-19 11:12:00 +02:00
committed by GitHub
parent f48efa1003
commit c012a95fa1
39 changed files with 1485 additions and 274 deletions
+2 -2
View File
@@ -338,7 +338,7 @@ require (
github.com/sethvargo/go-retry v0.3.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect
@@ -433,7 +433,7 @@ require (
gopkg.in/mail.v2 v2.3.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/src-d/go-errors.v1 v1.0.0 // indirect
gopkg.in/telebot.v3 v3.2.1 // indirect
gopkg.in/telebot.v3 v3.3.8 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.34.1 // indirect
+4 -4
View File
@@ -1217,8 +1217,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 h1:OfRzdxCzDhp+rsKWXuOO2I/quKMJ/+TQwVbIP/gltZg=
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6S6I7v6WXb+IjhMuZEYfH/RJ5RwEWnEo5BMg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -2058,8 +2058,8 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/src-d/go-errors.v1 v1.0.0 h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIfc=
gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMMNxPCbdYg=
gopkg.in/telebot.v3 v3.2.1 h1:3I4LohaAyJBiivGmkfB+CiVu7QFOWkuZ4+KHgO/G3rs=
gopkg.in/telebot.v3 v3.2.1/go.mod h1:GJKwwWqp9nSkIVN51eRKU78aB5f5OnQuWdwiIZfPbko=
gopkg.in/telebot.v3 v3.3.8 h1:uVDGjak9l824FN9YARWUHMsiNZnlohAVwUycw21k6t8=
gopkg.in/telebot.v3 v3.3.8/go.mod h1:1mlbqcLTVSfK9dx7fdp+Nb5HZsy4LLPtpZTKmwhwtzM=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+1 -2
View File
@@ -8,6 +8,5 @@ UserSpec: {
login: string
name: string
provisioned: bool
// What to do with salt, rands and password?
role: string
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type CoreRoleClient struct {
client *resource.TypedClient[*CoreRole, *CoreRoleList]
}
func NewCoreRoleClient(client resource.Client) *CoreRoleClient {
return &CoreRoleClient{
client: resource.NewTypedClient[*CoreRole, *CoreRoleList](client, CoreRoleKind()),
}
}
func NewCoreRoleClientFromGenerator(generator resource.ClientGenerator) (*CoreRoleClient, error) {
c, err := generator.ClientFor(CoreRoleKind())
if err != nil {
return nil, err
}
return NewCoreRoleClient(c), nil
}
func (c *CoreRoleClient) Get(ctx context.Context, identifier resource.Identifier) (*CoreRole, error) {
return c.client.Get(ctx, identifier)
}
func (c *CoreRoleClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*CoreRoleList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *CoreRoleClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*CoreRoleList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *CoreRoleClient) Create(ctx context.Context, obj *CoreRole, opts resource.CreateOptions) (*CoreRole, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = CoreRoleKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *CoreRoleClient) Update(ctx context.Context, obj *CoreRole, opts resource.UpdateOptions) (*CoreRole, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *CoreRoleClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*CoreRole, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *CoreRoleClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus CoreRoleStatus, opts resource.UpdateOptions) (*CoreRole, error) {
return c.client.Update(ctx, &CoreRole{
TypeMeta: metav1.TypeMeta{
Kind: CoreRoleKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *CoreRoleClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type GlobalRoleClient struct {
client *resource.TypedClient[*GlobalRole, *GlobalRoleList]
}
func NewGlobalRoleClient(client resource.Client) *GlobalRoleClient {
return &GlobalRoleClient{
client: resource.NewTypedClient[*GlobalRole, *GlobalRoleList](client, GlobalRoleKind()),
}
}
func NewGlobalRoleClientFromGenerator(generator resource.ClientGenerator) (*GlobalRoleClient, error) {
c, err := generator.ClientFor(GlobalRoleKind())
if err != nil {
return nil, err
}
return NewGlobalRoleClient(c), nil
}
func (c *GlobalRoleClient) Get(ctx context.Context, identifier resource.Identifier) (*GlobalRole, error) {
return c.client.Get(ctx, identifier)
}
func (c *GlobalRoleClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*GlobalRoleList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *GlobalRoleClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*GlobalRoleList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *GlobalRoleClient) Create(ctx context.Context, obj *GlobalRole, opts resource.CreateOptions) (*GlobalRole, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = GlobalRoleKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *GlobalRoleClient) Update(ctx context.Context, obj *GlobalRole, opts resource.UpdateOptions) (*GlobalRole, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *GlobalRoleClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*GlobalRole, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *GlobalRoleClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus GlobalRoleStatus, opts resource.UpdateOptions) (*GlobalRole, error) {
return c.client.Update(ctx, &GlobalRole{
TypeMeta: metav1.TypeMeta{
Kind: GlobalRoleKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *GlobalRoleClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type GlobalRoleBindingClient struct {
client *resource.TypedClient[*GlobalRoleBinding, *GlobalRoleBindingList]
}
func NewGlobalRoleBindingClient(client resource.Client) *GlobalRoleBindingClient {
return &GlobalRoleBindingClient{
client: resource.NewTypedClient[*GlobalRoleBinding, *GlobalRoleBindingList](client, GlobalRoleBindingKind()),
}
}
func NewGlobalRoleBindingClientFromGenerator(generator resource.ClientGenerator) (*GlobalRoleBindingClient, error) {
c, err := generator.ClientFor(GlobalRoleBindingKind())
if err != nil {
return nil, err
}
return NewGlobalRoleBindingClient(c), nil
}
func (c *GlobalRoleBindingClient) Get(ctx context.Context, identifier resource.Identifier) (*GlobalRoleBinding, error) {
return c.client.Get(ctx, identifier)
}
func (c *GlobalRoleBindingClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*GlobalRoleBindingList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *GlobalRoleBindingClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*GlobalRoleBindingList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *GlobalRoleBindingClient) Create(ctx context.Context, obj *GlobalRoleBinding, opts resource.CreateOptions) (*GlobalRoleBinding, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = GlobalRoleBindingKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *GlobalRoleBindingClient) Update(ctx context.Context, obj *GlobalRoleBinding, opts resource.UpdateOptions) (*GlobalRoleBinding, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *GlobalRoleBindingClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*GlobalRoleBinding, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *GlobalRoleBindingClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus GlobalRoleBindingStatus, opts resource.UpdateOptions) (*GlobalRoleBinding, error) {
return c.client.Update(ctx, &GlobalRoleBinding{
TypeMeta: metav1.TypeMeta{
Kind: GlobalRoleBindingKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *GlobalRoleBindingClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type ResourcePermissionClient struct {
client *resource.TypedClient[*ResourcePermission, *ResourcePermissionList]
}
func NewResourcePermissionClient(client resource.Client) *ResourcePermissionClient {
return &ResourcePermissionClient{
client: resource.NewTypedClient[*ResourcePermission, *ResourcePermissionList](client, ResourcePermissionKind()),
}
}
func NewResourcePermissionClientFromGenerator(generator resource.ClientGenerator) (*ResourcePermissionClient, error) {
c, err := generator.ClientFor(ResourcePermissionKind())
if err != nil {
return nil, err
}
return NewResourcePermissionClient(c), nil
}
func (c *ResourcePermissionClient) Get(ctx context.Context, identifier resource.Identifier) (*ResourcePermission, error) {
return c.client.Get(ctx, identifier)
}
func (c *ResourcePermissionClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*ResourcePermissionList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *ResourcePermissionClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*ResourcePermissionList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *ResourcePermissionClient) Create(ctx context.Context, obj *ResourcePermission, opts resource.CreateOptions) (*ResourcePermission, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = ResourcePermissionKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *ResourcePermissionClient) Update(ctx context.Context, obj *ResourcePermission, opts resource.UpdateOptions) (*ResourcePermission, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *ResourcePermissionClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*ResourcePermission, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *ResourcePermissionClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus ResourcePermissionStatus, opts resource.UpdateOptions) (*ResourcePermission, error) {
return c.client.Update(ctx, &ResourcePermission{
TypeMeta: metav1.TypeMeta{
Kind: ResourcePermissionKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *ResourcePermissionClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type RoleClient struct {
client *resource.TypedClient[*Role, *RoleList]
}
func NewRoleClient(client resource.Client) *RoleClient {
return &RoleClient{
client: resource.NewTypedClient[*Role, *RoleList](client, RoleKind()),
}
}
func NewRoleClientFromGenerator(generator resource.ClientGenerator) (*RoleClient, error) {
c, err := generator.ClientFor(RoleKind())
if err != nil {
return nil, err
}
return NewRoleClient(c), nil
}
func (c *RoleClient) Get(ctx context.Context, identifier resource.Identifier) (*Role, error) {
return c.client.Get(ctx, identifier)
}
func (c *RoleClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*RoleList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *RoleClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*RoleList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *RoleClient) Create(ctx context.Context, obj *Role, opts resource.CreateOptions) (*Role, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = RoleKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *RoleClient) Update(ctx context.Context, obj *Role, opts resource.UpdateOptions) (*Role, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *RoleClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*Role, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *RoleClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus RoleStatus, opts resource.UpdateOptions) (*Role, error) {
return c.client.Update(ctx, &Role{
TypeMeta: metav1.TypeMeta{
Kind: RoleKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *RoleClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type RoleBindingClient struct {
client *resource.TypedClient[*RoleBinding, *RoleBindingList]
}
func NewRoleBindingClient(client resource.Client) *RoleBindingClient {
return &RoleBindingClient{
client: resource.NewTypedClient[*RoleBinding, *RoleBindingList](client, RoleBindingKind()),
}
}
func NewRoleBindingClientFromGenerator(generator resource.ClientGenerator) (*RoleBindingClient, error) {
c, err := generator.ClientFor(RoleBindingKind())
if err != nil {
return nil, err
}
return NewRoleBindingClient(c), nil
}
func (c *RoleBindingClient) Get(ctx context.Context, identifier resource.Identifier) (*RoleBinding, error) {
return c.client.Get(ctx, identifier)
}
func (c *RoleBindingClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*RoleBindingList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *RoleBindingClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*RoleBindingList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *RoleBindingClient) Create(ctx context.Context, obj *RoleBinding, opts resource.CreateOptions) (*RoleBinding, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = RoleBindingKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *RoleBindingClient) Update(ctx context.Context, obj *RoleBinding, opts resource.UpdateOptions) (*RoleBinding, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *RoleBindingClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*RoleBinding, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *RoleBindingClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus RoleBindingStatus, opts resource.UpdateOptions) (*RoleBinding, error) {
return c.client.Update(ctx, &RoleBinding{
TypeMeta: metav1.TypeMeta{
Kind: RoleBindingKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *RoleBindingClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type ServiceAccountClient struct {
client *resource.TypedClient[*ServiceAccount, *ServiceAccountList]
}
func NewServiceAccountClient(client resource.Client) *ServiceAccountClient {
return &ServiceAccountClient{
client: resource.NewTypedClient[*ServiceAccount, *ServiceAccountList](client, ServiceAccountKind()),
}
}
func NewServiceAccountClientFromGenerator(generator resource.ClientGenerator) (*ServiceAccountClient, error) {
c, err := generator.ClientFor(ServiceAccountKind())
if err != nil {
return nil, err
}
return NewServiceAccountClient(c), nil
}
func (c *ServiceAccountClient) Get(ctx context.Context, identifier resource.Identifier) (*ServiceAccount, error) {
return c.client.Get(ctx, identifier)
}
func (c *ServiceAccountClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*ServiceAccountList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *ServiceAccountClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*ServiceAccountList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *ServiceAccountClient) Create(ctx context.Context, obj *ServiceAccount, opts resource.CreateOptions) (*ServiceAccount, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = ServiceAccountKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *ServiceAccountClient) Update(ctx context.Context, obj *ServiceAccount, opts resource.UpdateOptions) (*ServiceAccount, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *ServiceAccountClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*ServiceAccount, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *ServiceAccountClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus ServiceAccountStatus, opts resource.UpdateOptions) (*ServiceAccount, error) {
return c.client.Update(ctx, &ServiceAccount{
TypeMeta: metav1.TypeMeta{
Kind: ServiceAccountKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *ServiceAccountClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type TeamClient struct {
client *resource.TypedClient[*Team, *TeamList]
}
func NewTeamClient(client resource.Client) *TeamClient {
return &TeamClient{
client: resource.NewTypedClient[*Team, *TeamList](client, TeamKind()),
}
}
func NewTeamClientFromGenerator(generator resource.ClientGenerator) (*TeamClient, error) {
c, err := generator.ClientFor(TeamKind())
if err != nil {
return nil, err
}
return NewTeamClient(c), nil
}
func (c *TeamClient) Get(ctx context.Context, identifier resource.Identifier) (*Team, error) {
return c.client.Get(ctx, identifier)
}
func (c *TeamClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*TeamList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *TeamClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*TeamList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *TeamClient) Create(ctx context.Context, obj *Team, opts resource.CreateOptions) (*Team, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = TeamKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *TeamClient) Update(ctx context.Context, obj *Team, opts resource.UpdateOptions) (*Team, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *TeamClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*Team, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *TeamClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus TeamStatus, opts resource.UpdateOptions) (*Team, error) {
return c.client.Update(ctx, &Team{
TypeMeta: metav1.TypeMeta{
Kind: TeamKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *TeamClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type TeamBindingClient struct {
client *resource.TypedClient[*TeamBinding, *TeamBindingList]
}
func NewTeamBindingClient(client resource.Client) *TeamBindingClient {
return &TeamBindingClient{
client: resource.NewTypedClient[*TeamBinding, *TeamBindingList](client, TeamBindingKind()),
}
}
func NewTeamBindingClientFromGenerator(generator resource.ClientGenerator) (*TeamBindingClient, error) {
c, err := generator.ClientFor(TeamBindingKind())
if err != nil {
return nil, err
}
return NewTeamBindingClient(c), nil
}
func (c *TeamBindingClient) Get(ctx context.Context, identifier resource.Identifier) (*TeamBinding, error) {
return c.client.Get(ctx, identifier)
}
func (c *TeamBindingClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*TeamBindingList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *TeamBindingClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*TeamBindingList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *TeamBindingClient) Create(ctx context.Context, obj *TeamBinding, opts resource.CreateOptions) (*TeamBinding, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = TeamBindingKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *TeamBindingClient) Update(ctx context.Context, obj *TeamBinding, opts resource.UpdateOptions) (*TeamBinding, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *TeamBindingClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*TeamBinding, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *TeamBindingClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus TeamBindingStatus, opts resource.UpdateOptions) (*TeamBinding, error) {
return c.client.Update(ctx, &TeamBinding{
TypeMeta: metav1.TypeMeta{
Kind: TeamBindingKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *TeamBindingClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -0,0 +1,99 @@
package v0alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type UserClient struct {
client *resource.TypedClient[*User, *UserList]
}
func NewUserClient(client resource.Client) *UserClient {
return &UserClient{
client: resource.NewTypedClient[*User, *UserList](client, UserKind()),
}
}
func NewUserClientFromGenerator(generator resource.ClientGenerator) (*UserClient, error) {
c, err := generator.ClientFor(UserKind())
if err != nil {
return nil, err
}
return NewUserClient(c), nil
}
func (c *UserClient) Get(ctx context.Context, identifier resource.Identifier) (*User, error) {
return c.client.Get(ctx, identifier)
}
func (c *UserClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*UserList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *UserClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*UserList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *UserClient) Create(ctx context.Context, obj *User, opts resource.CreateOptions) (*User, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = UserKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *UserClient) Update(ctx context.Context, obj *User, opts resource.UpdateOptions) (*User, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *UserClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*User, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *UserClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus UserStatus, opts resource.UpdateOptions) (*User, error) {
return c.client.Update(ctx, &User{
TypeMeta: metav1.TypeMeta{
Kind: UserKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *UserClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}
@@ -10,8 +10,8 @@ type UserSpec struct {
GrafanaAdmin bool `json:"grafanaAdmin"`
Login string `json:"login"`
Name string `json:"name"`
// What to do with salt, rands and password?
Provisioned bool `json:"provisioned"`
Provisioned bool `json:"provisioned"`
Role string `json:"role"`
}
// NewUserSpec creates a new UserSpec object.
@@ -2660,14 +2660,20 @@ func schema_pkg_apis_iam_v0alpha1_UserSpec(ref common.ReferenceCallback) common.
},
"provisioned": {
SchemaProps: spec.SchemaProps{
Description: "What to do with salt, rands and password?",
Default: false,
Type: []string{"boolean"},
Format: "",
Default: false,
Type: []string{"boolean"},
Format: "",
},
},
"role": {
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"disabled", "email", "emailVerified", "grafanaAdmin", "login", "name", "provisioned"},
Required: []string{"disabled", "email", "emailVerified", "grafanaAdmin", "login", "name", "provisioned", "role"},
},
},
}
+46
View File
@@ -11,6 +11,8 @@ import (
"github.com/grafana/grafana-app-sdk/app"
"github.com/grafana/grafana-app-sdk/resource"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kube-openapi/pkg/spec3"
v0alpha1 "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1"
)
@@ -93,6 +95,10 @@ var appManifestData = app.ManifestData{
Conversion: false,
},
},
Routes: app.ManifestVersionRoutes{
Namespaced: map[string]spec3.PathProps{},
Cluster: map[string]spec3.PathProps{},
},
},
},
}
@@ -130,6 +136,7 @@ var customRouteToGoResponseType = map[string]any{}
// ManifestCustomRouteResponsesAssociator returns the associated response go type for a given kind, version, custom route path, and method, if one exists.
// kind may be empty for custom routes which are not kind subroutes. Leading slashes are removed from subroute paths.
// If there is no association for the provided kind, version, custom route path, and method, exists will return false.
// Resource routes (those without a kind) should prefix their route with "<namespace>/" if the route is namespaced (otherwise the route is assumed to be cluster-scope)
func ManifestCustomRouteResponsesAssociator(kind, version, path, verb string) (goType any, exists bool) {
if len(path) > 0 && path[0] == '/' {
path = path[1:]
@@ -137,3 +144,42 @@ func ManifestCustomRouteResponsesAssociator(kind, version, path, verb string) (g
goType, exists = customRouteToGoResponseType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))]
return goType, exists
}
var customRouteToGoParamsType = map[string]runtime.Object{}
func ManifestCustomRouteQueryAssociator(kind, version, path, verb string) (goType runtime.Object, exists bool) {
if len(path) > 0 && path[0] == '/' {
path = path[1:]
}
goType, exists = customRouteToGoParamsType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))]
return goType, exists
}
var customRouteToGoRequestBodyType = map[string]any{}
func ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb string) (goType any, exists bool) {
if len(path) > 0 && path[0] == '/' {
path = path[1:]
}
goType, exists = customRouteToGoRequestBodyType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))]
return goType, exists
}
type GoTypeAssociator struct{}
func NewGoTypeAssociator() *GoTypeAssociator {
return &GoTypeAssociator{}
}
func (g *GoTypeAssociator) KindToGoType(kind, version string) (goType resource.Kind, exists bool) {
return ManifestGoTypeAssociator(kind, version)
}
func (g *GoTypeAssociator) CustomRouteReturnGoType(kind, version, path, verb string) (goType any, exists bool) {
return ManifestCustomRouteResponsesAssociator(kind, version, path, verb)
}
func (g *GoTypeAssociator) CustomRouteQueryGoType(kind, version, path, verb string) (goType runtime.Object, exists bool) {
return ManifestCustomRouteQueryAssociator(kind, version, path, verb)
}
func (g *GoTypeAssociator) CustomRouteRequestBodyGoType(kind, version, path, verb string) (goType any, exists bool) {
return ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb)
}