SSOSettings: Add api:s (#92018)
* apis: add sso setting resource * Implement Storage for sso * Rename packages * Merge identity and sso package * Update table format and expose GetNestedBool * Restructure identity api package
This commit is contained in:
@@ -101,6 +101,14 @@ func (u *Unstructured) GetNestedString(fields ...string) string {
|
||||
return val
|
||||
}
|
||||
|
||||
func (u *Unstructured) GetNestedBool(fields ...string) bool {
|
||||
val, found, err := unstructured.NestedBool(u.Object, fields...)
|
||||
if !found || err != nil {
|
||||
return false
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (u *Unstructured) GetNestedStringSlice(fields ...string) []string {
|
||||
val, found, err := unstructured.NestedStringSlice(u.Object, fields...)
|
||||
if !found || err != nil {
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"github.com/grafana/authlib/claims"
|
||||
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 IdentityDisplayResults struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// Request keys used to lookup the display value
|
||||
// +listType=set
|
||||
Keys []string `json:"keys"`
|
||||
|
||||
// Matching items (the caller may need to remap from keys to results)
|
||||
// +listType=atomic
|
||||
Display []IdentityDisplay `json:"display"`
|
||||
|
||||
// Input keys that were not useable
|
||||
// +listType=set
|
||||
InvalidKeys []string `json:"invalidKeys,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityDisplay struct {
|
||||
IdentityType claims.IdentityType `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
|
||||
InternalID int64 `json:"internalId,omitempty"`
|
||||
}
|
||||
+31
-10
@@ -95,6 +95,32 @@ var ServiceAccountResourceInfo = common.NewResourceInfo(GROUP, VERSION,
|
||||
},
|
||||
)
|
||||
|
||||
var SSOSettingResourceInfo = common.NewResourceInfo(
|
||||
GROUP, VERSION, "ssosettings", "ssosetting", "SSOSetting",
|
||||
func() runtime.Object { return &SSOSetting{} },
|
||||
func() runtime.Object { return &SSOSettingList{} },
|
||||
utils.TableColumns{
|
||||
Definition: []metav1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name"},
|
||||
{Name: "Source", Type: "string"},
|
||||
{Name: "Enabled", Type: "boolean"},
|
||||
{Name: "Created At", Type: "string", Format: "date"},
|
||||
},
|
||||
Reader: func(obj any) ([]interface{}, error) {
|
||||
m, ok := obj.(*SSOSetting)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected sso setting")
|
||||
}
|
||||
return []interface{}{
|
||||
m.Name,
|
||||
m.Spec.Source,
|
||||
m.Spec.Settings.GetNestedBool("enabled"),
|
||||
m.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION}
|
||||
@@ -105,15 +131,10 @@ var (
|
||||
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},
|
||||
func AddKnownTypes(scheme *runtime.Scheme, version string) {
|
||||
scheme.AddKnownTypes(
|
||||
schema.GroupVersion{Group: GROUP, Version: version},
|
||||
&User{},
|
||||
&UserList{},
|
||||
&ServiceAccount{},
|
||||
@@ -121,9 +142,9 @@ func AddKnownTypes(scheme *runtime.Scheme, version string) error {
|
||||
&Team{},
|
||||
&TeamList{},
|
||||
&IdentityDisplayResults{},
|
||||
&SSOSetting{},
|
||||
&SSOSettingList{},
|
||||
)
|
||||
// metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
@@ -0,0 +1,33 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"github.com/grafana/authlib/claims"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type IdentityDisplayResults struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// Request keys used to lookup the display value
|
||||
// +listType=set
|
||||
Keys []string `json:"keys"`
|
||||
|
||||
// Matching items (the caller may need to remap from keys to results)
|
||||
// +listType=atomic
|
||||
Display []IdentityDisplay `json:"display"`
|
||||
|
||||
// Input keys that were not useable
|
||||
// +listType=set
|
||||
InvalidKeys []string `json:"invalidKeys,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityDisplay struct {
|
||||
IdentityType claims.IdentityType `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
|
||||
InternalID int64 `json:"internalId,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package v0alpha1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// +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"`
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type SSOSetting struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec SSOSettingSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// SSOSettingSpec defines model for SSOSettingSpec.
|
||||
type SSOSettingSpec struct {
|
||||
Source Source `json:"source"`
|
||||
Settings common.Unstructured `json:"settings"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type SSOSettingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []SSOSetting `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// Source for settings.
|
||||
// +enum
|
||||
type Source string
|
||||
|
||||
// Defines values for ItemType.
|
||||
const (
|
||||
SourceDB Source = "db"
|
||||
// system is from config file, env or argument
|
||||
SourceSystem Source = "system"
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
package v0alpha1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// +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"`
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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"`
|
||||
}
|
||||
+77
@@ -67,6 +67,83 @@ func (in *IdentityDisplayResults) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SSOSetting) DeepCopyInto(out *SSOSetting) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSOSetting.
|
||||
func (in *SSOSetting) DeepCopy() *SSOSetting {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SSOSetting)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *SSOSetting) 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 *SSOSettingList) DeepCopyInto(out *SSOSettingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]SSOSetting, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSOSettingList.
|
||||
func (in *SSOSettingList) DeepCopy() *SSOSettingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SSOSettingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *SSOSettingList) 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 *SSOSettingSpec) DeepCopyInto(out *SSOSettingSpec) {
|
||||
*out = *in
|
||||
in.Settings.DeepCopyInto(&out.Settings)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSOSettingSpec.
|
||||
func (in *SSOSettingSpec) DeepCopy() *SSOSettingSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SSOSettingSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// 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
|
||||
+159
-38
@@ -14,21 +14,24 @@ import (
|
||||
|
||||
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.IdentityDisplayResults": schema_apimachinery_apis_identity_v0alpha1_IdentityDisplayResults(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),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.IdentityDisplay": schema_pkg_apis_identity_v0alpha1_IdentityDisplay(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.IdentityDisplayResults": schema_pkg_apis_identity_v0alpha1_IdentityDisplayResults(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.SSOSetting": schema_pkg_apis_identity_v0alpha1_SSOSetting(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.SSOSettingList": schema_pkg_apis_identity_v0alpha1_SSOSettingList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.SSOSettingSpec": schema_pkg_apis_identity_v0alpha1_SSOSettingSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.ServiceAccount": schema_pkg_apis_identity_v0alpha1_ServiceAccount(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.ServiceAccountList": schema_pkg_apis_identity_v0alpha1_ServiceAccountList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.ServiceAccountSpec": schema_pkg_apis_identity_v0alpha1_ServiceAccountSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.Team": schema_pkg_apis_identity_v0alpha1_Team(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.TeamList": schema_pkg_apis_identity_v0alpha1_TeamList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.TeamSpec": schema_pkg_apis_identity_v0alpha1_TeamSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.User": schema_pkg_apis_identity_v0alpha1_User(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.UserList": schema_pkg_apis_identity_v0alpha1_UserList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.UserSpec": schema_pkg_apis_identity_v0alpha1_UserSpec(ref),
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_IdentityDisplay(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_IdentityDisplay(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -77,7 +80,7 @@ func schema_apimachinery_apis_identity_v0alpha1_IdentityDisplay(ref common.Refer
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_IdentityDisplayResults(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_IdentityDisplayResults(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -130,7 +133,7 @@ func schema_apimachinery_apis_identity_v0alpha1_IdentityDisplayResults(ref commo
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.IdentityDisplay"),
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/identity/v0alpha1.IdentityDisplay"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -161,11 +164,11 @@ func schema_apimachinery_apis_identity_v0alpha1_IdentityDisplayResults(ref commo
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.IdentityDisplay"},
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.IdentityDisplay"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_ServiceAccount(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_SSOSetting(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -187,25 +190,26 @@ func schema_apimachinery_apis_identity_v0alpha1_ServiceAccount(ref common.Refere
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
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"),
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/identity/v0alpha1.SSOSettingSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccountSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.SSOSettingSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_ServiceAccountList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_SSOSettingList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -238,7 +242,7 @@ func schema_apimachinery_apis_identity_v0alpha1_ServiceAccountList(ref common.Re
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccount"),
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/identity/v0alpha1.SSOSetting"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -248,11 +252,128 @@ func schema_apimachinery_apis_identity_v0alpha1_ServiceAccountList(ref common.Re
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.ServiceAccount", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.SSOSetting", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_ServiceAccountSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_SSOSettingSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "SSOSettingSpec defines model for SSOSettingSpec.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"source": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Possible enum values:\n - `\"db\"`\n - `\"system\"` system is from config file, env or argument",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
Enum: []interface{}{"db", "system"},
|
||||
},
|
||||
},
|
||||
"settings": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"source", "settings"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_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/apis/identity/v0alpha1.ServiceAccountSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.ServiceAccountSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_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/apis/identity/v0alpha1.ServiceAccount"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.ServiceAccount", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_identity_v0alpha1_ServiceAccountSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -288,7 +409,7 @@ func schema_apimachinery_apis_identity_v0alpha1_ServiceAccountSpec(ref common.Re
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_Team(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_Team(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -317,18 +438,18 @@ func schema_apimachinery_apis_identity_v0alpha1_Team(ref common.ReferenceCallbac
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.TeamSpec"),
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/identity/v0alpha1.TeamSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.TeamSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.TeamSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_TeamList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_TeamList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -361,7 +482,7 @@ func schema_apimachinery_apis_identity_v0alpha1_TeamList(ref common.ReferenceCal
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.Team"),
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/identity/v0alpha1.Team"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -371,11 +492,11 @@ func schema_apimachinery_apis_identity_v0alpha1_TeamList(ref common.ReferenceCal
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.Team", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.Team", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_TeamSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_TeamSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -399,7 +520,7 @@ func schema_apimachinery_apis_identity_v0alpha1_TeamSpec(ref common.ReferenceCal
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_User(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_User(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -428,18 +549,18 @@ func schema_apimachinery_apis_identity_v0alpha1_User(ref common.ReferenceCallbac
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.UserSpec"),
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/identity/v0alpha1.UserSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.UserSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.UserSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_UserList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_UserList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -472,7 +593,7 @@ func schema_apimachinery_apis_identity_v0alpha1_UserList(ref common.ReferenceCal
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.User"),
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/identity/v0alpha1.User"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -482,11 +603,11 @@ func schema_apimachinery_apis_identity_v0alpha1_UserList(ref common.ReferenceCal
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1.User", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
"github.com/grafana/grafana/pkg/apis/identity/v0alpha1.User", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_identity_v0alpha1_UserSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_identity_v0alpha1_UserSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
+3
-3
@@ -1,3 +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,InternalID
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1,TeamSpec,Title
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/identity/v0alpha1,IdentityDisplay,IdentityType
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/identity/v0alpha1,IdentityDisplay,InternalID
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/identity/v0alpha1,TeamSpec,Title
|
||||
@@ -1,87 +0,0 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
identity "github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
)
|
||||
|
||||
type userTeamsREST struct {
|
||||
logger log.Logger
|
||||
store legacy.LegacyIdentityStore
|
||||
}
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*userTeamsREST)(nil)
|
||||
_ rest.SingularNameProvider = (*userTeamsREST)(nil)
|
||||
_ rest.Connecter = (*userTeamsREST)(nil)
|
||||
_ rest.Scoper = (*userTeamsREST)(nil)
|
||||
_ rest.StorageMetadata = (*userTeamsREST)(nil)
|
||||
)
|
||||
|
||||
func newUserTeamsREST(store legacy.LegacyIdentityStore) *userTeamsREST {
|
||||
return &userTeamsREST{
|
||||
logger: log.New("user teams"),
|
||||
store: store,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) New() runtime.Object {
|
||||
return &identity.TeamList{}
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) Destroy() {}
|
||||
|
||||
func (r *userTeamsREST) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) GetSingularName() string {
|
||||
return "TeamList" // Used for the
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"} // and parquet!
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) ProducesObject(verb string) interface{} {
|
||||
return &identity.TeamList{}
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) ConnectMethods() []string {
|
||||
return []string{"GET"}
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
return nil, false, "" // true means you can use the trailing path as a variable
|
||||
}
|
||||
|
||||
func (r *userTeamsREST) Connect(ctx context.Context, name string, _ runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
teams, err := r.store.GetUserTeams(ctx, ns, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
|
||||
list := &identity.TeamList{}
|
||||
for _, team := range teams {
|
||||
t, err := asTeam(&team, ns.Value)
|
||||
if err != nil {
|
||||
responder.Error(err)
|
||||
return
|
||||
}
|
||||
list.Items = append(list.Items, *t)
|
||||
}
|
||||
responder.Object(200, list)
|
||||
}), nil
|
||||
}
|
||||
@@ -13,13 +13,18 @@ import (
|
||||
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"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/legacy"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/serviceaccount"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/sso"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/team"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/user"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/builder"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings"
|
||||
"github.com/grafana/grafana/pkg/storage/legacysql"
|
||||
)
|
||||
|
||||
@@ -27,14 +32,14 @@ var _ builder.APIGroupBuilder = (*IdentityAPIBuilder)(nil)
|
||||
|
||||
// This is used just so wire has something unique to return
|
||||
type IdentityAPIBuilder struct {
|
||||
Store legacy.LegacyIdentityStore
|
||||
Store legacy.LegacyIdentityStore
|
||||
SSOService ssosettings.Service
|
||||
}
|
||||
|
||||
func RegisterAPIService(
|
||||
features featuremgmt.FeatureToggles,
|
||||
apiregistration builder.APIRegistrar,
|
||||
// svcTeam team.Service,
|
||||
// svcUser user.Service,
|
||||
ssoService ssosettings.Service,
|
||||
sql db.DB,
|
||||
) (*IdentityAPIBuilder, error) {
|
||||
if !features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) {
|
||||
@@ -42,34 +47,28 @@ func RegisterAPIService(
|
||||
}
|
||||
|
||||
builder := &IdentityAPIBuilder{
|
||||
Store: legacy.NewLegacySQLStores(legacysql.NewDatabaseProvider(sql)),
|
||||
Store: legacy.NewLegacySQLStores(legacysql.NewDatabaseProvider(sql)),
|
||||
SSOService: ssoService,
|
||||
}
|
||||
apiregistration.RegisterAPI(builder)
|
||||
|
||||
return builder, nil
|
||||
}
|
||||
|
||||
func (b *IdentityAPIBuilder) GetGroupVersion() schema.GroupVersion {
|
||||
return identity.SchemeGroupVersion
|
||||
return identityv0.SchemeGroupVersion
|
||||
}
|
||||
|
||||
func (b *IdentityAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
|
||||
if err := identity.AddKnownTypes(scheme, identity.VERSION); err != nil {
|
||||
return err
|
||||
}
|
||||
identityv0.AddKnownTypes(scheme, identityv0.VERSION)
|
||||
|
||||
// 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
|
||||
}
|
||||
// "no kind is registered for the type"
|
||||
identityv0.AddKnownTypes(scheme, runtime.APIVersionInternal)
|
||||
|
||||
// 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)
|
||||
metav1.AddToGroupVersion(scheme, identityv0.SchemeGroupVersion)
|
||||
return scheme.SetVersionPriority(identityv0.SchemeGroupVersion)
|
||||
}
|
||||
|
||||
func (b *IdentityAPIBuilder) GetAPIGroupInfo(
|
||||
@@ -78,53 +77,45 @@ func (b *IdentityAPIBuilder) GetAPIGroupInfo(
|
||||
optsGetter generic.RESTOptionsGetter,
|
||||
dualWriteBuilder grafanarest.DualWriteBuilder,
|
||||
) (*genericapiserver.APIGroupInfo, error) {
|
||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(identity.GROUP, scheme, metav1.ParameterCodec, codecs)
|
||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(identityv0.GROUP, scheme, metav1.ParameterCodec, codecs)
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
team := identity.TeamResourceInfo
|
||||
teamStore := &legacyTeamStorage{
|
||||
service: b.Store,
|
||||
resourceInfo: team,
|
||||
tableConverter: team.TableConverter(),
|
||||
}
|
||||
storage[team.StoragePath()] = teamStore
|
||||
teamResource := identityv0.TeamResourceInfo
|
||||
storage[teamResource.StoragePath()] = team.NewLegacyStore(b.Store)
|
||||
|
||||
user := identity.UserResourceInfo
|
||||
userStore := &legacyUserStorage{
|
||||
service: b.Store,
|
||||
resourceInfo: user,
|
||||
tableConverter: user.TableConverter(),
|
||||
}
|
||||
storage[user.StoragePath()] = userStore
|
||||
storage[user.StoragePath("teams")] = newUserTeamsREST(b.Store)
|
||||
userResource := identityv0.UserResourceInfo
|
||||
storage[userResource.StoragePath()] = user.NewLegacyStore(b.Store)
|
||||
storage[userResource.StoragePath("teams")] = team.NewLegacyUserTeamsStore(b.Store)
|
||||
|
||||
sa := identity.ServiceAccountResourceInfo
|
||||
saStore := &legacyServiceAccountStorage{
|
||||
service: b.Store,
|
||||
resourceInfo: sa,
|
||||
tableConverter: sa.TableConverter(),
|
||||
serviceaccountResource := identityv0.ServiceAccountResourceInfo
|
||||
storage[serviceaccountResource.StoragePath()] = serviceaccount.NewLegacyStore(b.Store)
|
||||
|
||||
if b.SSOService != nil {
|
||||
ssoResource := identityv0.SSOSettingResourceInfo
|
||||
storage[ssoResource.StoragePath()] = sso.NewLegacyStore(b.SSOService)
|
||||
}
|
||||
storage[sa.StoragePath()] = saStore
|
||||
|
||||
// The display endpoint -- NOTE, this uses a rewrite hack to allow requests without a name parameter
|
||||
storage["display"] = newDisplayREST(b.Store)
|
||||
storage["display"] = user.NewLegacyDisplayStore(b.Store)
|
||||
|
||||
apiGroupInfo.VersionedResourcesStorageMap[identity.VERSION] = storage
|
||||
apiGroupInfo.VersionedResourcesStorageMap[identityv0.VERSION] = storage
|
||||
return &apiGroupInfo, nil
|
||||
}
|
||||
|
||||
func (b *IdentityAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
|
||||
return identity.GetOpenAPIDefinitions
|
||||
return identityv0.GetOpenAPIDefinitions
|
||||
}
|
||||
|
||||
func (b *IdentityAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
return nil // no custom API routes
|
||||
// no custom API routes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IdentityAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
||||
// TODO: handle authorization based in entity.
|
||||
return authorizer.AuthorizerFunc(
|
||||
func(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
user, err := identityapi.GetRequester(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return authorizer.DecisionDeny, "no identity found", err
|
||||
}
|
||||
|
||||
+40
-36
@@ -1,59 +1,63 @@
|
||||
package identity
|
||||
package serviceaccount
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
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/registry/apis/identity/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"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"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/legacy"
|
||||
"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)
|
||||
_ rest.Scoper = (*LegacyStore)(nil)
|
||||
_ rest.SingularNameProvider = (*LegacyStore)(nil)
|
||||
_ rest.Getter = (*LegacyStore)(nil)
|
||||
_ rest.Lister = (*LegacyStore)(nil)
|
||||
_ rest.Storage = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
type legacyServiceAccountStorage struct {
|
||||
service legacy.LegacyIdentityStore
|
||||
tableConverter rest.TableConvertor
|
||||
resourceInfo common.ResourceInfo
|
||||
var resource = identityv0.ServiceAccountResourceInfo
|
||||
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore) *LegacyStore {
|
||||
return &LegacyStore{store}
|
||||
}
|
||||
|
||||
func (s *legacyServiceAccountStorage) New() runtime.Object {
|
||||
return s.resourceInfo.NewFunc()
|
||||
type LegacyStore struct {
|
||||
store legacy.LegacyIdentityStore
|
||||
}
|
||||
|
||||
func (s *legacyServiceAccountStorage) Destroy() {}
|
||||
func (s *LegacyStore) New() runtime.Object {
|
||||
return resource.NewFunc()
|
||||
}
|
||||
|
||||
func (s *legacyServiceAccountStorage) NamespaceScoped() bool {
|
||||
func (s *LegacyStore) Destroy() {}
|
||||
|
||||
func (s *LegacyStore) NamespaceScoped() bool {
|
||||
return true // namespace == org
|
||||
}
|
||||
|
||||
func (s *legacyServiceAccountStorage) GetSingularName() string {
|
||||
return s.resourceInfo.GetSingularName()
|
||||
func (s *LegacyStore) GetSingularName() string {
|
||||
return resource.GetSingularName()
|
||||
}
|
||||
|
||||
func (s *legacyServiceAccountStorage) NewList() runtime.Object {
|
||||
return s.resourceInfo.NewListFunc()
|
||||
func (s *LegacyStore) NewList() runtime.Object {
|
||||
return resource.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 *LegacyStore) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||
return resource.TableConverter().ConvertToTable(ctx, object, tableOptions)
|
||||
}
|
||||
|
||||
func (s *legacyServiceAccountStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -70,12 +74,12 @@ func (s *legacyServiceAccountStorage) List(ctx context.Context, options *interna
|
||||
}
|
||||
}
|
||||
|
||||
found, err := s.service.ListUsers(ctx, ns, query)
|
||||
found, err := s.store.ListUsers(ctx, ns, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := &identity.ServiceAccountList{}
|
||||
list := &identityv0.ServiceAccountList{}
|
||||
for _, item := range found.Users {
|
||||
list.Items = append(list.Items, *toSAItem(&item, ns.Value))
|
||||
}
|
||||
@@ -88,15 +92,15 @@ func (s *legacyServiceAccountStorage) List(ctx context.Context, options *interna
|
||||
return list, err
|
||||
}
|
||||
|
||||
func toSAItem(u *user.User, ns string) *identity.ServiceAccount {
|
||||
item := &identity.ServiceAccount{
|
||||
func toSAItem(u *user.User, ns string) *identityv0.ServiceAccount {
|
||||
item := &identityv0.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: u.UID,
|
||||
Namespace: ns,
|
||||
ResourceVersion: fmt.Sprintf("%d", u.Updated.UnixMilli()),
|
||||
CreationTimestamp: metav1.NewTime(u.Created),
|
||||
},
|
||||
Spec: identity.ServiceAccountSpec{
|
||||
Spec: identityv0.ServiceAccountSpec{
|
||||
Name: u.Name,
|
||||
Email: u.Email,
|
||||
EmailVerified: u.EmailVerified,
|
||||
@@ -112,7 +116,7 @@ func toSAItem(u *user.User, ns string) *identity.ServiceAccount {
|
||||
return item
|
||||
}
|
||||
|
||||
func (s *legacyServiceAccountStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -123,12 +127,12 @@ func (s *legacyServiceAccountStorage) Get(ctx context.Context, name string, opti
|
||||
IsServiceAccount: true,
|
||||
}
|
||||
|
||||
found, err := s.service.ListUsers(ctx, ns, query)
|
||||
found, err := s.store.ListUsers(ctx, ns, query)
|
||||
if found == nil || err != nil {
|
||||
return nil, s.resourceInfo.NewNotFound(name)
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
if len(found.Users) < 1 {
|
||||
return nil, s.resourceInfo.NewNotFound(name)
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
return toSAItem(&found.Users[0], ns.Value), nil
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
package sso
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
commonv1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings"
|
||||
ssomodels "github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||
)
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*LegacyStore)(nil)
|
||||
_ rest.Scoper = (*LegacyStore)(nil)
|
||||
_ rest.Getter = (*LegacyStore)(nil)
|
||||
_ rest.Lister = (*LegacyStore)(nil)
|
||||
_ rest.Updater = (*LegacyStore)(nil)
|
||||
_ rest.SingularNameProvider = (*LegacyStore)(nil)
|
||||
_ rest.GracefulDeleter = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
var resource = identityv0.SSOSettingResourceInfo
|
||||
|
||||
func NewLegacyStore(service ssosettings.Service) *LegacyStore {
|
||||
return &LegacyStore{service}
|
||||
}
|
||||
|
||||
type LegacyStore struct {
|
||||
service ssosettings.Service
|
||||
}
|
||||
|
||||
// Destroy implements rest.Storage.
|
||||
func (s *LegacyStore) Destroy() {}
|
||||
|
||||
// NamespaceScoped implements rest.Scoper.
|
||||
func (s *LegacyStore) NamespaceScoped() bool {
|
||||
// this is maybe incorrect
|
||||
return true
|
||||
}
|
||||
|
||||
// GetSingularName implements rest.SingularNameProvider.
|
||||
func (s *LegacyStore) GetSingularName() string {
|
||||
return resource.GetSingularName()
|
||||
}
|
||||
|
||||
// New implements rest.Storage.
|
||||
func (s *LegacyStore) New() runtime.Object {
|
||||
return resource.NewFunc()
|
||||
}
|
||||
|
||||
// ConvertToTable implements rest.Lister.
|
||||
func (s *LegacyStore) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||
return resource.TableConverter().ConvertToTable(ctx, object, tableOptions)
|
||||
}
|
||||
|
||||
// NewList implements rest.Lister.
|
||||
func (s *LegacyStore) NewList() runtime.Object {
|
||||
return resource.NewListFunc()
|
||||
}
|
||||
|
||||
// List implements rest.Lister.
|
||||
func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
ns, _ := request.NamespaceInfoFrom(ctx, false)
|
||||
|
||||
settings, err := s.service.List(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list sso settings: %w", err)
|
||||
}
|
||||
|
||||
list := &identityv0.SSOSettingList{}
|
||||
for _, s := range settings {
|
||||
list.Items = append(list.Items, mapToObject(ns.Value, s))
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// Get implements rest.Getter.
|
||||
func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
ns, _ := request.NamespaceInfoFrom(ctx, false)
|
||||
|
||||
setting, err := s.service.GetForProviderWithRedactedSecrets(ctx, name)
|
||||
if err != nil {
|
||||
if errors.Is(err, ssosettings.ErrNotFound) {
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
object := mapToObject(ns.Value, setting)
|
||||
return &object, nil
|
||||
}
|
||||
|
||||
// Update implements rest.Updater.
|
||||
func (s *LegacyStore) Update(
|
||||
ctx context.Context,
|
||||
name string,
|
||||
objInfo rest.UpdatedObjectInfo,
|
||||
_ rest.ValidateObjectFunc,
|
||||
_ rest.ValidateObjectUpdateFunc,
|
||||
_ bool,
|
||||
_ *metav1.UpdateOptions,
|
||||
) (runtime.Object, bool, error) {
|
||||
const created = false
|
||||
ident, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, created, err
|
||||
}
|
||||
|
||||
old, err := s.Get(ctx, name, nil)
|
||||
if err != nil {
|
||||
return old, created, err
|
||||
}
|
||||
|
||||
obj, err := objInfo.UpdatedObject(ctx, old)
|
||||
if err != nil {
|
||||
return old, created, err
|
||||
}
|
||||
|
||||
setting, ok := obj.(*identityv0.SSOSetting)
|
||||
if !ok {
|
||||
return old, created, errors.New("expected ssosetting after update")
|
||||
}
|
||||
|
||||
if err := s.service.Upsert(ctx, mapToModel(setting), ident); err != nil {
|
||||
return old, created, err
|
||||
}
|
||||
|
||||
updated, err := s.Get(ctx, name, nil)
|
||||
return updated, created, err
|
||||
}
|
||||
|
||||
// Delete implements rest.GracefulDeleter.
|
||||
func (s *LegacyStore) Delete(
|
||||
ctx context.Context,
|
||||
name string,
|
||||
_ rest.ValidateObjectFunc,
|
||||
options *metav1.DeleteOptions,
|
||||
) (runtime.Object, bool, error) {
|
||||
obj, err := s.Get(ctx, name, nil)
|
||||
if err != nil {
|
||||
return obj, false, err
|
||||
}
|
||||
|
||||
old, ok := obj.(*identityv0.SSOSetting)
|
||||
if !ok {
|
||||
return obj, false, errors.New("expected ssosetting")
|
||||
}
|
||||
|
||||
// FIXME(kalleep): this should probably be validated in transaction
|
||||
if options.Preconditions != nil && options.Preconditions.ResourceVersion != nil {
|
||||
if *options.Preconditions.ResourceVersion != old.GetResourceVersion() {
|
||||
return old, false, apierrors.NewConflict(
|
||||
resource.GroupResource(),
|
||||
name,
|
||||
fmt.Errorf(
|
||||
"the ResourceVersion in the precondition (%s) does not match the ResourceVersion in record (%s). The object might have been modified",
|
||||
*options.Preconditions.ResourceVersion,
|
||||
old.GetResourceVersion(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.service.Delete(ctx, name); err != nil {
|
||||
return old, false, err
|
||||
}
|
||||
|
||||
// If settings for a provider is deleted from db they will fallback to settings from config file, env or arguments.
|
||||
afterDelete, err := s.Get(ctx, name, nil)
|
||||
return afterDelete, false, err
|
||||
}
|
||||
|
||||
func mapToObject(ns string, s *ssomodels.SSOSettings) identityv0.SSOSetting {
|
||||
source := identityv0.SourceDB
|
||||
if s.Source == ssomodels.System {
|
||||
source = identityv0.SourceSystem
|
||||
}
|
||||
|
||||
version := "0"
|
||||
if !s.Updated.IsZero() {
|
||||
version = fmt.Sprintf("%d", s.Updated.UnixMilli())
|
||||
}
|
||||
|
||||
object := identityv0.SSOSetting{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: s.Provider,
|
||||
Namespace: ns,
|
||||
UID: types.UID(s.Provider),
|
||||
ResourceVersion: version,
|
||||
CreationTimestamp: metav1.NewTime(s.Updated),
|
||||
},
|
||||
Spec: identityv0.SSOSettingSpec{
|
||||
Source: source,
|
||||
Settings: commonv1.Unstructured{Object: s.Settings},
|
||||
},
|
||||
}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func mapToModel(obj *identityv0.SSOSetting) *ssomodels.SSOSettings {
|
||||
return &ssomodels.SSOSettings{
|
||||
Provider: obj.Name,
|
||||
Settings: obj.Spec.Settings.Object,
|
||||
}
|
||||
}
|
||||
+45
-40
@@ -1,81 +1,86 @@
|
||||
package identity
|
||||
package team
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
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/registry/apis/identity/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
"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"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/legacy"
|
||||
"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)
|
||||
_ rest.Scoper = (*LegacyStore)(nil)
|
||||
_ rest.SingularNameProvider = (*LegacyStore)(nil)
|
||||
_ rest.Getter = (*LegacyStore)(nil)
|
||||
_ rest.Lister = (*LegacyStore)(nil)
|
||||
_ rest.Storage = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
type legacyTeamStorage struct {
|
||||
service legacy.LegacyIdentityStore
|
||||
tableConverter rest.TableConvertor
|
||||
resourceInfo common.ResourceInfo
|
||||
var resource = identityv0.TeamResourceInfo
|
||||
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore) *LegacyStore {
|
||||
return &LegacyStore{store}
|
||||
}
|
||||
|
||||
func (s *legacyTeamStorage) New() runtime.Object {
|
||||
return s.resourceInfo.NewFunc()
|
||||
type LegacyStore struct {
|
||||
store legacy.LegacyIdentityStore
|
||||
}
|
||||
|
||||
func (s *legacyTeamStorage) Destroy() {}
|
||||
|
||||
func (s *legacyTeamStorage) NamespaceScoped() bool {
|
||||
return true // namespace == org
|
||||
func (s *LegacyStore) New() runtime.Object {
|
||||
return resource.NewFunc()
|
||||
}
|
||||
|
||||
func (s *legacyTeamStorage) GetSingularName() string {
|
||||
return s.resourceInfo.GetSingularName()
|
||||
func (s *LegacyStore) Destroy() {}
|
||||
|
||||
func (s *LegacyStore) NamespaceScoped() bool {
|
||||
// namespace == org
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *legacyTeamStorage) NewList() runtime.Object {
|
||||
return s.resourceInfo.NewListFunc()
|
||||
func (s *LegacyStore) GetSingularName() string {
|
||||
return resource.GetSingularName()
|
||||
}
|
||||
|
||||
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 *LegacyStore) NewList() runtime.Object {
|
||||
return resource.NewListFunc()
|
||||
}
|
||||
|
||||
func (s *legacyTeamStorage) doList(ctx context.Context, ns claims.NamespaceInfo, query legacy.ListTeamQuery) (*identity.TeamList, error) {
|
||||
func (s *LegacyStore) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||
return resource.TableConverter().ConvertToTable(ctx, object, tableOptions)
|
||||
}
|
||||
|
||||
func (s *LegacyStore) doList(ctx context.Context, ns claims.NamespaceInfo, query legacy.ListTeamQuery) (*identityv0.TeamList, error) {
|
||||
if query.Limit < 1 {
|
||||
query.Limit = 100
|
||||
}
|
||||
|
||||
rsp, err := s.service.ListTeams(ctx, ns, query)
|
||||
rsp, err := s.store.ListTeams(ctx, ns, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list := &identity.TeamList{
|
||||
list := &identityv0.TeamList{
|
||||
ListMeta: metav1.ListMeta{
|
||||
ResourceVersion: strconv.FormatInt(rsp.RV, 10),
|
||||
},
|
||||
}
|
||||
for _, team := range rsp.Teams {
|
||||
item := identity.Team{
|
||||
item := identityv0.Team{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: team.UID,
|
||||
Namespace: ns.Value,
|
||||
CreationTimestamp: metav1.NewTime(team.Created),
|
||||
ResourceVersion: strconv.FormatInt(team.Updated.UnixMilli(), 10),
|
||||
},
|
||||
Spec: identity.TeamSpec{
|
||||
Spec: identityv0.TeamSpec{
|
||||
Title: team.Name,
|
||||
Email: team.Email,
|
||||
},
|
||||
@@ -97,7 +102,7 @@ func (s *legacyTeamStorage) doList(ctx context.Context, ns claims.NamespaceInfo,
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (s *legacyTeamStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -115,7 +120,7 @@ func (s *legacyTeamStorage) List(ctx context.Context, options *internalversion.L
|
||||
return s.doList(ctx, ns, query)
|
||||
}
|
||||
|
||||
func (s *legacyTeamStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -131,18 +136,18 @@ func (s *legacyTeamStorage) Get(ctx context.Context, name string, options *metav
|
||||
if len(rsp.Items) > 0 {
|
||||
return &rsp.Items[0], nil
|
||||
}
|
||||
return nil, s.resourceInfo.NewNotFound(name)
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
|
||||
func asTeam(team *team.Team, ns string) (*identity.Team, error) {
|
||||
item := &identity.Team{
|
||||
func asTeam(team *team.Team, ns string) (*identityv0.Team, error) {
|
||||
item := &identityv0.Team{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: team.UID,
|
||||
Namespace: ns,
|
||||
CreationTimestamp: metav1.NewTime(team.Created),
|
||||
ResourceVersion: strconv.FormatInt(team.Updated.UnixMilli(), 10),
|
||||
},
|
||||
Spec: identity.TeamSpec{
|
||||
Spec: identityv0.TeamSpec{
|
||||
Title: team.Name,
|
||||
Email: team.Email,
|
||||
},
|
||||
@@ -0,0 +1,88 @@
|
||||
package team
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
)
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*LegacyUserTeamsStore)(nil)
|
||||
_ rest.SingularNameProvider = (*LegacyUserTeamsStore)(nil)
|
||||
_ rest.Connecter = (*LegacyUserTeamsStore)(nil)
|
||||
_ rest.Scoper = (*LegacyUserTeamsStore)(nil)
|
||||
_ rest.StorageMetadata = (*LegacyUserTeamsStore)(nil)
|
||||
)
|
||||
|
||||
func NewLegacyUserTeamsStore(store legacy.LegacyIdentityStore) *LegacyUserTeamsStore {
|
||||
return &LegacyUserTeamsStore{
|
||||
logger: log.New("user teams"),
|
||||
store: store,
|
||||
}
|
||||
}
|
||||
|
||||
type LegacyUserTeamsStore struct {
|
||||
logger log.Logger
|
||||
store legacy.LegacyIdentityStore
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) New() runtime.Object {
|
||||
return &identityv0.TeamList{}
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) Destroy() {}
|
||||
|
||||
func (r *LegacyUserTeamsStore) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) GetSingularName() string {
|
||||
return "TeamList"
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"}
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) ProducesObject(verb string) interface{} {
|
||||
return &identityv0.TeamList{}
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) ConnectMethods() []string {
|
||||
return []string{"GET"}
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
return nil, false, "" // true means you can use the trailing path as a variable
|
||||
}
|
||||
|
||||
func (r *LegacyUserTeamsStore) Connect(ctx context.Context, name string, _ runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
teams, err := r.store.GetUserTeams(ctx, ns, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
|
||||
list := &identityv0.TeamList{}
|
||||
for _, team := range teams {
|
||||
t, err := asTeam(&team, ns.Value)
|
||||
if err != nil {
|
||||
responder.Error(err)
|
||||
return
|
||||
}
|
||||
list.Items = append(list.Items, *t)
|
||||
}
|
||||
responder.Object(200, list)
|
||||
}), nil
|
||||
}
|
||||
+21
-20
@@ -1,4 +1,4 @@
|
||||
package identity
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
identity "github.com/grafana/grafana/pkg/apimachinery/apis/identity/v0alpha1"
|
||||
identity "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@@ -18,56 +18,57 @@ import (
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
)
|
||||
|
||||
type displayREST struct {
|
||||
type LegacyDisplayStore struct {
|
||||
store legacy.LegacyIdentityStore
|
||||
}
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*displayREST)(nil)
|
||||
_ rest.SingularNameProvider = (*displayREST)(nil)
|
||||
_ rest.Connecter = (*displayREST)(nil)
|
||||
_ rest.Scoper = (*displayREST)(nil)
|
||||
_ rest.StorageMetadata = (*displayREST)(nil)
|
||||
_ rest.Storage = (*LegacyDisplayStore)(nil)
|
||||
_ rest.SingularNameProvider = (*LegacyDisplayStore)(nil)
|
||||
_ rest.Connecter = (*LegacyDisplayStore)(nil)
|
||||
_ rest.Scoper = (*LegacyDisplayStore)(nil)
|
||||
_ rest.StorageMetadata = (*LegacyDisplayStore)(nil)
|
||||
)
|
||||
|
||||
func newDisplayREST(store legacy.LegacyIdentityStore) *displayREST {
|
||||
return &displayREST{store}
|
||||
func NewLegacyDisplayStore(store legacy.LegacyIdentityStore) *LegacyDisplayStore {
|
||||
return &LegacyDisplayStore{store}
|
||||
}
|
||||
|
||||
func (r *displayREST) New() runtime.Object {
|
||||
func (r *LegacyDisplayStore) New() runtime.Object {
|
||||
return &identity.IdentityDisplayResults{}
|
||||
}
|
||||
|
||||
func (r *displayREST) Destroy() {}
|
||||
func (r *LegacyDisplayStore) Destroy() {}
|
||||
|
||||
func (r *displayREST) NamespaceScoped() bool {
|
||||
func (r *LegacyDisplayStore) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *displayREST) GetSingularName() string {
|
||||
return "IdentityDisplay" // not actually used anywhere, but required by SingularNameProvider
|
||||
func (r *LegacyDisplayStore) GetSingularName() string {
|
||||
// not actually used anywhere, but required by SingularNameProvider
|
||||
return "IdentityDisplay"
|
||||
}
|
||||
|
||||
func (r *displayREST) ProducesMIMETypes(verb string) []string {
|
||||
func (r *LegacyDisplayStore) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"}
|
||||
}
|
||||
|
||||
func (r *displayREST) ProducesObject(verb string) any {
|
||||
func (r *LegacyDisplayStore) ProducesObject(verb string) any {
|
||||
return &identity.IdentityDisplayResults{}
|
||||
}
|
||||
|
||||
func (r *displayREST) ConnectMethods() []string {
|
||||
func (r *LegacyDisplayStore) ConnectMethods() []string {
|
||||
return []string{"GET"}
|
||||
}
|
||||
|
||||
func (r *displayREST) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
func (r *LegacyDisplayStore) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
return nil, false, "" // true means you can use the trailing path as a variable
|
||||
}
|
||||
|
||||
// This will always have an empty app url
|
||||
var fakeCfgForGravatar = &setting.Cfg{}
|
||||
|
||||
func (r *displayREST) Connect(ctx context.Context, name string, _ runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
func (r *LegacyDisplayStore) Connect(ctx context.Context, name string, _ runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
// See: /pkg/services/apiserver/builder/helper.go#L34
|
||||
// The name is set with a rewriter hack
|
||||
if name != "name" {
|
||||
+57
-53
@@ -1,59 +1,63 @@
|
||||
package identity
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
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/registry/apis/identity/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"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"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/identity/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/identity/legacy"
|
||||
"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)
|
||||
_ rest.Scoper = (*LegacyStore)(nil)
|
||||
_ rest.SingularNameProvider = (*LegacyStore)(nil)
|
||||
_ rest.Getter = (*LegacyStore)(nil)
|
||||
_ rest.Lister = (*LegacyStore)(nil)
|
||||
_ rest.Storage = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
type legacyUserStorage struct {
|
||||
service legacy.LegacyIdentityStore
|
||||
tableConverter rest.TableConvertor
|
||||
resourceInfo common.ResourceInfo
|
||||
var resource = identityv0.UserResourceInfo
|
||||
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore) *LegacyStore {
|
||||
return &LegacyStore{store}
|
||||
}
|
||||
|
||||
func (s *legacyUserStorage) New() runtime.Object {
|
||||
return s.resourceInfo.NewFunc()
|
||||
type LegacyStore struct {
|
||||
store legacy.LegacyIdentityStore
|
||||
}
|
||||
|
||||
func (s *legacyUserStorage) Destroy() {}
|
||||
func (s *LegacyStore) New() runtime.Object {
|
||||
return resource.NewFunc()
|
||||
}
|
||||
|
||||
func (s *legacyUserStorage) NamespaceScoped() bool {
|
||||
func (s *LegacyStore) Destroy() {}
|
||||
|
||||
func (s *LegacyStore) NamespaceScoped() bool {
|
||||
return true // namespace == org
|
||||
}
|
||||
|
||||
func (s *legacyUserStorage) GetSingularName() string {
|
||||
return s.resourceInfo.GetSingularName()
|
||||
func (s *LegacyStore) GetSingularName() string {
|
||||
return resource.GetSingularName()
|
||||
}
|
||||
|
||||
func (s *legacyUserStorage) NewList() runtime.Object {
|
||||
return s.resourceInfo.NewListFunc()
|
||||
func (s *LegacyStore) NewList() runtime.Object {
|
||||
return resource.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 *LegacyStore) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||
return resource.TableConverter().ConvertToTable(ctx, object, tableOptions)
|
||||
}
|
||||
|
||||
func (s *legacyUserStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -70,12 +74,12 @@ func (s *legacyUserStorage) List(ctx context.Context, options *internalversion.L
|
||||
}
|
||||
}
|
||||
|
||||
found, err := s.service.ListUsers(ctx, ns, query)
|
||||
found, err := s.store.ListUsers(ctx, ns, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := &identity.UserList{}
|
||||
list := &identityv0.UserList{}
|
||||
for _, item := range found.Users {
|
||||
list.Items = append(list.Items, *toUserItem(&item, ns.Value))
|
||||
}
|
||||
@@ -88,15 +92,36 @@ func (s *legacyUserStorage) List(ctx context.Context, options *internalversion.L
|
||||
return list, err
|
||||
}
|
||||
|
||||
func toUserItem(u *user.User, ns string) *identity.User {
|
||||
item := &identity.User{
|
||||
func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := legacy.ListUserQuery{
|
||||
OrgID: ns.OrgID,
|
||||
Limit: 1,
|
||||
IsServiceAccount: false,
|
||||
}
|
||||
|
||||
found, err := s.store.ListUsers(ctx, ns, query)
|
||||
if found == nil || err != nil {
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
if len(found.Users) < 1 {
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
return toUserItem(&found.Users[0], ns.Value), nil
|
||||
}
|
||||
|
||||
func toUserItem(u *user.User, ns string) *identityv0.User {
|
||||
item := &identityv0.User{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: u.UID,
|
||||
Namespace: ns,
|
||||
ResourceVersion: fmt.Sprintf("%d", u.Updated.UnixMilli()),
|
||||
CreationTimestamp: metav1.NewTime(u.Created),
|
||||
},
|
||||
Spec: identity.UserSpec{
|
||||
Spec: identityv0.UserSpec{
|
||||
Name: u.Name,
|
||||
Login: u.Login,
|
||||
Email: u.Email,
|
||||
@@ -112,24 +137,3 @@ func toUserItem(u *user.User, ns string) *identity.User {
|
||||
})
|
||||
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
|
||||
}
|
||||
query := legacy.ListUserQuery{
|
||||
OrgID: ns.OrgID,
|
||||
Limit: 1,
|
||||
IsServiceAccount: false,
|
||||
}
|
||||
|
||||
found, err := s.service.ListUsers(ctx, ns, query)
|
||||
if found == nil || err != nil {
|
||||
return nil, s.resourceInfo.NewNotFound(name)
|
||||
}
|
||||
if len(found.Users) < 1 {
|
||||
return nil, s.resourceInfo.NewNotFound(name)
|
||||
}
|
||||
return toUserItem(&found.Users[0], ns.Value), nil
|
||||
}
|
||||
@@ -39,4 +39,5 @@ var WireSet = wire.NewSet(
|
||||
query.RegisterAPIService,
|
||||
scope.RegisterAPIService,
|
||||
notifications.RegisterAPIService,
|
||||
//sso.RegisterAPIService,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user