mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Identity: Add read-only identity apiserver (#90418)
This commit is contained in:
parent
be7b1ce2df
commit
ec6c6bd6c3
@ -7332,9 +7332,6 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||||
],
|
],
|
||||||
"public/app/types/teams.ts:5381": [
|
|
||||||
[0, 0, 0, "Do not re-export imported variable (\`TeamDTO\`)", "0"]
|
|
||||||
],
|
|
||||||
"public/app/types/unified-alerting-dto.ts:5381": [
|
"public/app/types/unified-alerting-dto.ts:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||||
],
|
],
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
package kind
|
|
||||||
|
|
||||||
name: "Team"
|
|
||||||
maturity: "merged"
|
|
||||||
description: "A team is a named grouping of Grafana users to which access control rules may be assigned."
|
|
||||||
|
|
||||||
lineage: schemas: [{
|
|
||||||
version: [0, 0]
|
|
||||||
schema: {
|
|
||||||
spec: {
|
|
||||||
// Name of the team.
|
|
||||||
name: string
|
|
||||||
// Email of the team.
|
|
||||||
email?: string
|
|
||||||
} @cuetsy(kind="interface")
|
|
||||||
}
|
|
||||||
}]
|
|
@ -145,6 +145,3 @@ export type {
|
|||||||
BuiltinRoleRef,
|
BuiltinRoleRef,
|
||||||
RoleBindingSubject
|
RoleBindingSubject
|
||||||
} from './raw/rolebinding/x/rolebinding_types.gen';
|
} from './raw/rolebinding/x/rolebinding_types.gen';
|
||||||
|
|
||||||
// Raw generated types from Team kind.
|
|
||||||
export type { Team } from './raw/team/x/team_types.gen';
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
|
||||||
//
|
|
||||||
// Generated by:
|
|
||||||
// kinds/gen.go
|
|
||||||
// Using jennies:
|
|
||||||
// TSTypesJenny
|
|
||||||
// LatestMajorsOrXJenny
|
|
||||||
//
|
|
||||||
// Run 'make gen-cue' from repository root to regenerate.
|
|
||||||
|
|
||||||
export interface Team {
|
|
||||||
/**
|
|
||||||
* Email of the team.
|
|
||||||
*/
|
|
||||||
email?: string;
|
|
||||||
/**
|
|
||||||
* Name of the team.
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
}
|
|
6
pkg/apimachinery/apis/identity/v0alpha1/doc.go
Normal file
6
pkg/apimachinery/apis/identity/v0alpha1/doc.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// +k8s:deepcopy-gen=package
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
// +k8s:defaulter-gen=TypeMeta
|
||||||
|
// +groupName=identity.grafana.app
|
||||||
|
|
||||||
|
package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
68
pkg/apimachinery/apis/identity/v0alpha1/register.go
Normal file
68
pkg/apimachinery/apis/identity/v0alpha1/register.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package v0alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
GROUP = "identity.grafana.app"
|
||||||
|
VERSION = "v0alpha1"
|
||||||
|
APIVERSION = GROUP + "/" + VERSION
|
||||||
|
)
|
||||||
|
|
||||||
|
var UserResourceInfo = common.NewResourceInfo(GROUP, VERSION,
|
||||||
|
"users", "user", "User",
|
||||||
|
func() runtime.Object { return &User{} },
|
||||||
|
func() runtime.Object { return &UserList{} },
|
||||||
|
)
|
||||||
|
|
||||||
|
var TeamResourceInfo = common.NewResourceInfo(GROUP, VERSION,
|
||||||
|
"teams", "team", "Team",
|
||||||
|
func() runtime.Object { return &Team{} },
|
||||||
|
func() runtime.Object { return &TeamList{} },
|
||||||
|
)
|
||||||
|
|
||||||
|
var ServiceAccountResourceInfo = common.NewResourceInfo(GROUP, VERSION,
|
||||||
|
"serviceaccounts", "serviceaccount", "ServiceAccount",
|
||||||
|
func() runtime.Object { return &ServiceAccount{} },
|
||||||
|
func() runtime.Object { return &ServiceAccountList{} },
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// SchemeGroupVersion is group version used to register these objects
|
||||||
|
SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION}
|
||||||
|
|
||||||
|
// SchemaBuilder is used by standard codegen
|
||||||
|
SchemeBuilder runtime.SchemeBuilder
|
||||||
|
localSchemeBuilder = &SchemeBuilder
|
||||||
|
AddToScheme = localSchemeBuilder.AddToScheme
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
localSchemeBuilder.Register(func(s *runtime.Scheme) error {
|
||||||
|
return AddKnownTypes(s, VERSION)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds the list of known types to the given scheme.
|
||||||
|
func AddKnownTypes(scheme *runtime.Scheme, version string) error {
|
||||||
|
scheme.AddKnownTypes(schema.GroupVersion{Group: GROUP, Version: version},
|
||||||
|
&User{},
|
||||||
|
&UserList{},
|
||||||
|
&ServiceAccount{},
|
||||||
|
&ServiceAccountList{},
|
||||||
|
&Team{},
|
||||||
|
&TeamList{},
|
||||||
|
&IdentityDisplayList{},
|
||||||
|
)
|
||||||
|
// metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||||
|
func Resource(resource string) schema.GroupResource {
|
||||||
|
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||||
|
}
|
91
pkg/apimachinery/apis/identity/v0alpha1/types.go
Normal file
91
pkg/apimachinery/apis/identity/v0alpha1/types.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package v0alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
type User struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Spec UserSpec `json:"spec,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserSpec struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Login string `json:"login,omitempty"`
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
EmailVerified bool `json:"emailVerified,omitempty"`
|
||||||
|
Disabled bool `json:"disabled,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
type UserList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Items []User `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
type Team struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Spec TeamSpec `json:"spec,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TeamSpec struct {
|
||||||
|
Title string `json:"name,omitempty"`
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
type TeamList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Items []Team `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
type ServiceAccount struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Spec ServiceAccountSpec `json:"spec,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceAccountSpec struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
EmailVerified bool `json:"emailVerified,omitempty"`
|
||||||
|
Disabled bool `json:"disabled,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
type ServiceAccountList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Items []ServiceAccount `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
type IdentityDisplayList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Items []IdentityDisplay `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IdentityDisplay struct {
|
||||||
|
IdentityType string `json:"type"` // The namespaced UID, eg `user|api-key|...`
|
||||||
|
UID string `json:"uid"` // The namespaced UID, eg `xyz`
|
||||||
|
Display string `json:"display"`
|
||||||
|
AvatarURL string `json:"avatarURL,omitempty"`
|
||||||
|
|
||||||
|
// Legacy internal ID -- usage of this value should be phased out
|
||||||
|
LegacyID int64 `json:"legacyId,omitempty"`
|
||||||
|
}
|
287
pkg/apimachinery/apis/identity/v0alpha1/zz_generated.deepcopy.go
Normal file
287
pkg/apimachinery/apis/identity/v0alpha1/zz_generated.deepcopy.go
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
//go:build !ignore_autogenerated
|
||||||
|
// +build !ignore_autogenerated
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *IdentityDisplay) DeepCopyInto(out *IdentityDisplay) {
|
||||||
|
*out = *in
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IdentityDisplay.
|
||||||
|
func (in *IdentityDisplay) DeepCopy() *IdentityDisplay {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(IdentityDisplay)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *IdentityDisplayList) DeepCopyInto(out *IdentityDisplayList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]IdentityDisplay, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IdentityDisplayList.
|
||||||
|
func (in *IdentityDisplayList) DeepCopy() *IdentityDisplayList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(IdentityDisplayList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *IdentityDisplayList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServiceAccount) DeepCopyInto(out *ServiceAccount) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
out.Spec = in.Spec
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccount.
|
||||||
|
func (in *ServiceAccount) DeepCopy() *ServiceAccount {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServiceAccount)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ServiceAccount) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServiceAccountList) DeepCopyInto(out *ServiceAccountList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]ServiceAccount, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccountList.
|
||||||
|
func (in *ServiceAccountList) DeepCopy() *ServiceAccountList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServiceAccountList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ServiceAccountList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServiceAccountSpec) DeepCopyInto(out *ServiceAccountSpec) {
|
||||||
|
*out = *in
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccountSpec.
|
||||||
|
func (in *ServiceAccountSpec) DeepCopy() *ServiceAccountSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServiceAccountSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Team) DeepCopyInto(out *Team) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
out.Spec = in.Spec
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Team.
|
||||||
|
func (in *Team) DeepCopy() *Team {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Team)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *Team) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *TeamList) DeepCopyInto(out *TeamList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]Team, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeamList.
|
||||||
|
func (in *TeamList) DeepCopy() *TeamList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(TeamList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *TeamList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *TeamSpec) DeepCopyInto(out *TeamSpec) {
|
||||||
|
*out = *in
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeamSpec.
|
||||||
|
func (in *TeamSpec) DeepCopy() *TeamSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(TeamSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *User) DeepCopyInto(out *User) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
out.Spec = in.Spec
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new User.
|
||||||
|
func (in *User) DeepCopy() *User {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(User)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *User) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *UserList) DeepCopyInto(out *UserList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]User, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserList.
|
||||||
|
func (in *UserList) DeepCopy() *UserList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(UserList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *UserList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *UserSpec) DeepCopyInto(out *UserSpec) {
|
||||||
|
*out = *in
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserSpec.
|
||||||
|
func (in *UserSpec) DeepCopy() *UserSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(UserSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
//go:build !ignore_autogenerated
|
||||||
|
// +build !ignore_autogenerated
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||||
|
// Public to allow building arbitrary schemes.
|
||||||
|
// All generated defaulters are covering - they call all nested defaulters.
|
||||||
|
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||||
|
return nil
|
||||||
|
}
|
490
pkg/apimachinery/apis/identity/v0alpha1/zz_generated.openapi.go
Normal file
490
pkg/apimachinery/apis/identity/v0alpha1/zz_generated.openapi.go
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
//go:build !ignore_autogenerated
|
||||||
|
// +build !ignore_autogenerated
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by openapi-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
// This file was autogenerated by openapi-gen. Do not edit it manually!
|
||||||
|
|
||||||
|
package v0alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
common "k8s.io/kube-openapi/pkg/common"
|
||||||
|
spec "k8s.io/kube-openapi/pkg/validation/spec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||||
|
return map[string]common.OpenAPIDefinition{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.IdentityDisplay": schema_apimachinery_apis_identity_v0alpha1_IdentityDisplay(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.IdentityDisplayList": schema_apimachinery_apis_identity_v0alpha1_IdentityDisplayList(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccount": schema_apimachinery_apis_identity_v0alpha1_ServiceAccount(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccountList": schema_apimachinery_apis_identity_v0alpha1_ServiceAccountList(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccountSpec": schema_apimachinery_apis_identity_v0alpha1_ServiceAccountSpec(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.Team": schema_apimachinery_apis_identity_v0alpha1_Team(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.TeamList": schema_apimachinery_apis_identity_v0alpha1_TeamList(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.TeamSpec": schema_apimachinery_apis_identity_v0alpha1_TeamSpec(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.User": schema_apimachinery_apis_identity_v0alpha1_User(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.UserList": schema_apimachinery_apis_identity_v0alpha1_UserList(ref),
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.UserSpec": schema_apimachinery_apis_identity_v0alpha1_UserSpec(ref),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_IdentityDisplay(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"type": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: "",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"uid": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "The namespaced UID, eg `user|api-key|...`",
|
||||||
|
Default: "",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"display": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "The namespaced UID, eg `xyz`",
|
||||||
|
Default: "",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"avatarURL": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"legacyId": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Legacy internal ID -- usage of this value should be phased out",
|
||||||
|
Type: []string{"integer"},
|
||||||
|
Format: "int64",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Required: []string{"type", "uid", "display"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_IdentityDisplayList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"kind": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apiVersion": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"array"},
|
||||||
|
Items: &spec.SchemaOrArray{
|
||||||
|
Schema: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.IdentityDisplay"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.IdentityDisplay", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_ServiceAccount(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"kind": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apiVersion": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccountSpec"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccountSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_ServiceAccountList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"kind": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apiVersion": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"array"},
|
||||||
|
Items: &spec.SchemaOrArray{
|
||||||
|
Schema: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccount"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccount", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_ServiceAccountSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"name": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"emailVerified": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"boolean"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"boolean"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_Team(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"kind": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apiVersion": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.TeamSpec"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.TeamSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_TeamList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"kind": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apiVersion": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"array"},
|
||||||
|
Items: &spec.SchemaOrArray{
|
||||||
|
Schema: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.Team"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.Team", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_TeamSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"name": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_User(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"kind": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apiVersion": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.UserSpec"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.UserSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_UserList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"kind": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apiVersion": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"array"},
|
||||||
|
Items: &spec.SchemaOrArray{
|
||||||
|
Schema: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.User"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.User", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_apimachinery_apis_identity_v0alpha1_UserSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"name": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"emailVerified": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"boolean"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"boolean"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1,IdentityDisplay,IdentityType
|
||||||
|
API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1,IdentityDisplay,LegacyID
|
||||||
|
API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1,TeamSpec,Title
|
@ -1,43 +0,0 @@
|
|||||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
|
||||||
//
|
|
||||||
// Generated by:
|
|
||||||
// kinds/gen.go
|
|
||||||
// Using jennies:
|
|
||||||
// K8ResourcesJenny
|
|
||||||
//
|
|
||||||
// Run 'make gen-cue' from repository root to regenerate.
|
|
||||||
|
|
||||||
package team
|
|
||||||
|
|
||||||
import (
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/kinds"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Resource is the kubernetes style representation of Team. (TODO be better)
|
|
||||||
type K8sResource = kinds.GrafanaResource[Spec, Status]
|
|
||||||
|
|
||||||
// NewResource creates a new instance of the resource with a given name (UID)
|
|
||||||
func NewK8sResource(name string, s *Spec) K8sResource {
|
|
||||||
return K8sResource{
|
|
||||||
TypeMeta: v1.TypeMeta{
|
|
||||||
Kind: "Team",
|
|
||||||
APIVersion: "v0-0-alpha",
|
|
||||||
},
|
|
||||||
ObjectMeta: v1.ObjectMeta{
|
|
||||||
Name: name,
|
|
||||||
Annotations: make(map[string]string),
|
|
||||||
Labels: make(map[string]string),
|
|
||||||
},
|
|
||||||
Spec: s,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resource is the wire representation of Team.
|
|
||||||
// It currently will soon be merged into the k8s flavor (TODO be better)
|
|
||||||
type Resource struct {
|
|
||||||
Metadata Metadata `json:"metadata"`
|
|
||||||
Spec Spec `json:"spec"`
|
|
||||||
Status Status `json:"status"`
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
|
||||||
//
|
|
||||||
// Generated by:
|
|
||||||
// kinds/gen.go
|
|
||||||
// Using jennies:
|
|
||||||
// K8ResourcesJenny
|
|
||||||
//
|
|
||||||
// Run 'make gen-cue' from repository root to regenerate.
|
|
||||||
|
|
||||||
package team
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Metadata defines model for Metadata.
|
|
||||||
type Metadata struct {
|
|
||||||
CreatedBy string `json:"createdBy"`
|
|
||||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
|
||||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
|
||||||
|
|
||||||
// extraFields is reserved for any fields that are pulled from the API server metadata but do not have concrete fields in the CUE metadata
|
|
||||||
ExtraFields map[string]any `json:"extraFields"`
|
|
||||||
Finalizers []string `json:"finalizers"`
|
|
||||||
Labels map[string]string `json:"labels"`
|
|
||||||
ResourceVersion string `json:"resourceVersion"`
|
|
||||||
Uid string `json:"uid"`
|
|
||||||
UpdateTimestamp time.Time `json:"updateTimestamp"`
|
|
||||||
UpdatedBy string `json:"updatedBy"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kubeObjectMetadata is metadata found in a kubernetes object's metadata field.
|
|
||||||
// It is not exhaustive and only includes fields which may be relevant to a kind's implementation,
|
|
||||||
// As it is also intended to be generic enough to function with any API Server.
|
|
||||||
type KubeObjectMetadata struct {
|
|
||||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
|
||||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
|
||||||
Finalizers []string `json:"finalizers"`
|
|
||||||
Labels map[string]string `json:"labels"`
|
|
||||||
ResourceVersion string `json:"resourceVersion"`
|
|
||||||
Uid string `json:"uid"`
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
|
||||||
//
|
|
||||||
// Generated by:
|
|
||||||
// kinds/gen.go
|
|
||||||
// Using jennies:
|
|
||||||
// GoResourceTypes
|
|
||||||
//
|
|
||||||
// Run 'make gen-cue' from repository root to regenerate.
|
|
||||||
|
|
||||||
package team
|
|
||||||
|
|
||||||
// Spec defines model for Spec.
|
|
||||||
type Spec struct {
|
|
||||||
// Email of the team.
|
|
||||||
Email *string `json:"email,omitempty"`
|
|
||||||
|
|
||||||
// Name of the team.
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
|
||||||
//
|
|
||||||
// Generated by:
|
|
||||||
// kinds/gen.go
|
|
||||||
// Using jennies:
|
|
||||||
// K8ResourcesJenny
|
|
||||||
//
|
|
||||||
// Run 'make gen-cue' from repository root to regenerate.
|
|
||||||
|
|
||||||
package team
|
|
||||||
|
|
||||||
// Defines values for OperatorStateState.
|
|
||||||
const (
|
|
||||||
OperatorStateStateFailed OperatorStateState = "failed"
|
|
||||||
OperatorStateStateInProgress OperatorStateState = "in_progress"
|
|
||||||
OperatorStateStateSuccess OperatorStateState = "success"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Defines values for StatusOperatorStateState.
|
|
||||||
const (
|
|
||||||
StatusOperatorStateStateFailed StatusOperatorStateState = "failed"
|
|
||||||
StatusOperatorStateStateInProgress StatusOperatorStateState = "in_progress"
|
|
||||||
StatusOperatorStateStateSuccess StatusOperatorStateState = "success"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OperatorState defines model for OperatorState.
|
|
||||||
type OperatorState struct {
|
|
||||||
// descriptiveState is an optional more descriptive state field which has no requirements on format
|
|
||||||
DescriptiveState *string `json:"descriptiveState,omitempty"`
|
|
||||||
|
|
||||||
// details contains any extra information that is operator-specific
|
|
||||||
Details map[string]any `json:"details,omitempty"`
|
|
||||||
|
|
||||||
// lastEvaluation is the ResourceVersion last evaluated
|
|
||||||
LastEvaluation string `json:"lastEvaluation"`
|
|
||||||
|
|
||||||
// state describes the state of the lastEvaluation.
|
|
||||||
// It is limited to three possible states for machine evaluation.
|
|
||||||
State OperatorStateState `json:"state"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// OperatorStateState state describes the state of the lastEvaluation.
|
|
||||||
// It is limited to three possible states for machine evaluation.
|
|
||||||
type OperatorStateState string
|
|
||||||
|
|
||||||
// Status defines model for Status.
|
|
||||||
type Status struct {
|
|
||||||
// additionalFields is reserved for future use
|
|
||||||
AdditionalFields map[string]any `json:"additionalFields,omitempty"`
|
|
||||||
|
|
||||||
// operatorStates is a map of operator ID to operator state evaluations.
|
|
||||||
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
|
|
||||||
OperatorStates map[string]StatusOperatorState `json:"operatorStates,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusOperatorState defines model for status.#OperatorState.
|
|
||||||
type StatusOperatorState struct {
|
|
||||||
// descriptiveState is an optional more descriptive state field which has no requirements on format
|
|
||||||
DescriptiveState *string `json:"descriptiveState,omitempty"`
|
|
||||||
|
|
||||||
// details contains any extra information that is operator-specific
|
|
||||||
Details map[string]any `json:"details,omitempty"`
|
|
||||||
|
|
||||||
// lastEvaluation is the ResourceVersion last evaluated
|
|
||||||
LastEvaluation string `json:"lastEvaluation"`
|
|
||||||
|
|
||||||
// state describes the state of the lastEvaluation.
|
|
||||||
// It is limited to three possible states for machine evaluation.
|
|
||||||
State StatusOperatorStateState `json:"state"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusOperatorStateState state describes the state of the lastEvaluation.
|
|
||||||
// It is limited to three possible states for machine evaluation.
|
|
||||||
type StatusOperatorStateState string
|
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/registry/apis/datasource"
|
"github.com/grafana/grafana/pkg/registry/apis/datasource"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/featuretoggle"
|
"github.com/grafana/grafana/pkg/registry/apis/featuretoggle"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/folders"
|
"github.com/grafana/grafana/pkg/registry/apis/folders"
|
||||||
|
"github.com/grafana/grafana/pkg/registry/apis/identity"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/peakq"
|
"github.com/grafana/grafana/pkg/registry/apis/peakq"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/playlist"
|
"github.com/grafana/grafana/pkg/registry/apis/playlist"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/query"
|
"github.com/grafana/grafana/pkg/registry/apis/query"
|
||||||
@ -32,6 +33,7 @@ func ProvideRegistryServiceSink(
|
|||||||
_ *datasource.DataSourceAPIBuilder,
|
_ *datasource.DataSourceAPIBuilder,
|
||||||
_ *folders.FolderAPIBuilder,
|
_ *folders.FolderAPIBuilder,
|
||||||
_ *peakq.PeakQAPIBuilder,
|
_ *peakq.PeakQAPIBuilder,
|
||||||
|
_ *identity.IdentityAPIBuilder,
|
||||||
_ *scope.ScopeAPIBuilder,
|
_ *scope.ScopeAPIBuilder,
|
||||||
_ *query.QueryAPIBuilder,
|
_ *query.QueryAPIBuilder,
|
||||||
_ *notifications.NotificationsAPIBuilder,
|
_ *notifications.NotificationsAPIBuilder,
|
||||||
|
130
pkg/registry/apis/identity/legacy_sa.go
Normal file
130
pkg/registry/apis/identity/legacy_sa.go
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package identity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||||
|
identity "github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1"
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ rest.Scoper = (*legacyServiceAccountStorage)(nil)
|
||||||
|
_ rest.SingularNameProvider = (*legacyServiceAccountStorage)(nil)
|
||||||
|
_ rest.Getter = (*legacyServiceAccountStorage)(nil)
|
||||||
|
_ rest.Lister = (*legacyServiceAccountStorage)(nil)
|
||||||
|
_ rest.Storage = (*legacyServiceAccountStorage)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
type legacyServiceAccountStorage struct {
|
||||||
|
service user.Service
|
||||||
|
tableConverter rest.TableConvertor
|
||||||
|
resourceInfo common.ResourceInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) New() runtime.Object {
|
||||||
|
return s.resourceInfo.NewFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) Destroy() {}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) NamespaceScoped() bool {
|
||||||
|
return true // namespace == org
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) GetSingularName() string {
|
||||||
|
return s.resourceInfo.GetSingularName()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) NewList() runtime.Object {
|
||||||
|
return s.resourceInfo.NewListFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||||
|
return s.tableConverter.ConvertToTable(ctx, object, tableOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||||
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query := &user.ListUsersCommand{
|
||||||
|
OrgID: ns.OrgID,
|
||||||
|
Limit: options.Limit,
|
||||||
|
IsServiceAccount: true,
|
||||||
|
}
|
||||||
|
if options.Continue != "" {
|
||||||
|
query.ContinueID, err = strconv.ParseInt(options.Continue, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid continue token")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found, err := s.service.List(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list := &identity.ServiceAccountList{}
|
||||||
|
for _, item := range found.Users {
|
||||||
|
list.Items = append(list.Items, *toSAItem(item, ns.Value))
|
||||||
|
}
|
||||||
|
if found.ContinueID > 0 {
|
||||||
|
list.ListMeta.Continue = strconv.FormatInt(found.ContinueID, 10)
|
||||||
|
}
|
||||||
|
if found.RV > 0 {
|
||||||
|
list.ListMeta.ResourceVersion = strconv.FormatInt(found.RV, 10)
|
||||||
|
}
|
||||||
|
return list, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func toSAItem(u *user.User, ns string) *identity.ServiceAccount {
|
||||||
|
item := &identity.ServiceAccount{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: u.UID,
|
||||||
|
Namespace: ns,
|
||||||
|
ResourceVersion: fmt.Sprintf("%d", u.Updated.UnixMilli()),
|
||||||
|
CreationTimestamp: metav1.NewTime(u.Created),
|
||||||
|
},
|
||||||
|
Spec: identity.ServiceAccountSpec{
|
||||||
|
Name: u.Name,
|
||||||
|
Email: u.Email,
|
||||||
|
EmailVerified: u.EmailVerified,
|
||||||
|
Disabled: u.IsDisabled,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
obj, _ := utils.MetaAccessor(item)
|
||||||
|
obj.SetUpdatedTimestamp(&u.Updated)
|
||||||
|
obj.SetOriginInfo(&utils.ResourceOriginInfo{
|
||||||
|
Name: "SQL",
|
||||||
|
Path: strconv.FormatInt(u.ID, 10),
|
||||||
|
})
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyServiceAccountStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||||
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
found, err := s.service.GetByUID(ctx, &user.GetUserByUIDQuery{
|
||||||
|
OrgID: ns.OrgID,
|
||||||
|
UID: name,
|
||||||
|
})
|
||||||
|
if found == nil || err != nil {
|
||||||
|
return nil, s.resourceInfo.NewNotFound(name)
|
||||||
|
}
|
||||||
|
if !found.IsServiceAccount {
|
||||||
|
return nil, s.resourceInfo.NewNotFound(name) // looking up the wrong type
|
||||||
|
}
|
||||||
|
return toUserItem(found, ns.Value), nil
|
||||||
|
}
|
119
pkg/registry/apis/identity/legacy_teams.go
Normal file
119
pkg/registry/apis/identity/legacy_teams.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
package identity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||||
|
identity "github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1"
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
|
"github.com/grafana/grafana/pkg/services/team"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ rest.Scoper = (*legacyTeamStorage)(nil)
|
||||||
|
_ rest.SingularNameProvider = (*legacyTeamStorage)(nil)
|
||||||
|
_ rest.Getter = (*legacyTeamStorage)(nil)
|
||||||
|
_ rest.Lister = (*legacyTeamStorage)(nil)
|
||||||
|
_ rest.Storage = (*legacyTeamStorage)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
type legacyTeamStorage struct {
|
||||||
|
service team.Service
|
||||||
|
tableConverter rest.TableConvertor
|
||||||
|
resourceInfo common.ResourceInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) New() runtime.Object {
|
||||||
|
return s.resourceInfo.NewFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) Destroy() {}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) NamespaceScoped() bool {
|
||||||
|
return true // namespace == org
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) GetSingularName() string {
|
||||||
|
return s.resourceInfo.GetSingularName()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) NewList() runtime.Object {
|
||||||
|
return s.resourceInfo.NewListFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||||
|
return s.tableConverter.ConvertToTable(ctx, object, tableOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) doList(ctx context.Context, ns string, query *team.ListTeamsCommand) (*identity.TeamList, error) {
|
||||||
|
if query.Limit < 1 {
|
||||||
|
query.Limit = 100
|
||||||
|
}
|
||||||
|
teams, err := s.service.ListTeams(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list := &identity.TeamList{}
|
||||||
|
for _, team := range teams {
|
||||||
|
item := identity.Team{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: team.UID,
|
||||||
|
Namespace: ns,
|
||||||
|
CreationTimestamp: metav1.NewTime(team.Created),
|
||||||
|
ResourceVersion: strconv.FormatInt(team.Updated.UnixMilli(), 10),
|
||||||
|
},
|
||||||
|
Spec: identity.TeamSpec{
|
||||||
|
Title: team.Name,
|
||||||
|
Email: team.Email,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
meta, err := utils.MetaAccessor(&item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
meta.SetUpdatedTimestamp(&team.Updated)
|
||||||
|
meta.SetOriginInfo(&utils.ResourceOriginInfo{
|
||||||
|
Name: "SQL",
|
||||||
|
Path: strconv.FormatInt(team.ID, 10),
|
||||||
|
})
|
||||||
|
list.Items = append(list.Items, item)
|
||||||
|
}
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||||
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.doList(ctx, ns.Value, &team.ListTeamsCommand{
|
||||||
|
Limit: int(options.Limit),
|
||||||
|
OrgID: ns.OrgID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyTeamStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||||
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rsp, err := s.doList(ctx, ns.Value, &team.ListTeamsCommand{
|
||||||
|
Limit: 1,
|
||||||
|
OrgID: ns.OrgID,
|
||||||
|
UID: name,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(rsp.Items) > 0 {
|
||||||
|
return &rsp.Items[0], nil
|
||||||
|
}
|
||||||
|
return nil, s.resourceInfo.NewNotFound(name)
|
||||||
|
}
|
130
pkg/registry/apis/identity/legacy_users.go
Normal file
130
pkg/registry/apis/identity/legacy_users.go
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package identity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||||
|
identity "github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1"
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ rest.Scoper = (*legacyUserStorage)(nil)
|
||||||
|
_ rest.SingularNameProvider = (*legacyUserStorage)(nil)
|
||||||
|
_ rest.Getter = (*legacyUserStorage)(nil)
|
||||||
|
_ rest.Lister = (*legacyUserStorage)(nil)
|
||||||
|
_ rest.Storage = (*legacyUserStorage)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
type legacyUserStorage struct {
|
||||||
|
service user.Service
|
||||||
|
tableConverter rest.TableConvertor
|
||||||
|
resourceInfo common.ResourceInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) New() runtime.Object {
|
||||||
|
return s.resourceInfo.NewFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) Destroy() {}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) NamespaceScoped() bool {
|
||||||
|
return true // namespace == org
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) GetSingularName() string {
|
||||||
|
return s.resourceInfo.GetSingularName()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) NewList() runtime.Object {
|
||||||
|
return s.resourceInfo.NewListFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||||
|
return s.tableConverter.ConvertToTable(ctx, object, tableOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||||
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query := &user.ListUsersCommand{
|
||||||
|
OrgID: ns.OrgID,
|
||||||
|
Limit: options.Limit,
|
||||||
|
}
|
||||||
|
if options.Continue != "" {
|
||||||
|
query.ContinueID, err = strconv.ParseInt(options.Continue, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid continue token")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found, err := s.service.List(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list := &identity.UserList{}
|
||||||
|
for _, item := range found.Users {
|
||||||
|
list.Items = append(list.Items, *toUserItem(item, ns.Value))
|
||||||
|
}
|
||||||
|
if found.ContinueID > 0 {
|
||||||
|
list.ListMeta.Continue = strconv.FormatInt(found.ContinueID, 10)
|
||||||
|
}
|
||||||
|
if found.RV > 0 {
|
||||||
|
list.ListMeta.ResourceVersion = strconv.FormatInt(found.RV, 10)
|
||||||
|
}
|
||||||
|
return list, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func toUserItem(u *user.User, ns string) *identity.User {
|
||||||
|
item := &identity.User{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: u.UID,
|
||||||
|
Namespace: ns,
|
||||||
|
ResourceVersion: fmt.Sprintf("%d", u.Updated.UnixMilli()),
|
||||||
|
CreationTimestamp: metav1.NewTime(u.Created),
|
||||||
|
},
|
||||||
|
Spec: identity.UserSpec{
|
||||||
|
Name: u.Name,
|
||||||
|
Login: u.Login,
|
||||||
|
Email: u.Email,
|
||||||
|
EmailVerified: u.EmailVerified,
|
||||||
|
Disabled: u.IsDisabled,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
obj, _ := utils.MetaAccessor(item)
|
||||||
|
obj.SetUpdatedTimestamp(&u.Updated)
|
||||||
|
obj.SetOriginInfo(&utils.ResourceOriginInfo{
|
||||||
|
Name: "SQL",
|
||||||
|
Path: strconv.FormatInt(u.ID, 10),
|
||||||
|
})
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *legacyUserStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||||
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
found, err := s.service.GetByUID(ctx, &user.GetUserByUIDQuery{
|
||||||
|
OrgID: ns.OrgID,
|
||||||
|
UID: name,
|
||||||
|
})
|
||||||
|
if found == nil || err != nil {
|
||||||
|
return nil, s.resourceInfo.NewNotFound(name)
|
||||||
|
}
|
||||||
|
if found.IsServiceAccount {
|
||||||
|
return nil, s.resourceInfo.NewNotFound(name) // looking up the wrong type
|
||||||
|
}
|
||||||
|
return toUserItem(found, ns.Value), nil
|
||||||
|
}
|
196
pkg/registry/apis/identity/register.go
Normal file
196
pkg/registry/apis/identity/register.go
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
package identity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
|
"k8s.io/apiserver/pkg/registry/generic"
|
||||||
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
|
common "k8s.io/kube-openapi/pkg/common"
|
||||||
|
|
||||||
|
identity "github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1"
|
||||||
|
identityapi "github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
|
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||||
|
"github.com/grafana/grafana/pkg/services/apiserver/builder"
|
||||||
|
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
|
"github.com/grafana/grafana/pkg/services/team"
|
||||||
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ builder.APIGroupBuilder = (*IdentityAPIBuilder)(nil)
|
||||||
|
|
||||||
|
// This is used just so wire has something unique to return
|
||||||
|
type IdentityAPIBuilder struct {
|
||||||
|
svcTeam team.Service
|
||||||
|
svcUser user.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterAPIService(
|
||||||
|
features featuremgmt.FeatureToggles,
|
||||||
|
apiregistration builder.APIRegistrar,
|
||||||
|
svcTeam team.Service,
|
||||||
|
svcUser user.Service,
|
||||||
|
|
||||||
|
) *IdentityAPIBuilder {
|
||||||
|
if !features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) {
|
||||||
|
return nil // skip registration unless opting into experimental apis
|
||||||
|
}
|
||||||
|
|
||||||
|
builder := &IdentityAPIBuilder{
|
||||||
|
svcTeam: svcTeam,
|
||||||
|
svcUser: svcUser,
|
||||||
|
}
|
||||||
|
apiregistration.RegisterAPI(builder)
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *IdentityAPIBuilder) GetGroupVersion() schema.GroupVersion {
|
||||||
|
return identity.SchemeGroupVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *IdentityAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
|
||||||
|
if err := identity.AddKnownTypes(scheme, identity.VERSION); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link this version to the internal representation.
|
||||||
|
// This is used for server-side-apply (PATCH), and avoids the error:
|
||||||
|
// "no kind is registered for the type"
|
||||||
|
if err := identity.AddKnownTypes(scheme, runtime.APIVersionInternal); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If multiple versions exist, then register conversions from zz_generated.conversion.go
|
||||||
|
// if err := playlist.RegisterConversions(scheme); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
metav1.AddToGroupVersion(scheme, identity.SchemeGroupVersion)
|
||||||
|
return scheme.SetVersionPriority(identity.SchemeGroupVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *IdentityAPIBuilder) GetAPIGroupInfo(
|
||||||
|
scheme *runtime.Scheme,
|
||||||
|
codecs serializer.CodecFactory, // pointer?
|
||||||
|
optsGetter generic.RESTOptionsGetter,
|
||||||
|
dualWriteBuilder grafanarest.DualWriteBuilder,
|
||||||
|
) (*genericapiserver.APIGroupInfo, error) {
|
||||||
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(identity.GROUP, scheme, metav1.ParameterCodec, codecs)
|
||||||
|
storage := map[string]rest.Storage{}
|
||||||
|
|
||||||
|
team := identity.TeamResourceInfo
|
||||||
|
teamStore := &legacyTeamStorage{
|
||||||
|
service: b.svcTeam,
|
||||||
|
resourceInfo: team,
|
||||||
|
tableConverter: gapiutil.NewTableConverter(
|
||||||
|
team.GroupResource(),
|
||||||
|
[]metav1.TableColumnDefinition{
|
||||||
|
{Name: "Name", Type: "string", Format: "name"},
|
||||||
|
{Name: "Title", Type: "string", Format: "string", Description: "The team name"},
|
||||||
|
{Name: "Email", Type: "string", Format: "string", Description: "team email"},
|
||||||
|
{Name: "Created At", Type: "date"},
|
||||||
|
},
|
||||||
|
func(obj any) ([]interface{}, error) {
|
||||||
|
m, ok := obj.(*identity.Team)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("expected playlist")
|
||||||
|
}
|
||||||
|
return []interface{}{
|
||||||
|
m.Name,
|
||||||
|
m.Spec.Title,
|
||||||
|
m.Spec.Email,
|
||||||
|
m.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
storage[team.StoragePath()] = teamStore
|
||||||
|
|
||||||
|
user := identity.UserResourceInfo
|
||||||
|
userStore := &legacyUserStorage{
|
||||||
|
service: b.svcUser,
|
||||||
|
resourceInfo: user,
|
||||||
|
tableConverter: gapiutil.NewTableConverter(
|
||||||
|
user.GroupResource(),
|
||||||
|
[]metav1.TableColumnDefinition{
|
||||||
|
{Name: "Name", Type: "string", Format: "name"},
|
||||||
|
{Name: "Login", Type: "string", Format: "string", Description: "The user login"},
|
||||||
|
{Name: "Email", Type: "string", Format: "string", Description: "The user email"},
|
||||||
|
{Name: "Created At", Type: "date"},
|
||||||
|
},
|
||||||
|
func(obj any) ([]interface{}, error) {
|
||||||
|
u, ok := obj.(*identity.User)
|
||||||
|
if ok {
|
||||||
|
return []interface{}{
|
||||||
|
u.Name,
|
||||||
|
u.Spec.Login,
|
||||||
|
u.Spec.Email,
|
||||||
|
u.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("expected user")
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
storage[user.StoragePath()] = userStore
|
||||||
|
|
||||||
|
sa := identity.ServiceAccountResourceInfo
|
||||||
|
saStore := &legacyServiceAccountStorage{
|
||||||
|
service: b.svcUser,
|
||||||
|
resourceInfo: sa,
|
||||||
|
tableConverter: gapiutil.NewTableConverter(
|
||||||
|
user.GroupResource(),
|
||||||
|
[]metav1.TableColumnDefinition{
|
||||||
|
{Name: "Name", Type: "string", Format: "name"},
|
||||||
|
{Name: "Account", Type: "string", Format: "string", Description: "The service account email"},
|
||||||
|
{Name: "Email", Type: "string", Format: "string", Description: "The user email"},
|
||||||
|
{Name: "Created At", Type: "date"},
|
||||||
|
},
|
||||||
|
func(obj any) ([]interface{}, error) {
|
||||||
|
u, ok := obj.(*identity.ServiceAccount)
|
||||||
|
if ok {
|
||||||
|
return []interface{}{
|
||||||
|
u.Name,
|
||||||
|
u.Spec.Name,
|
||||||
|
u.Spec.Email,
|
||||||
|
u.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("expected user")
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
storage[sa.StoragePath()] = saStore
|
||||||
|
|
||||||
|
apiGroupInfo.VersionedResourcesStorageMap[identity.VERSION] = storage
|
||||||
|
return &apiGroupInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *IdentityAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
|
||||||
|
return identity.GetOpenAPIDefinitions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *IdentityAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||||
|
return nil // no custom API routes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *IdentityAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
||||||
|
return authorizer.AuthorizerFunc(
|
||||||
|
func(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||||
|
user, err := identityapi.GetRequester(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return authorizer.DecisionDeny, "no identity found", err
|
||||||
|
}
|
||||||
|
if user.GetIsGrafanaAdmin() {
|
||||||
|
return authorizer.DecisionAllow, "", nil
|
||||||
|
}
|
||||||
|
return authorizer.DecisionDeny, "only grafana admins have access for now", nil
|
||||||
|
})
|
||||||
|
}
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/registry/apis/datasource"
|
"github.com/grafana/grafana/pkg/registry/apis/datasource"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/featuretoggle"
|
"github.com/grafana/grafana/pkg/registry/apis/featuretoggle"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/folders"
|
"github.com/grafana/grafana/pkg/registry/apis/folders"
|
||||||
|
"github.com/grafana/grafana/pkg/registry/apis/identity"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/peakq"
|
"github.com/grafana/grafana/pkg/registry/apis/peakq"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/playlist"
|
"github.com/grafana/grafana/pkg/registry/apis/playlist"
|
||||||
"github.com/grafana/grafana/pkg/registry/apis/query"
|
"github.com/grafana/grafana/pkg/registry/apis/query"
|
||||||
@ -32,6 +33,7 @@ var WireSet = wire.NewSet(
|
|||||||
featuretoggle.RegisterAPIService,
|
featuretoggle.RegisterAPIService,
|
||||||
datasource.RegisterAPIService,
|
datasource.RegisterAPIService,
|
||||||
folders.RegisterAPIService,
|
folders.RegisterAPIService,
|
||||||
|
identity.RegisterAPIService,
|
||||||
peakq.RegisterAPIService,
|
peakq.RegisterAPIService,
|
||||||
service.RegisterAPIService,
|
service.RegisterAPIService,
|
||||||
query.RegisterAPIService,
|
query.RegisterAPIService,
|
||||||
|
@ -93,15 +93,6 @@ func GetCoreKinds() ([]CoreKind, error) {
|
|||||||
CueFile: rolebindingCue,
|
CueFile: rolebindingCue,
|
||||||
})
|
})
|
||||||
|
|
||||||
teamCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/team/team_kind.cue"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
kinds = append(kinds, CoreKind{
|
|
||||||
Name: "team",
|
|
||||||
CueFile: teamCue,
|
|
||||||
})
|
|
||||||
|
|
||||||
return kinds, nil
|
return kinds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,13 @@ type SearchTeamsQuery struct {
|
|||||||
HiddenUsers map[string]struct{}
|
HiddenUsers map[string]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListTeamsCommand struct {
|
||||||
|
Limit int
|
||||||
|
Start int
|
||||||
|
OrgID int64
|
||||||
|
UID string
|
||||||
|
}
|
||||||
|
|
||||||
type TeamDTO struct {
|
type TeamDTO struct {
|
||||||
ID int64 `json:"id" xorm:"id"`
|
ID int64 `json:"id" xorm:"id"`
|
||||||
UID string `json:"uid" xorm:"uid"`
|
UID string `json:"uid" xorm:"uid"`
|
||||||
|
@ -8,6 +8,7 @@ type Service interface {
|
|||||||
CreateTeam(ctx context.Context, name, email string, orgID int64) (Team, error)
|
CreateTeam(ctx context.Context, name, email string, orgID int64) (Team, error)
|
||||||
UpdateTeam(ctx context.Context, cmd *UpdateTeamCommand) error
|
UpdateTeam(ctx context.Context, cmd *UpdateTeamCommand) error
|
||||||
DeleteTeam(ctx context.Context, cmd *DeleteTeamCommand) error
|
DeleteTeam(ctx context.Context, cmd *DeleteTeamCommand) error
|
||||||
|
ListTeams(ctx context.Context, query *ListTeamsCommand) ([]*Team, error)
|
||||||
SearchTeams(ctx context.Context, query *SearchTeamsQuery) (SearchTeamQueryResult, error)
|
SearchTeams(ctx context.Context, query *SearchTeamsQuery) (SearchTeamQueryResult, error)
|
||||||
GetTeamByID(ctx context.Context, query *GetTeamByIDQuery) (*TeamDTO, error)
|
GetTeamByID(ctx context.Context, query *GetTeamByIDQuery) (*TeamDTO, error)
|
||||||
GetTeamsByUser(ctx context.Context, query *GetTeamsByUserQuery) ([]*TeamDTO, error)
|
GetTeamsByUser(ctx context.Context, query *GetTeamsByUserQuery) ([]*TeamDTO, error)
|
||||||
|
@ -20,6 +20,7 @@ type store interface {
|
|||||||
Create(name, email string, orgID int64) (team.Team, error)
|
Create(name, email string, orgID int64) (team.Team, error)
|
||||||
Update(ctx context.Context, cmd *team.UpdateTeamCommand) error
|
Update(ctx context.Context, cmd *team.UpdateTeamCommand) error
|
||||||
Delete(ctx context.Context, cmd *team.DeleteTeamCommand) error
|
Delete(ctx context.Context, cmd *team.DeleteTeamCommand) error
|
||||||
|
ListTeams(ctx context.Context, query *team.ListTeamsCommand) ([]*team.Team, error)
|
||||||
Search(ctx context.Context, query *team.SearchTeamsQuery) (team.SearchTeamQueryResult, error)
|
Search(ctx context.Context, query *team.SearchTeamsQuery) (team.SearchTeamQueryResult, error)
|
||||||
GetByID(ctx context.Context, query *team.GetTeamByIDQuery) (*team.TeamDTO, error)
|
GetByID(ctx context.Context, query *team.GetTeamByIDQuery) (*team.TeamDTO, error)
|
||||||
GetByUser(ctx context.Context, query *team.GetTeamsByUserQuery) ([]*team.TeamDTO, error)
|
GetByUser(ctx context.Context, query *team.GetTeamsByUserQuery) ([]*team.TeamDTO, error)
|
||||||
@ -267,6 +268,21 @@ func (ss *xormStore) Search(ctx context.Context, query *team.SearchTeamsQuery) (
|
|||||||
return queryResult, nil
|
return queryResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *xormStore) ListTeams(ctx context.Context, query *team.ListTeamsCommand) ([]*team.Team, error) {
|
||||||
|
results := make([]*team.Team, 0)
|
||||||
|
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
|
q := sess.Table("team")
|
||||||
|
q.Where("team.org_id=?", query.OrgID)
|
||||||
|
if query.UID != "" {
|
||||||
|
q.Where("team.uid=?", query.UID)
|
||||||
|
}
|
||||||
|
q.Limit(query.Limit, query.Start)
|
||||||
|
|
||||||
|
return q.Find(&results)
|
||||||
|
})
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *xormStore) GetByID(ctx context.Context, query *team.GetTeamByIDQuery) (*team.TeamDTO, error) {
|
func (ss *xormStore) GetByID(ctx context.Context, query *team.GetTeamByIDQuery) (*team.TeamDTO, error) {
|
||||||
var queryResult *team.TeamDTO
|
var queryResult *team.TeamDTO
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
|
@ -51,6 +51,14 @@ func (s *Service) DeleteTeam(ctx context.Context, cmd *team.DeleteTeamCommand) e
|
|||||||
return s.store.Delete(ctx, cmd)
|
return s.store.Delete(ctx, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) ListTeams(ctx context.Context, query *team.ListTeamsCommand) ([]*team.Team, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "team.ListTeams", trace.WithAttributes(
|
||||||
|
attribute.Int64("orgID", query.OrgID),
|
||||||
|
))
|
||||||
|
defer span.End()
|
||||||
|
return s.store.ListTeams(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) SearchTeams(ctx context.Context, query *team.SearchTeamsQuery) (team.SearchTeamQueryResult, error) {
|
func (s *Service) SearchTeams(ctx context.Context, query *team.SearchTeamsQuery) (team.SearchTeamQueryResult, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "team.SearchTeams", trace.WithAttributes(
|
ctx, span := s.tracer.Start(ctx, "team.SearchTeams", trace.WithAttributes(
|
||||||
attribute.Int64("orgID", query.OrgID),
|
attribute.Int64("orgID", query.OrgID),
|
||||||
|
@ -36,6 +36,10 @@ func (s *FakeService) SearchTeams(ctx context.Context, query *team.SearchTeamsQu
|
|||||||
return team.SearchTeamQueryResult{}, s.ExpectedError
|
return team.SearchTeamQueryResult{}, s.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FakeService) ListTeams(ctx context.Context, query *team.ListTeamsCommand) ([]*team.Team, error) {
|
||||||
|
return nil, s.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FakeService) GetTeamByID(ctx context.Context, query *team.GetTeamByIDQuery) (*team.TeamDTO, error) {
|
func (s *FakeService) GetTeamByID(ctx context.Context, query *team.GetTeamByIDQuery) (*team.TeamDTO, error) {
|
||||||
return s.ExpectedTeamDTO, s.ExpectedError
|
return s.ExpectedTeamDTO, s.ExpectedError
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,19 @@ type UpdateUserLastSeenAtCommand struct {
|
|||||||
OrgID int64
|
OrgID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListUsersCommand struct {
|
||||||
|
OrgID int64
|
||||||
|
Limit int64
|
||||||
|
ContinueID int64
|
||||||
|
IsServiceAccount bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListUserResult struct {
|
||||||
|
Users []*User
|
||||||
|
ContinueID int64
|
||||||
|
RV int64
|
||||||
|
}
|
||||||
|
|
||||||
type SearchUsersQuery struct {
|
type SearchUsersQuery struct {
|
||||||
SignedInUser identity.Requester
|
SignedInUser identity.Requester
|
||||||
OrgID int64 `xorm:"org_id"`
|
OrgID int64 `xorm:"org_id"`
|
||||||
@ -120,7 +133,7 @@ type SearchUserQueryResult struct {
|
|||||||
|
|
||||||
type UserSearchHitDTO struct {
|
type UserSearchHitDTO struct {
|
||||||
ID int64 `json:"id" xorm:"id"`
|
ID int64 `json:"id" xorm:"id"`
|
||||||
UID string `json:"uid" xorm:"id"`
|
UID string `json:"uid" xorm:"uid"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Login string `json:"login"`
|
Login string `json:"login"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
@ -206,6 +219,11 @@ type GetUserByIDQuery struct {
|
|||||||
ID int64
|
ID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetUserByUIDQuery struct {
|
||||||
|
OrgID int64
|
||||||
|
UID string
|
||||||
|
}
|
||||||
|
|
||||||
type StartVerifyEmailCommand struct {
|
type StartVerifyEmailCommand struct {
|
||||||
User User
|
User User
|
||||||
Email string
|
Email string
|
||||||
|
@ -13,8 +13,10 @@ type Service interface {
|
|||||||
CreateServiceAccount(context.Context, *CreateUserCommand) (*User, error)
|
CreateServiceAccount(context.Context, *CreateUserCommand) (*User, error)
|
||||||
Delete(context.Context, *DeleteUserCommand) error
|
Delete(context.Context, *DeleteUserCommand) error
|
||||||
GetByID(context.Context, *GetUserByIDQuery) (*User, error)
|
GetByID(context.Context, *GetUserByIDQuery) (*User, error)
|
||||||
|
GetByUID(context.Context, *GetUserByUIDQuery) (*User, error)
|
||||||
GetByLogin(context.Context, *GetUserByLoginQuery) (*User, error)
|
GetByLogin(context.Context, *GetUserByLoginQuery) (*User, error)
|
||||||
GetByEmail(context.Context, *GetUserByEmailQuery) (*User, error)
|
GetByEmail(context.Context, *GetUserByEmailQuery) (*User, error)
|
||||||
|
List(context.Context, *ListUsersCommand) (*ListUserResult, error)
|
||||||
Update(context.Context, *UpdateUserCommand) error
|
Update(context.Context, *UpdateUserCommand) error
|
||||||
UpdateLastSeenAt(context.Context, *UpdateUserLastSeenAtCommand) error
|
UpdateLastSeenAt(context.Context, *UpdateUserLastSeenAtCommand) error
|
||||||
GetSignedInUser(context.Context, *GetSignedInUserQuery) (*SignedInUser, error)
|
GetSignedInUser(context.Context, *GetSignedInUserQuery) (*SignedInUser, error)
|
||||||
|
@ -20,8 +20,10 @@ import (
|
|||||||
type store interface {
|
type store interface {
|
||||||
Insert(context.Context, *user.User) (int64, error)
|
Insert(context.Context, *user.User) (int64, error)
|
||||||
GetByID(context.Context, int64) (*user.User, error)
|
GetByID(context.Context, int64) (*user.User, error)
|
||||||
|
GetByUID(ctx context.Context, orgId int64, uid string) (*user.User, error)
|
||||||
GetByLogin(context.Context, *user.GetUserByLoginQuery) (*user.User, error)
|
GetByLogin(context.Context, *user.GetUserByLoginQuery) (*user.User, error)
|
||||||
GetByEmail(context.Context, *user.GetUserByEmailQuery) (*user.User, error)
|
GetByEmail(context.Context, *user.GetUserByEmailQuery) (*user.User, error)
|
||||||
|
List(context.Context, *user.ListUsersCommand) (*user.ListUserResult, error)
|
||||||
Delete(context.Context, int64) error
|
Delete(context.Context, int64) error
|
||||||
LoginConflict(ctx context.Context, login, email string) error
|
LoginConflict(ctx context.Context, login, email string) error
|
||||||
Update(context.Context, *user.UpdateUserCommand) error
|
Update(context.Context, *user.UpdateUserCommand) error
|
||||||
@ -107,6 +109,24 @@ func (ss *sqlStore) GetByID(ctx context.Context, userID int64) (*user.User, erro
|
|||||||
return &usr, err
|
return &usr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *sqlStore) GetByUID(ctx context.Context, orgId int64, uid string) (*user.User, error) {
|
||||||
|
var usr user.User
|
||||||
|
|
||||||
|
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
|
has, err := sess.Table("user").
|
||||||
|
Where("org_id = ? AND uid = ?", orgId, uid).
|
||||||
|
Get(&usr)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if !has {
|
||||||
|
return user.ErrUserNotFound
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return &usr, err
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) notServiceAccountFilter() string {
|
func (ss *sqlStore) notServiceAccountFilter() string {
|
||||||
return fmt.Sprintf("%s.is_service_account = %s",
|
return fmt.Sprintf("%s.is_service_account = %s",
|
||||||
ss.dialect.Quote("user"),
|
ss.dialect.Quote("user"),
|
||||||
@ -506,7 +526,7 @@ func (ss *sqlStore) Search(ctx context.Context, query *user.SearchUsersQuery) (*
|
|||||||
sess.Limit(query.Limit, offset)
|
sess.Limit(query.Limit, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
sess.Cols("u.id", "u.email", "u.name", "u.login", "u.is_admin", "u.is_disabled", "u.last_seen_at", "user_auth.auth_module")
|
sess.Cols("u.id", "u.uid", "u.email", "u.name", "u.login", "u.is_admin", "u.is_disabled", "u.last_seen_at", "user_auth.auth_module")
|
||||||
|
|
||||||
if len(query.SortOpts) > 0 {
|
if len(query.SortOpts) > 0 {
|
||||||
for i := range query.SortOpts {
|
for i := range query.SortOpts {
|
||||||
@ -559,6 +579,40 @@ func (ss *sqlStore) Search(ctx context.Context, query *user.SearchUsersQuery) (*
|
|||||||
return &result, err
|
return &result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *sqlStore) List(ctx context.Context, query *user.ListUsersCommand) (*user.ListUserResult, error) {
|
||||||
|
limit := int(query.Limit)
|
||||||
|
if limit <= 0 {
|
||||||
|
limit = 25
|
||||||
|
}
|
||||||
|
result := &user.ListUserResult{
|
||||||
|
Users: make([]*user.User, 0),
|
||||||
|
}
|
||||||
|
max := ""
|
||||||
|
err := ss.db.WithDbSession(ctx, func(dbSess *db.Session) error {
|
||||||
|
sess := dbSess.Table("user")
|
||||||
|
sess.Where("id >= ? AND is_service_account = ?", query.ContinueID, query.IsServiceAccount)
|
||||||
|
err := sess.OrderBy("id asc").Limit(limit + 1).Find(&result.Users)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the revision version
|
||||||
|
_, err = dbSess.Table("user").Select("MAX(updated)").Get(&max)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if max != "" {
|
||||||
|
t, err := time.Parse(time.DateTime, max)
|
||||||
|
if err == nil {
|
||||||
|
result.RV = t.UnixMilli()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(result.Users) > limit {
|
||||||
|
result.ContinueID = result.Users[limit].ID
|
||||||
|
result.Users = result.Users[:limit]
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
func setOptional[T any](v *T, add func(v T)) {
|
func setOptional[T any](v *T, add func(v T)) {
|
||||||
if v != nil {
|
if v != nil {
|
||||||
add(*v)
|
add(*v)
|
||||||
|
@ -212,6 +212,16 @@ func (s *Service) GetByID(ctx context.Context, query *user.GetUserByIDQuery) (*u
|
|||||||
return s.store.GetByID(ctx, query.ID)
|
return s.store.GetByID(ctx, query.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetByUID(ctx context.Context, query *user.GetUserByUIDQuery) (*user.User, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "user.GetByUID", trace.WithAttributes(
|
||||||
|
attribute.Int64("orgID", query.OrgID),
|
||||||
|
attribute.String("userUID", query.UID),
|
||||||
|
))
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
return s.store.GetByUID(ctx, query.OrgID, query.UID)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) GetByLogin(ctx context.Context, query *user.GetUserByLoginQuery) (*user.User, error) {
|
func (s *Service) GetByLogin(ctx context.Context, query *user.GetUserByLoginQuery) (*user.User, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "user.GetByLogin")
|
ctx, span := s.tracer.Start(ctx, "user.GetByLogin")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@ -368,6 +378,15 @@ func (s *Service) getSignedInUser(ctx context.Context, query *user.GetSignedInUs
|
|||||||
return usr, err
|
return usr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) List(ctx context.Context, query *user.ListUsersCommand) (*user.ListUserResult, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "user.List", trace.WithAttributes(
|
||||||
|
attribute.Int64("orgID", query.OrgID),
|
||||||
|
))
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
return s.store.List(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) Search(ctx context.Context, query *user.SearchUsersQuery) (*user.SearchUserQueryResult, error) {
|
func (s *Service) Search(ctx context.Context, query *user.SearchUsersQuery) (*user.SearchUserQueryResult, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "user.Search", trace.WithAttributes(
|
ctx, span := s.tracer.Start(ctx, "user.Search", trace.WithAttributes(
|
||||||
attribute.Int64("orgID", query.OrgID),
|
attribute.Int64("orgID", query.OrgID),
|
||||||
|
@ -291,6 +291,10 @@ func (f *FakeUserStore) GetByID(context.Context, int64) (*user.User, error) {
|
|||||||
return f.ExpectedUser, f.ExpectedError
|
return f.ExpectedUser, f.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FakeUserStore) GetByUID(context.Context, int64, string) (*user.User, error) {
|
||||||
|
return f.ExpectedUser, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FakeUserStore) LoginConflict(context.Context, string, string) error {
|
func (f *FakeUserStore) LoginConflict(context.Context, string, string) error {
|
||||||
return f.ExpectedError
|
return f.ExpectedError
|
||||||
}
|
}
|
||||||
@ -327,6 +331,10 @@ func (f *FakeUserStore) Search(ctx context.Context, query *user.SearchUsersQuery
|
|||||||
return f.ExpectedSearchUserQueryResult, f.ExpectedError
|
return f.ExpectedSearchUserQueryResult, f.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FakeUserStore) List(ctx context.Context, query *user.ListUsersCommand) (*user.ListUserResult, error) {
|
||||||
|
return nil, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FakeUserStore) Count(ctx context.Context) (int64, error) {
|
func (f *FakeUserStore) Count(ctx context.Context) (int64, error) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ type FakeUserService struct {
|
|||||||
ExpectedError error
|
ExpectedError error
|
||||||
ExpectedSetUsingOrgError error
|
ExpectedSetUsingOrgError error
|
||||||
ExpectedSearchUsers user.SearchUserQueryResult
|
ExpectedSearchUsers user.SearchUserQueryResult
|
||||||
|
ExpectedListUsers user.ListUserResult
|
||||||
ExpectedUserProfileDTO *user.UserProfileDTO
|
ExpectedUserProfileDTO *user.UserProfileDTO
|
||||||
ExpectedUserProfileDTOs []*user.UserProfileDTO
|
ExpectedUserProfileDTOs []*user.UserProfileDTO
|
||||||
ExpectedUsageStats map[string]any
|
ExpectedUsageStats map[string]any
|
||||||
@ -53,6 +54,10 @@ func (f *FakeUserService) GetByID(ctx context.Context, query *user.GetUserByIDQu
|
|||||||
return f.ExpectedUser, f.ExpectedError
|
return f.ExpectedUser, f.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FakeUserService) GetByUID(ctx context.Context, query *user.GetUserByUIDQuery) (*user.User, error) {
|
||||||
|
return f.ExpectedUser, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FakeUserService) GetByLogin(ctx context.Context, query *user.GetUserByLoginQuery) (*user.User, error) {
|
func (f *FakeUserService) GetByLogin(ctx context.Context, query *user.GetUserByLoginQuery) (*user.User, error) {
|
||||||
return f.ExpectedUser, f.ExpectedError
|
return f.ExpectedUser, f.ExpectedError
|
||||||
}
|
}
|
||||||
@ -93,6 +98,10 @@ func (f *FakeUserService) Search(ctx context.Context, query *user.SearchUsersQue
|
|||||||
return &f.ExpectedSearchUsers, f.ExpectedError
|
return &f.ExpectedSearchUsers, f.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FakeUserService) List(ctx context.Context, query *user.ListUsersCommand) (*user.ListUserResult, error) {
|
||||||
|
return &f.ExpectedListUsers, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FakeUserService) BatchDisableUsers(ctx context.Context, cmd *user.BatchDisableUsersCommand) error {
|
func (f *FakeUserService) BatchDisableUsers(ctx context.Context, cmd *user.BatchDisableUsersCommand) error {
|
||||||
if f.BatchDisableUsersFn != nil {
|
if f.BatchDisableUsersFn != nil {
|
||||||
return f.BatchDisableUsersFn(ctx, cmd)
|
return f.BatchDisableUsersFn(ctx, cmd)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Code generated by mockery v2.42.2. DO NOT EDIT.
|
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||||
|
|
||||||
package usertest
|
package usertest
|
||||||
|
|
||||||
@ -200,6 +200,36 @@ func (_m *MockService) GetByLogin(_a0 context.Context, _a1 *user.GetUserByLoginQ
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetByUID provides a mock function with given fields: _a0, _a1
|
||||||
|
func (_m *MockService) GetByUID(_a0 context.Context, _a1 *user.GetUserByUIDQuery) (*user.User, error) {
|
||||||
|
ret := _m.Called(_a0, _a1)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for GetByUID")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 *user.User
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *user.GetUserByUIDQuery) (*user.User, error)); ok {
|
||||||
|
return rf(_a0, _a1)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *user.GetUserByUIDQuery) *user.User); ok {
|
||||||
|
r0 = rf(_a0, _a1)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*user.User)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *user.GetUserByUIDQuery) error); ok {
|
||||||
|
r1 = rf(_a0, _a1)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
// GetProfile provides a mock function with given fields: _a0, _a1
|
// GetProfile provides a mock function with given fields: _a0, _a1
|
||||||
func (_m *MockService) GetProfile(_a0 context.Context, _a1 *user.GetUserProfileQuery) (*user.UserProfileDTO, error) {
|
func (_m *MockService) GetProfile(_a0 context.Context, _a1 *user.GetUserProfileQuery) (*user.UserProfileDTO, error) {
|
||||||
ret := _m.Called(_a0, _a1)
|
ret := _m.Called(_a0, _a1)
|
||||||
@ -260,36 +290,6 @@ func (_m *MockService) GetSignedInUser(_a0 context.Context, _a1 *user.GetSignedI
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSignedInUserWithCacheCtx provides a mock function with given fields: _a0, _a1
|
|
||||||
func (_m *MockService) GetSignedInUserWithCacheCtx(_a0 context.Context, _a1 *user.GetSignedInUserQuery) (*user.SignedInUser, error) {
|
|
||||||
ret := _m.Called(_a0, _a1)
|
|
||||||
|
|
||||||
if len(ret) == 0 {
|
|
||||||
panic("no return value specified for GetSignedInUserWithCacheCtx")
|
|
||||||
}
|
|
||||||
|
|
||||||
var r0 *user.SignedInUser
|
|
||||||
var r1 error
|
|
||||||
if rf, ok := ret.Get(0).(func(context.Context, *user.GetSignedInUserQuery) (*user.SignedInUser, error)); ok {
|
|
||||||
return rf(_a0, _a1)
|
|
||||||
}
|
|
||||||
if rf, ok := ret.Get(0).(func(context.Context, *user.GetSignedInUserQuery) *user.SignedInUser); ok {
|
|
||||||
r0 = rf(_a0, _a1)
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(*user.SignedInUser)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if rf, ok := ret.Get(1).(func(context.Context, *user.GetSignedInUserQuery) error); ok {
|
|
||||||
r1 = rf(_a0, _a1)
|
|
||||||
} else {
|
|
||||||
r1 = ret.Error(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0, r1
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsageStats provides a mock function with given fields: ctx
|
// GetUsageStats provides a mock function with given fields: ctx
|
||||||
func (_m *MockService) GetUsageStats(ctx context.Context) map[string]interface{} {
|
func (_m *MockService) GetUsageStats(ctx context.Context) map[string]interface{} {
|
||||||
ret := _m.Called(ctx)
|
ret := _m.Called(ctx)
|
||||||
@ -310,6 +310,36 @@ func (_m *MockService) GetUsageStats(ctx context.Context) map[string]interface{}
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List provides a mock function with given fields: _a0, _a1
|
||||||
|
func (_m *MockService) List(_a0 context.Context, _a1 *user.ListUsersCommand) (*user.ListUserResult, error) {
|
||||||
|
ret := _m.Called(_a0, _a1)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for List")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 *user.ListUserResult
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *user.ListUsersCommand) (*user.ListUserResult, error)); ok {
|
||||||
|
return rf(_a0, _a1)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *user.ListUsersCommand) *user.ListUserResult); ok {
|
||||||
|
r0 = rf(_a0, _a1)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*user.ListUserResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *user.ListUsersCommand) error); ok {
|
||||||
|
r1 = rf(_a0, _a1)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
// Search provides a mock function with given fields: _a0, _a1
|
// Search provides a mock function with given fields: _a0, _a1
|
||||||
func (_m *MockService) Search(_a0 context.Context, _a1 *user.SearchUsersQuery) (*user.SearchUserQueryResult, error) {
|
func (_m *MockService) Search(_a0 context.Context, _a1 *user.SearchUsersQuery) (*user.SearchUserQueryResult, error) {
|
||||||
ret := _m.Called(_a0, _a1)
|
ret := _m.Called(_a0, _a1)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package playlist
|
package peakq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -16,7 +16,7 @@ func TestMain(m *testing.M) {
|
|||||||
testsuite.Run(m)
|
testsuite.Run(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntegrationFoldersApp(t *testing.T) {
|
func TestIntegrationPeakQ(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("skipping integration test")
|
t.Skip("skipping integration test")
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
import { Team as TeamDTO } from '@grafana/schema/src/raw/team/x/team_types.gen';
|
|
||||||
|
|
||||||
import { Role } from './accessControl';
|
import { Role } from './accessControl';
|
||||||
import { TeamPermissionLevel } from './acl';
|
import { TeamPermissionLevel } from './acl';
|
||||||
|
|
||||||
// The team resource
|
export interface TeamDTO {
|
||||||
export { TeamDTO };
|
/**
|
||||||
|
* Email of the team.
|
||||||
|
*/
|
||||||
|
email?: string;
|
||||||
|
/**
|
||||||
|
* Name of the team.
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
// This is the team resource with permissions and metadata expanded
|
// This is the team resource with permissions and metadata expanded
|
||||||
export interface Team {
|
export interface Team {
|
||||||
|
Loading…
Reference in New Issue
Block a user