diff --git a/docs/sources/administration/roles-and-permissions/_index.md b/docs/sources/administration/roles-and-permissions/_index.md
index 134482723b4..87457d1d0fa 100644
--- a/docs/sources/administration/roles-and-permissions/_index.md
+++ b/docs/sources/administration/roles-and-permissions/_index.md
@@ -121,29 +121,6 @@ For more information about assigning dashboard folder permissions, refer to [Gra
For more information about assigning dashboard permissions, refer to [Grant dashboard permissions]({{< relref "../user-management/manage-dashboard-permissions/#grant-dashboard-permissions" >}}).
-## Editors with administrator permissions
-
-If you have access to the Grafana server, you can modify the default editor role so that editors can use administrator permissions to manage dashboard folders, dashboards, and teams that they create.
-
-{{% admonition type="note" %}}
-This permission does not allow editors to manage folders, dashboards, and teams that they do not create.
-{{% /admonition %}}
-
-This setting can be used to enable self-organizing teams to administer their own dashboards.
-
-For more information about assigning administrator permissions to editors, refer to [Grant editors administrator permissions]({{< relref "../user-management/server-user-management/grant-editor-admin-permissions/" >}}).
-
-## Viewers with dashboard preview and Explore permissions
-
-If you have access to the Grafana server, you can modify the default viewer role so that viewers can:
-
-- Edit and preview dashboards, but cannot save their changes or create new dashboards.
-- Access and use [Explore]({{< relref "../../explore" >}}).
-
-Extending the viewer role is useful for public Grafana installations where you want anonymous users to be able to edit panels and queries, but not be able to save or create new dashboards.
-
-For more information about assigning dashboard preview permissions to viewers, refer to [Enable viewers to preview dashboards and use Explore]({{< relref "../user-management/manage-dashboard-permissions/#enable-viewers-to-edit-but-not-save-dashboards-and-use-explore" >}}).
-
## Teams and permissions
A team is a group of users within an organization that have common dashboard and data source permission needs. For example, instead of assigning five users access to the same dashboard, you can create a team that consists of those users and assign dashboard permissions to the team. A user can belong to multiple teams.
@@ -153,7 +130,7 @@ You can assign a team member one of the following permissions:
- **Member**: Includes the user as a member of the team. Members do not have team administrator privileges.
- **Admin**: Administrators have permission to manage various aspects of the team, including team membership, permissions, and settings.
-Because teams exist inside an organization, the organization administrator can manage all teams. When the `editors_can_admin` setting is enabled, editors can create teams and manage teams that they create. For more information about the `editors_can_admin` setting, refer to [Grant editors administrator permissions]({{< relref "../user-management/server-user-management/grant-editor-admin-permissions/" >}}).
+Because teams exist inside an organization, the organization administrator can manage all teams.
For details on managing teams, see [Team management]({{< relref "../team-management/" >}}).
diff --git a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md
index f651becaa4e..2c328c749b8 100644
--- a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md
+++ b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md
@@ -58,8 +58,8 @@ The following tables list permissions associated with basic and fixed roles.
| ------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Grafana Admin | `basic_grafana_admin` | `fixed:roles:reader`
`fixed:roles:writer`
`fixed:users:reader`
`fixed:users:writer`
`fixed:org.users:reader`
`fixed:org.users:writer`
`fixed:ldap:reader`
`fixed:ldap:writer`
`fixed:stats:reader`
`fixed:settings:reader`
`fixed:settings:writer`
`fixed:provisioning:writer`
`fixed:organization:reader`
`fixed:organization:maintainer`
`fixed:licensing:reader`
`fixed:licensing:writer`
`fixed:datasources.caching:reader`
`fixed:datasources.caching:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:plugins:maintainer`
`fixed:authentication.config:writer`
`fixed:library.panels:creator`
`fixed:library.panels:reader`
`fixed:library.panels:general.reader`
`fixed:library.panels:writer`
`fixed:library.panels:general.writer`
`fixed:groupsync:writer`
`fixed:migrationassistant:migrator` | Default [Grafana server administrator](/docs/grafana//administration/roles-and-permissions/#grafana-server-administrators) assignments. |
| Admin | `basic_admin` | `fixed:reports:reader`
`fixed:reports:writer`
`fixed:datasources:reader`
`fixed:datasources:writer`
`fixed:organization:writer`
`fixed:datasources.permissions:reader`
`fixed:datasources.permissions:writer`
`fixed:teams:writer`
`fixed:dashboards:reader`
`fixed:dashboards:writer`
`fixed:dashboards.permissions:reader`
`fixed:dashboards.permissions:writer`
`fixed:dashboards.public:writer`
`fixed:folders:reader`
`fixed:folders:writer`
`fixed:folders.permissions:reader`
`fixed:folders.permissions:writer`
`fixed:alerting:writer`
`fixed:apikeys:reader`
`fixed:apikeys:writer`
`fixed:alerting.provisioning.secrets:reader`
`fixed:alerting.provisioning:writer`
`fixed:datasources.caching:reader`
`fixed:datasources.caching:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:plugins:writer`
`fixed:library.panels:creator`
`fixed:library.panels:reader`
`fixed:library.panels:general.reader`
`fixed:library.panels:writer`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer`
`fixed:groupsync:writer` | Default [Grafana organization administrator](ref:rbac-basic-roles) assignments. |
-| Editor | `basic_editor` | `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:teams:creator` if the `editors_can_admin` configuration flag is enabled
`fixed:alerting:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:creator`
`fixed:library.panels:general.reader`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer` | Default [Editor](ref:rbac-basic-roles) assignments. |
-| Viewer | `basic_viewer` | `fixed:datasources.id:reader`
`fixed:organization:reader`
`fixed:annotations:reader`
`fixed:annotations.dashboard:writer`
`fixed:alerting:reader`
`fixed:plugins.app:reader`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:general.reader`
`fixed:datasources:explorer` if the `viewers_can_edit` configuration flag is enabled | Default [Viewer](ref:rbac-basic-roles) assignments. |
+| Editor | `basic_editor` | `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:alerting:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:creator`
`fixed:library.panels:general.reader`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer` | Default [Editor](ref:rbac-basic-roles) assignments. |
+| Viewer | `basic_viewer` | `fixed:datasources.id:reader`
`fixed:organization:reader`
`fixed:annotations:reader`
`fixed:annotations.dashboard:writer`
`fixed:alerting:reader`
`fixed:plugins.app:reader`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:general.reader` | Default [Viewer](ref:rbac-basic-roles) assignments. |
| No Basic Role | n/a | | Default [No Basic Role](ref:rbac-basic-roles) |
## Fixed role definitions
diff --git a/docs/sources/administration/user-management/manage-dashboard-permissions/index.md b/docs/sources/administration/user-management/manage-dashboard-permissions/index.md
index e87d0193fcc..b75f675cc5e 100644
--- a/docs/sources/administration/user-management/manage-dashboard-permissions/index.md
+++ b/docs/sources/administration/user-management/manage-dashboard-permissions/index.md
@@ -63,27 +63,7 @@ Grant dashboard permissions when you want to restrict or enhance dashboard acces
1. Select the user, service account, team, or role.
1. Select the permission and click **Save**.
-## Enable viewers to edit (but not save) dashboards and use Explore
-
-By default, the viewer organization role does not allow viewers to create dashboards or use the Explore feature. However, by modifying a configuration setting, you can allow viewers to edit a panel and make changes to a dashboard but not save those changes. This setting also enables viewers to use the Explore feature.
-
-This modification is useful for public Grafana installations where you want anonymous users to be able to edit panels and queries but not save or create new dashboards.
-
-### Before you begin
-
-- Ensure that you have access to the Grafana server
-
-**To enable viewers to preview dashboards and use Explore**:
-
-1. Open the Grafana configuration file.
-
- For more information about the Grafana configuration file and its location, refer to [Configuration]({{< relref "../../../setup-grafana/configure-grafana/" >}}).
-
-1. Locate the `viewers_can_edit` parameter.
-1. Set the `viewers_can_edit` value to `true`.
-1. Save your changes and restart Grafana.
-
-## Edit dashboard permissions
+# Edit dashboard permissions
Edit dashboard permissions when you are want to enhance or restrict a user's access to a dashboard. For more information about dashboard permissions, refer to [Dashboard permissions]({{< relref "../../roles-and-permissions/#dashboard-permissions" >}}).
diff --git a/docs/sources/administration/user-management/server-user-management/grant-editor-admin-permissions/index.md b/docs/sources/administration/user-management/server-user-management/grant-editor-admin-permissions/index.md
deleted file mode 100644
index cfefd775975..00000000000
--- a/docs/sources/administration/user-management/server-user-management/grant-editor-admin-permissions/index.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-aliases:
- - ../../manage-users-and-permissions/manage-server-users/grant-editor-admin-permissions/
-labels:
- products:
- - enterprise
- - oss
-title: Grant editors team creator permissions
-weight: 60
----
-
-# Grant editors team creator permissions
-
-By default, the editor organization role does not allow editors to creator and manage teams. You can allow them to do so using the `editors_can_admin` configuration option.
-
-When `editors_can_admin` is enabled, users with the Editor role in an organization can create teams, and they are Administrators of the teams they create. To learn more about team permissions, refer to [Team management]({{< relref "../../../team-management/" >}}).
-
-## Before you begin
-
-- Ensure that you have access to the Grafana server
-
-**To enable editors with team creator permissions**:
-
-1. Log in to the Grafana server and open the Grafana configuration file.
-
- For more information about the Grafana configuration file and its location, refer to [Configuration]({{< relref "../../../../setup-grafana/configure-grafana/" >}}).
-
-1. Locate the `editors_can_admin` parameter.
-1. Set the `editors_can_admin` value to `true`.
-1. Save your changes and restart the Grafana server.
diff --git a/docs/sources/developers/http_api/team.md b/docs/sources/developers/http_api/team.md
index e2c4cc654b4..e94d80be650 100644
--- a/docs/sources/developers/http_api/team.md
+++ b/docs/sources/developers/http_api/team.md
@@ -26,8 +26,6 @@ Access to these API endpoints is restricted as follows:
- All authenticated users are able to view details of teams they are a member of.
- Organization Admins are able to manage all teams and team members.
-- If you enable `editors_can_admin` configuration flag, then Organization Editors can create teams and manage teams where they are Admin.
- - If you enable `editors_can_admin` configuration flag, Editors can find out whether a team that they are not members of exists by trying to create a team with the same name.
> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information.
diff --git a/docs/sources/explore/get-started-with-explore.md b/docs/sources/explore/get-started-with-explore.md
index 7e78e4e80c3..b25f855bac9 100644
--- a/docs/sources/explore/get-started-with-explore.md
+++ b/docs/sources/explore/get-started-with-explore.md
@@ -38,14 +38,10 @@ Watch the following video to get started using Explore:
## Before you begin
-In order to access Explore, you must have either the `editor` or `administrator` role, unless the [`viewers_can_edit` option](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/#viewers_can_edit) is enabled. Refer to [Role and permissions](https://grafana.com/docs/grafana//administration/roles-and-permissions/) for more information on what each role can access.
+In order to access Explore, you must have either the `editor` or `administrator` basic role or the `data sources explore` role. Refer to [Role and permissions](https://grafana.com/docs/grafana//administration/roles-and-permissions/) for more information on what each role can access.
Refer to [Role-based access control (RBAC)](https://grafana.com/docs/grafana//administration/roles-and-permissions/access-control/) in Grafana Enterprise to understand how you can manage Explore with role-based permissions.
-{{< admonition type="note" >}}
-If you are using Grafana Cloud, open a [support ticket in the Cloud Portal](https://grafana.com/auth/sign-in) to enable the `viewers_can_edit` option.
-{{< /admonition >}}
-
## Explore elements
Explore consists of a toolbar, outline, query editor, the ability to add multiple queries, a query history and a query inspector.
diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md
index 527fc60d7a5..babe3619b35 100644
--- a/docs/sources/setup-grafana/configure-grafana/_index.md
+++ b/docs/sources/setup-grafana/configure-grafana/_index.md
@@ -950,10 +950,18 @@ If you manage users externally you can replace the user invite button for organi
#### `viewers_can_edit`
+{{< admonition type="note" >}}
+This option is deprecated - assign your viewers as editors, if you are using RBAC assign the data sources explorer role to your users.
+{{< /admonition >}}
+
Viewers can access and use [Explore]({{< relref "../../explore" >}}) and perform temporary edits on panels in dashboards they have access to. They cannot save their changes. Default is `false`.
#### `editors_can_admin`
+{{< admonition type="note" >}}
+This option is deprecated - assign your editors as admins, if you are using RBAC assign the team creator role to your users.
+{{< /admonition >}}
+
Editors can administrate dashboards, folders and teams they create.
Default is `false`.
diff --git a/go.work.sum b/go.work.sum
index e92bae1a534..794c308c58f 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -618,6 +618,11 @@ github.com/grafana/cog v0.0.23/go.mod h1:jrS9indvWuDs60RHEZpLaAkmZdgyoLKMOEUT0ji
github.com/grafana/go-gelf/v2 v2.0.1 h1:BOChP0h/jLeD+7F9mL7tq10xVkDG15he3T1zHuQaWak=
github.com/grafana/go-gelf/v2 v2.0.1/go.mod h1:lexHie0xzYGwCgiRGcvZ723bSNyNI8ZRD4s0CLobh90=
github.com/grafana/grafana/apps/advisor v0.0.0-20250220154326-6e5de80ef295/go.mod h1:9I1dKV3Dqr0NPR9Af0WJGxOytp5/6W3JLiNChOz8r+c=
+github.com/grafana/grafana/apps/advisor v0.0.0-20250220163425-b4c4b9abbdc8/go.mod h1:9I1dKV3Dqr0NPR9Af0WJGxOytp5/6W3JLiNChOz8r+c=
+github.com/grafana/grafana/apps/alerting/notifications v0.0.0-20250220163425-b4c4b9abbdc8/go.mod h1:dHhFF484qs1cmdIShKCB3kl+tMJyc4yuwgTQ3Afz37o=
+github.com/grafana/grafana/apps/investigations v0.0.0-20250220163425-b4c4b9abbdc8/go.mod h1:ygFcJP2McdSeMJVj/3YrKafZMc/lZBsp54HO51MtJYw=
+github.com/grafana/grafana/apps/playlist v0.0.0-20250220164708-c8d4ff28a450/go.mod h1:KKIsWpbv88Lwwcvdjon73zFL7vNJvuXLtsSoUjJErTw=
+github.com/grafana/grafana/pkg/build v0.0.0-20250220114259-be81314e2118/go.mod h1:STVpVboMYeBAfyn6Zw6XHhTHqUxzMy7pzRiVgk1l0W0=
github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0 h1:bjh0PVYSVVFxzINqPFYJmAmJNrWPgnVjuSdYJGHmtFU=
github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0/go.mod h1:7t5XR+2IA8P2qggOAHTj/GCZfoLBle3OvNSYh1VkRBU=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
diff --git a/packages/grafana-ui/src/components/Select/SelectBase.tsx b/packages/grafana-ui/src/components/Select/SelectBase.tsx
index 6a173554360..75c2b10681a 100644
--- a/packages/grafana-ui/src/components/Select/SelectBase.tsx
+++ b/packages/grafana-ui/src/components/Select/SelectBase.tsx
@@ -255,7 +255,6 @@ export function SelectBase({
menuIsOpen: isOpen,
menuPlacement: menuPlacement === 'auto' && closeToBottom ? 'top' : menuPlacement,
menuPosition,
- menuShouldBlockScroll: true,
menuPortalTarget: menuShouldPortal && typeof document !== 'undefined' ? document.body : undefined,
menuShouldScrollIntoView: false,
onBlur,
diff --git a/pkg/apimachinery/apis/common/v0alpha1/doc.go b/pkg/apimachinery/apis/common/v0alpha1/doc.go
index 8dbffd26f90..695a6afa690 100644
--- a/pkg/apimachinery/apis/common/v0alpha1/doc.go
+++ b/pkg/apimachinery/apis/common/v0alpha1/doc.go
@@ -1,3 +1,4 @@
+// +k8s:deepcopy-gen=package
// +k8s:openapi-gen=true
// +k8s:defaulter-gen=TypeMeta
// +groupName=common.grafana.app
diff --git a/pkg/apimachinery/apis/common/v0alpha1/types.go b/pkg/apimachinery/apis/common/v0alpha1/types.go
index 63ea94a8a96..8ccc08c62a0 100644
--- a/pkg/apimachinery/apis/common/v0alpha1/types.go
+++ b/pkg/apimachinery/apis/common/v0alpha1/types.go
@@ -1,5 +1,9 @@
package v0alpha1
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
// Similar to
// https://dev-k8sref-io.web.app/docs/common-definitions/objectreference-/
// ObjectReference contains enough information to let you inspect or modify the referred object.
@@ -15,3 +19,41 @@ type ObjectReference struct {
// APIVersion is the version of the API group that contains the referred object.
APIVersion string `json:"apiVersion,omitempty"`
}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+type Scope struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec ScopeSpec `json:"spec,omitempty"`
+}
+
+type ScopeSpec struct {
+ Title string `json:"title"`
+ Description string `json:"description"`
+
+ // +listType=atomic
+ Filters []ScopeFilter `json:"filters"`
+}
+
+type ScopeFilter struct {
+ Key string `json:"key"`
+ Value string `json:"value"`
+ // Values is used for operators that require multiple values (e.g. one-of and not-one-of).
+ Values []string `json:"values,omitempty"`
+ Operator FilterOperator `json:"operator"`
+}
+
+// Type of the filter operator.
+// +enum
+type FilterOperator string
+
+// Defines values for FilterOperator.
+const (
+ FilterOperatorEquals FilterOperator = "equals"
+ FilterOperatorNotEquals FilterOperator = "not-equals"
+ FilterOperatorRegexMatch FilterOperator = "regex-match"
+ FilterOperatorRegexNotMatch FilterOperator = "regex-not-match"
+ FilterOperatorOneOf FilterOperator = "one-of"
+ FilterOperatorNotOneOf FilterOperator = "not-one-of"
+)
diff --git a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.deepcopy.go b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.deepcopy.go
new file mode 100644
index 00000000000..8a3334e3634
--- /dev/null
+++ b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.deepcopy.go
@@ -0,0 +1,99 @@
+//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 *ObjectReference) DeepCopyInto(out *ObjectReference) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectReference.
+func (in *ObjectReference) DeepCopy() *ObjectReference {
+ if in == nil {
+ return nil
+ }
+ out := new(ObjectReference)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Scope) DeepCopyInto(out *Scope) {
+ *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 Scope.
+func (in *Scope) DeepCopy() *Scope {
+ if in == nil {
+ return nil
+ }
+ out := new(Scope)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Scope) 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 *ScopeFilter) DeepCopyInto(out *ScopeFilter) {
+ *out = *in
+ if in.Values != nil {
+ in, out := &in.Values, &out.Values
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeFilter.
+func (in *ScopeFilter) DeepCopy() *ScopeFilter {
+ if in == nil {
+ return nil
+ }
+ out := new(ScopeFilter)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ScopeSpec) DeepCopyInto(out *ScopeSpec) {
+ *out = *in
+ if in.Filters != nil {
+ in, out := &in.Filters, &out.Filters
+ *out = make([]ScopeFilter, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeSpec.
+func (in *ScopeSpec) DeepCopy() *ScopeSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(ScopeSpec)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go
index 2c5933d1790..8ddb9f8aecf 100644
--- a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go
+++ b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go
@@ -16,6 +16,9 @@ import (
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ObjectReference": schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref),
+ "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Scope": schema_apimachinery_apis_common_v0alpha1_Scope(ref),
+ "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter": schema_apimachinery_apis_common_v0alpha1_ScopeFilter(ref),
+ "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec": schema_apimachinery_apis_common_v0alpha1_ScopeSpec(ref),
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured": Unstructured{}.OpenAPIDefinition(),
"k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref),
"k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref),
@@ -118,6 +121,144 @@ func schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref common.Referen
}
}
+func schema_apimachinery_apis_common_v0alpha1_Scope(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/common/v0alpha1.ScopeSpec"),
+ },
+ },
+ },
+ },
+ },
+ Dependencies: []string{
+ "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
+ }
+}
+
+func schema_apimachinery_apis_common_v0alpha1_ScopeFilter(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "key": {
+ SchemaProps: spec.SchemaProps{
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "value": {
+ SchemaProps: spec.SchemaProps{
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "values": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Values is used for operators that require multiple values (e.g. one-of and not-one-of).",
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ },
+ },
+ },
+ "operator": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Possible enum values:\n - `\"equals\"`\n - `\"not-equals\"`\n - `\"not-one-of\"`\n - `\"one-of\"`\n - `\"regex-match\"`\n - `\"regex-not-match\"`",
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ Enum: []interface{}{"equals", "not-equals", "not-one-of", "one-of", "regex-match", "regex-not-match"},
+ },
+ },
+ },
+ Required: []string{"key", "value", "operator"},
+ },
+ },
+ }
+}
+
+func schema_apimachinery_apis_common_v0alpha1_ScopeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "title": {
+ SchemaProps: spec.SchemaProps{
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "description": {
+ SchemaProps: spec.SchemaProps{
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "filters": {
+ VendorExtensible: spec.VendorExtensible{
+ Extensions: spec.Extensions{
+ "x-kubernetes-list-type": "atomic",
+ },
+ },
+ 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/common/v0alpha1.ScopeFilter"),
+ },
+ },
+ },
+ },
+ },
+ },
+ Required: []string{"title", "description", "filters"},
+ },
+ },
+ Dependencies: []string{
+ "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter"},
+ }
+}
+
func schema_pkg_apis_meta_v1_APIGroup(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
diff --git a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi_violation_exceptions.list
index caca0df1147..e4491e5ef86 100644
--- a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi_violation_exceptions.list
+++ b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi_violation_exceptions.list
@@ -1,3 +1,4 @@
+API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1,ScopeFilter,Values
API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1,Unstructured,Object
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,APIResourceList,APIResources
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Duration,Duration
diff --git a/pkg/apis/scope/v0alpha1/doc.go b/pkg/apis/scope/v0alpha1/doc.go
deleted file mode 100644
index f9f43a0ea38..00000000000
--- a/pkg/apis/scope/v0alpha1/doc.go
+++ /dev/null
@@ -1,6 +0,0 @@
-// +k8s:deepcopy-gen=package
-// +k8s:openapi-gen=true
-// +k8s:defaulter-gen=TypeMeta
-// +groupName=scope.grafana.app
-
-package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
diff --git a/pkg/apis/scope/v0alpha1/register.go b/pkg/apis/scope/v0alpha1/register.go
deleted file mode 100644
index e4c514c062d..00000000000
--- a/pkg/apis/scope/v0alpha1/register.go
+++ /dev/null
@@ -1,139 +0,0 @@
-package v0alpha1
-
-import (
- "fmt"
- "time"
-
- "github.com/grafana/grafana/pkg/apimachinery/utils"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
-)
-
-const (
- GROUP = "scope.grafana.app"
- VERSION = "v0alpha1"
- APIVERSION = GROUP + "/" + VERSION
-)
-
-var ScopeResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
- "scopes", "scope", "Scope",
- func() runtime.Object { return &Scope{} },
- func() runtime.Object { return &ScopeList{} },
- utils.TableColumns{
- Definition: []metav1.TableColumnDefinition{
- {Name: "Name", Type: "string", Format: "name"},
- {Name: "Created At", Type: "date"},
- {Name: "Title", Type: "string"},
- {Name: "Filters", Type: "array"},
- },
- Reader: func(obj any) ([]interface{}, error) {
- m, ok := obj.(*Scope)
- if !ok {
- return nil, fmt.Errorf("expected scope")
- }
- return []interface{}{
- m.Name,
- m.CreationTimestamp.UTC().Format(time.RFC3339),
- m.Spec.Title,
- m.Spec.Filters,
- }, nil
- },
- }, // default table converter
-)
-
-var ScopeDashboardBindingResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
- "scopedashboardbindings", "scopedashboardbinding", "ScopeDashboardBinding",
- func() runtime.Object { return &ScopeDashboardBinding{} },
- func() runtime.Object { return &ScopeDashboardBindingList{} },
- utils.TableColumns{
- Definition: []metav1.TableColumnDefinition{
- {Name: "Name", Type: "string", Format: "name"},
- {Name: "Created At", Type: "date"},
- {Name: "Dashboard", Type: "string"},
- {Name: "Scope", Type: "string"},
- },
- Reader: func(obj any) ([]interface{}, error) {
- m, ok := obj.(*ScopeDashboardBinding)
- if !ok {
- return nil, fmt.Errorf("expected scope dashboard binding")
- }
- return []interface{}{
- m.Name,
- m.CreationTimestamp.UTC().Format(time.RFC3339),
- m.Spec.Dashboard,
- m.Spec.Scope,
- }, nil
- },
- },
-)
-
-var ScopeNodeResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
- "scopenodes", "scopenode", "ScopeNode",
- func() runtime.Object { return &ScopeNode{} },
- func() runtime.Object { return &ScopeNodeList{} },
- utils.TableColumns{
- Definition: []metav1.TableColumnDefinition{
- {Name: "Name", Type: "string", Format: "name"},
- {Name: "Created At", Type: "date"},
- {Name: "Title", Type: "string"},
- {Name: "Parent Name", Type: "string"},
- {Name: "Node Type", Type: "string"},
- {Name: "Link Type", Type: "string"},
- {Name: "Link ID", Type: "string"},
- },
- Reader: func(obj any) ([]interface{}, error) {
- m, ok := obj.(*ScopeNode)
- if !ok {
- return nil, fmt.Errorf("expected scope node")
- }
- return []interface{}{
- m.Name,
- m.CreationTimestamp.UTC().Format(time.RFC3339),
- m.Spec.Title,
- m.Spec.ParentName,
- m.Spec.NodeType,
- m.Spec.LinkType,
- m.Spec.LinkID,
- }, nil
- },
- }, // default table converter
-)
-
-var (
- // SchemeGroupVersion is group version used to register these objects
- SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION}
- InternalGroupVersion = schema.GroupVersion{Group: GROUP, Version: runtime.APIVersionInternal}
-
- // 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(SchemeGroupVersion, s)
- })
-}
-
-// Adds the list of known types to the given scheme.
-func AddKnownTypes(gv schema.GroupVersion, scheme *runtime.Scheme) error {
- scheme.AddKnownTypes(gv,
- &Scope{},
- &ScopeList{},
- &ScopeDashboardBinding{},
- &ScopeDashboardBindingList{},
- &ScopeNode{},
- &ScopeNodeList{},
- &FindScopeNodeChildrenResults{},
- &FindScopeDashboardBindingsResults{},
- )
- //metav1.AddToGroupVersion(scheme, gv)
- return nil
-}
-
-// Resource takes an unqualified resource and returns a Group qualified GroupResource
-func Resource(resource string) schema.GroupResource {
- return SchemeGroupVersion.WithResource(resource).GroupResource()
-}
diff --git a/pkg/apis/scope/v0alpha1/types.go b/pkg/apis/scope/v0alpha1/types.go
deleted file mode 100644
index c7ed0657ab5..00000000000
--- a/pkg/apis/scope/v0alpha1/types.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package v0alpha1
-
-import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-/*
-Please keep pkg/promlib/models/query.go and pkg/promlib/models/scope.go in sync
-with this file until this package is out of the grafana/grafana module.
-*/
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type Scope struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ObjectMeta `json:"metadata,omitempty"`
-
- Spec ScopeSpec `json:"spec,omitempty"`
-}
-
-type ScopeSpec struct {
- Title string `json:"title"`
- Description string `json:"description"`
-
- // +listType=atomic
- Filters []ScopeFilter `json:"filters"`
-}
-
-type ScopeFilter struct {
- Key string `json:"key"`
- Value string `json:"value"`
- // Values is used for operators that require multiple values (e.g. one-of and not-one-of).
- Values []string `json:"values,omitempty"`
- Operator FilterOperator `json:"operator"`
-}
-
-// Type of the filter operator.
-// +enum
-type FilterOperator string
-
-// Defines values for FilterOperator.
-const (
- FilterOperatorEquals FilterOperator = "equals"
- FilterOperatorNotEquals FilterOperator = "not-equals"
- FilterOperatorRegexMatch FilterOperator = "regex-match"
- FilterOperatorRegexNotMatch FilterOperator = "regex-not-match"
- FilterOperatorOneOf FilterOperator = "one-of"
- FilterOperatorNotOneOf FilterOperator = "not-one-of"
-)
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type ScopeList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
-
- Items []Scope `json:"items,omitempty"`
-}
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type ScopeDashboardBinding struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ObjectMeta `json:"metadata,omitempty"`
-
- Spec ScopeDashboardBindingSpec `json:"spec,omitempty"`
- Status ScopeDashboardBindingStatus `json:"status,omitempty"`
-}
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type ScopeDashboardBindingList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
-
- Items []ScopeDashboardBinding `json:"items,omitempty"`
-}
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type FindScopeDashboardBindingsResults struct {
- metav1.TypeMeta `json:",inline"`
-
- Items []ScopeDashboardBinding `json:"items,omitempty"`
- Message string `json:"message,omitempty"`
-}
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type ScopeNode struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ObjectMeta `json:"metadata,omitempty"`
-
- Spec ScopeNodeSpec `json:"spec,omitempty"`
-}
-
-type ScopeDashboardBindingSpec struct {
- Dashboard string `json:"dashboard"`
- Scope string `json:"scope"`
-}
-
-// Type of the item.
-// +enum
-// ScopeDashboardBindingStatus contains derived information about a ScopeDashboardBinding.
-type ScopeDashboardBindingStatus struct {
- // DashboardTitle should be populated and update from the dashboard
- DashboardTitle string `json:"dashboardTitle"`
-
- // Groups is used for the grouping of dashboards that are suggested based
- // on a scope. The source of truth for this information has not been
- // determined yet.
- Groups []string `json:"groups,omitempty"`
-
- // DashboardTitleConditions is a list of conditions that are used to determine if the dashboard title is valid.
- // +optional
- // +listType=map
- // +listMapKey=type
- DashboardTitleConditions []metav1.Condition `json:"dashboardTitleConditions,omitempty"`
-
- // DashboardTitleConditions is a list of conditions that are used to determine if the list of groups is valid.
- // +optional
- // +listType=map
- // +listMapKey=type
- GroupsConditions []metav1.Condition `json:"groupsConditions,omitempty"`
-}
-
-type NodeType string
-
-// Defines values for ItemType.
-const (
- NodeTypeContainer NodeType = "container"
- NodeTypeLeaf NodeType = "leaf"
-)
-
-// Type of the item.
-// +enum
-type LinkType string
-
-// Defines values for ItemType.
-const (
- LinkTypeScope LinkType = "scope"
-)
-
-type ScopeNodeSpec struct {
- //+optional
- ParentName string `json:"parentName,omitempty"`
-
- NodeType NodeType `json:"nodeType"` // container | leaf
-
- Title string `json:"title"`
- Description string `json:"description,omitempty"`
- DisableMultiSelect bool `json:"disableMultiSelect"`
-
- LinkType LinkType `json:"linkType,omitempty"` // scope (later more things)
- LinkID string `json:"linkId,omitempty"` // the k8s name
- // ?? should this be a slice of links
-}
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type ScopeNodeList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
-
- Items []ScopeNode `json:"items,omitempty"`
-}
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type FindScopeNodeChildrenResults struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
-
- Items []ScopeNode `json:"items,omitempty"`
-}
diff --git a/pkg/apis/scope/v0alpha1/zz_generated.deepcopy.go b/pkg/apis/scope/v0alpha1/zz_generated.deepcopy.go
deleted file mode 100644
index 73a9723640e..00000000000
--- a/pkg/apis/scope/v0alpha1/zz_generated.deepcopy.go
+++ /dev/null
@@ -1,370 +0,0 @@
-//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 (
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- 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 *FindScopeDashboardBindingsResults) DeepCopyInto(out *FindScopeDashboardBindingsResults) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]ScopeDashboardBinding, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FindScopeDashboardBindingsResults.
-func (in *FindScopeDashboardBindingsResults) DeepCopy() *FindScopeDashboardBindingsResults {
- if in == nil {
- return nil
- }
- out := new(FindScopeDashboardBindingsResults)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *FindScopeDashboardBindingsResults) 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 *FindScopeNodeChildrenResults) DeepCopyInto(out *FindScopeNodeChildrenResults) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ListMeta.DeepCopyInto(&out.ListMeta)
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]ScopeNode, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FindScopeNodeChildrenResults.
-func (in *FindScopeNodeChildrenResults) DeepCopy() *FindScopeNodeChildrenResults {
- if in == nil {
- return nil
- }
- out := new(FindScopeNodeChildrenResults)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *FindScopeNodeChildrenResults) 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 *Scope) DeepCopyInto(out *Scope) {
- *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 Scope.
-func (in *Scope) DeepCopy() *Scope {
- if in == nil {
- return nil
- }
- out := new(Scope)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *Scope) 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 *ScopeDashboardBinding) DeepCopyInto(out *ScopeDashboardBinding) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
- in.Status.DeepCopyInto(&out.Status)
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBinding.
-func (in *ScopeDashboardBinding) DeepCopy() *ScopeDashboardBinding {
- if in == nil {
- return nil
- }
- out := new(ScopeDashboardBinding)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ScopeDashboardBinding) 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 *ScopeDashboardBindingList) DeepCopyInto(out *ScopeDashboardBindingList) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ListMeta.DeepCopyInto(&out.ListMeta)
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]ScopeDashboardBinding, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingList.
-func (in *ScopeDashboardBindingList) DeepCopy() *ScopeDashboardBindingList {
- if in == nil {
- return nil
- }
- out := new(ScopeDashboardBindingList)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ScopeDashboardBindingList) 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 *ScopeDashboardBindingSpec) DeepCopyInto(out *ScopeDashboardBindingSpec) {
- *out = *in
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingSpec.
-func (in *ScopeDashboardBindingSpec) DeepCopy() *ScopeDashboardBindingSpec {
- if in == nil {
- return nil
- }
- out := new(ScopeDashboardBindingSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ScopeDashboardBindingStatus) DeepCopyInto(out *ScopeDashboardBindingStatus) {
- *out = *in
- if in.Groups != nil {
- in, out := &in.Groups, &out.Groups
- *out = make([]string, len(*in))
- copy(*out, *in)
- }
- if in.DashboardTitleConditions != nil {
- in, out := &in.DashboardTitleConditions, &out.DashboardTitleConditions
- *out = make([]v1.Condition, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- if in.GroupsConditions != nil {
- in, out := &in.GroupsConditions, &out.GroupsConditions
- *out = make([]v1.Condition, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingStatus.
-func (in *ScopeDashboardBindingStatus) DeepCopy() *ScopeDashboardBindingStatus {
- if in == nil {
- return nil
- }
- out := new(ScopeDashboardBindingStatus)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ScopeFilter) DeepCopyInto(out *ScopeFilter) {
- *out = *in
- if in.Values != nil {
- in, out := &in.Values, &out.Values
- *out = make([]string, len(*in))
- copy(*out, *in)
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeFilter.
-func (in *ScopeFilter) DeepCopy() *ScopeFilter {
- if in == nil {
- return nil
- }
- out := new(ScopeFilter)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ScopeList) DeepCopyInto(out *ScopeList) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ListMeta.DeepCopyInto(&out.ListMeta)
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]Scope, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeList.
-func (in *ScopeList) DeepCopy() *ScopeList {
- if in == nil {
- return nil
- }
- out := new(ScopeList)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ScopeList) 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 *ScopeNode) DeepCopyInto(out *ScopeNode) {
- *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 ScopeNode.
-func (in *ScopeNode) DeepCopy() *ScopeNode {
- if in == nil {
- return nil
- }
- out := new(ScopeNode)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ScopeNode) 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 *ScopeNodeList) DeepCopyInto(out *ScopeNodeList) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ListMeta.DeepCopyInto(&out.ListMeta)
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]ScopeNode, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeNodeList.
-func (in *ScopeNodeList) DeepCopy() *ScopeNodeList {
- if in == nil {
- return nil
- }
- out := new(ScopeNodeList)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ScopeNodeList) 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 *ScopeNodeSpec) DeepCopyInto(out *ScopeNodeSpec) {
- *out = *in
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeNodeSpec.
-func (in *ScopeNodeSpec) DeepCopy() *ScopeNodeSpec {
- if in == nil {
- return nil
- }
- out := new(ScopeNodeSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ScopeSpec) DeepCopyInto(out *ScopeSpec) {
- *out = *in
- if in.Filters != nil {
- in, out := &in.Filters, &out.Filters
- *out = make([]ScopeFilter, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
- return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeSpec.
-func (in *ScopeSpec) DeepCopy() *ScopeSpec {
- if in == nil {
- return nil
- }
- out := new(ScopeSpec)
- in.DeepCopyInto(out)
- return out
-}
diff --git a/pkg/apis/scope/v0alpha1/zz_generated.defaults.go b/pkg/apis/scope/v0alpha1/zz_generated.defaults.go
deleted file mode 100644
index 238fc2f4edc..00000000000
--- a/pkg/apis/scope/v0alpha1/zz_generated.defaults.go
+++ /dev/null
@@ -1,19 +0,0 @@
-//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
-}
diff --git a/pkg/apis/scope/v0alpha1/zz_generated.openapi.go b/pkg/apis/scope/v0alpha1/zz_generated.openapi.go
deleted file mode 100644
index 4018d2cf024..00000000000
--- a/pkg/apis/scope/v0alpha1/zz_generated.openapi.go
+++ /dev/null
@@ -1,661 +0,0 @@
-//go:build !ignore_autogenerated
-// +build !ignore_autogenerated
-
-// SPDX-License-Identifier: AGPL-3.0-only
-
-// Code generated by openapi-gen. DO NOT EDIT.
-
-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/apis/scope/v0alpha1.FindScopeDashboardBindingsResults": schema_pkg_apis_scope_v0alpha1_FindScopeDashboardBindingsResults(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.FindScopeNodeChildrenResults": schema_pkg_apis_scope_v0alpha1_FindScopeNodeChildrenResults(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.Scope": schema_pkg_apis_scope_v0alpha1_Scope(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBinding(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingList": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingList(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingSpec": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingSpec(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingStatus": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingStatus(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeFilter": schema_pkg_apis_scope_v0alpha1_ScopeFilter(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeList": schema_pkg_apis_scope_v0alpha1_ScopeList(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode": schema_pkg_apis_scope_v0alpha1_ScopeNode(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNodeList": schema_pkg_apis_scope_v0alpha1_ScopeNodeList(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNodeSpec": schema_pkg_apis_scope_v0alpha1_ScopeNodeSpec(ref),
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeSpec": schema_pkg_apis_scope_v0alpha1_ScopeSpec(ref),
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_FindScopeDashboardBindingsResults(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: "",
- },
- },
- "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/scope/v0alpha1.ScopeDashboardBinding"),
- },
- },
- },
- },
- },
- "message": {
- SchemaProps: spec.SchemaProps{
- Type: []string{"string"},
- Format: "",
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_FindScopeNodeChildrenResults(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/scope/v0alpha1.ScopeNode"),
- },
- },
- },
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_Scope(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/scope/v0alpha1.ScopeSpec"),
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBinding(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/scope/v0alpha1.ScopeDashboardBindingSpec"),
- },
- },
- "status": {
- SchemaProps: spec.SchemaProps{
- Default: map[string]interface{}{},
- Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingStatus"),
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingSpec", "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingList(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/scope/v0alpha1.ScopeDashboardBinding"),
- },
- },
- },
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
- return common.OpenAPIDefinition{
- Schema: spec.Schema{
- SchemaProps: spec.SchemaProps{
- Type: []string{"object"},
- Properties: map[string]spec.Schema{
- "dashboard": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "scope": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- },
- Required: []string{"dashboard", "scope"},
- },
- },
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
- return common.OpenAPIDefinition{
- Schema: spec.Schema{
- SchemaProps: spec.SchemaProps{
- Description: "Type of the item. ScopeDashboardBindingStatus contains derived information about a ScopeDashboardBinding.",
- Type: []string{"object"},
- Properties: map[string]spec.Schema{
- "dashboardTitle": {
- SchemaProps: spec.SchemaProps{
- Description: "DashboardTitle should be populated and update from the dashboard",
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "groups": {
- SchemaProps: spec.SchemaProps{
- Description: "Groups is used for the grouping of dashboards that are suggested based on a scope. The source of truth for this information has not been determined yet.",
- Type: []string{"array"},
- Items: &spec.SchemaOrArray{
- Schema: &spec.Schema{
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- },
- },
- },
- "dashboardTitleConditions": {
- VendorExtensible: spec.VendorExtensible{
- Extensions: spec.Extensions{
- "x-kubernetes-list-map-keys": []interface{}{
- "type",
- },
- "x-kubernetes-list-type": "map",
- },
- },
- SchemaProps: spec.SchemaProps{
- Description: "DashboardTitleConditions is a list of conditions that are used to determine if the dashboard title is valid.",
- Type: []string{"array"},
- Items: &spec.SchemaOrArray{
- Schema: &spec.Schema{
- SchemaProps: spec.SchemaProps{
- Default: map[string]interface{}{},
- Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"),
- },
- },
- },
- },
- },
- "groupsConditions": {
- VendorExtensible: spec.VendorExtensible{
- Extensions: spec.Extensions{
- "x-kubernetes-list-map-keys": []interface{}{
- "type",
- },
- "x-kubernetes-list-type": "map",
- },
- },
- SchemaProps: spec.SchemaProps{
- Description: "DashboardTitleConditions is a list of conditions that are used to determine if the list of groups is valid.",
- Type: []string{"array"},
- Items: &spec.SchemaOrArray{
- Schema: &spec.Schema{
- SchemaProps: spec.SchemaProps{
- Default: map[string]interface{}{},
- Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"),
- },
- },
- },
- },
- },
- },
- Required: []string{"dashboardTitle"},
- },
- },
- Dependencies: []string{
- "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeFilter(ref common.ReferenceCallback) common.OpenAPIDefinition {
- return common.OpenAPIDefinition{
- Schema: spec.Schema{
- SchemaProps: spec.SchemaProps{
- Type: []string{"object"},
- Properties: map[string]spec.Schema{
- "key": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "value": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "values": {
- SchemaProps: spec.SchemaProps{
- Description: "Values is used for operators that require multiple values (e.g. one-of and not-one-of).",
- Type: []string{"array"},
- Items: &spec.SchemaOrArray{
- Schema: &spec.Schema{
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- },
- },
- },
- "operator": {
- SchemaProps: spec.SchemaProps{
- Description: "Possible enum values:\n - `\"equals\"`\n - `\"not-equals\"`\n - `\"not-one-of\"`\n - `\"one-of\"`\n - `\"regex-match\"`\n - `\"regex-not-match\"`",
- Default: "",
- Type: []string{"string"},
- Format: "",
- Enum: []interface{}{"equals", "not-equals", "not-one-of", "one-of", "regex-match", "regex-not-match"},
- },
- },
- },
- Required: []string{"key", "value", "operator"},
- },
- },
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeList(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/scope/v0alpha1.Scope"),
- },
- },
- },
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.Scope", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeNode(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/scope/v0alpha1.ScopeNodeSpec"),
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNodeSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeNodeList(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/scope/v0alpha1.ScopeNode"),
- },
- },
- },
- },
- },
- },
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeNodeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
- return common.OpenAPIDefinition{
- Schema: spec.Schema{
- SchemaProps: spec.SchemaProps{
- Type: []string{"object"},
- Properties: map[string]spec.Schema{
- "parentName": {
- SchemaProps: spec.SchemaProps{
- Type: []string{"string"},
- Format: "",
- },
- },
- "nodeType": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "title": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "description": {
- SchemaProps: spec.SchemaProps{
- Type: []string{"string"},
- Format: "",
- },
- },
- "disableMultiSelect": {
- SchemaProps: spec.SchemaProps{
- Default: false,
- Type: []string{"boolean"},
- Format: "",
- },
- },
- "linkType": {
- SchemaProps: spec.SchemaProps{
- Description: "Possible enum values:\n - `\"scope\"`",
- Type: []string{"string"},
- Format: "",
- Enum: []interface{}{"scope"},
- },
- },
- "linkId": {
- SchemaProps: spec.SchemaProps{
- Description: "scope (later more things)",
- Type: []string{"string"},
- Format: "",
- },
- },
- },
- Required: []string{"nodeType", "title", "disableMultiSelect"},
- },
- },
- }
-}
-
-func schema_pkg_apis_scope_v0alpha1_ScopeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
- return common.OpenAPIDefinition{
- Schema: spec.Schema{
- SchemaProps: spec.SchemaProps{
- Type: []string{"object"},
- Properties: map[string]spec.Schema{
- "title": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "description": {
- SchemaProps: spec.SchemaProps{
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "filters": {
- VendorExtensible: spec.VendorExtensible{
- Extensions: spec.Extensions{
- "x-kubernetes-list-type": "atomic",
- },
- },
- 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/scope/v0alpha1.ScopeFilter"),
- },
- },
- },
- },
- },
- },
- Required: []string{"title", "description", "filters"},
- },
- },
- Dependencies: []string{
- "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeFilter"},
- }
-}
diff --git a/pkg/apis/scope/v0alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/scope/v0alpha1/zz_generated.openapi_violation_exceptions.list
deleted file mode 100644
index b473e1d66f0..00000000000
--- a/pkg/apis/scope/v0alpha1/zz_generated.openapi_violation_exceptions.list
+++ /dev/null
@@ -1,4 +0,0 @@
-API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,FindScopeDashboardBindingsResults,Items
-API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeDashboardBindingStatus,Groups
-API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeFilter,Values
-API rule violation: names_match,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeNodeSpec,LinkID
diff --git a/pkg/registry/apis/apis.go b/pkg/registry/apis/apis.go
index 0d3327725ab..5636df66eb3 100644
--- a/pkg/registry/apis/apis.go
+++ b/pkg/registry/apis/apis.go
@@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/iam"
"github.com/grafana/grafana/pkg/registry/apis/provisioning"
"github.com/grafana/grafana/pkg/registry/apis/query"
- "github.com/grafana/grafana/pkg/registry/apis/scope"
"github.com/grafana/grafana/pkg/registry/apis/userstorage"
)
@@ -31,7 +30,6 @@ func ProvideRegistryServiceSink(
_ *datasource.DataSourceAPIBuilder,
_ *folders.FolderAPIBuilder,
_ *iam.IdentityAccessManagementAPIBuilder,
- _ *scope.ScopeAPIBuilder,
_ *query.QueryAPIBuilder,
_ *notifications.NotificationsAPIBuilder,
_ *userstorage.UserStorageAPIBuilder,
diff --git a/pkg/registry/apis/scope/find.go b/pkg/registry/apis/scope/find.go
deleted file mode 100644
index 43cb057958a..00000000000
--- a/pkg/registry/apis/scope/find.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package scope
-
-import (
- "context"
- "fmt"
- "net/http"
- "strings"
-
- "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/apis/meta/internalversion"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/apiserver/pkg/registry/rest"
-
- scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
- "github.com/grafana/grafana/pkg/infra/log"
-)
-
-var logger = log.New("find-scopenode")
-
-type findREST struct {
- scopeNodeStorage *storage
-}
-
-var (
- _ rest.Storage = (*findREST)(nil)
- _ rest.SingularNameProvider = (*findREST)(nil)
- _ rest.Connecter = (*findREST)(nil)
- _ rest.Scoper = (*findREST)(nil)
- _ rest.StorageMetadata = (*findREST)(nil)
-)
-
-func (r *findREST) New() runtime.Object {
- // This is added as the "ResponseType" regarless what ProducesObject() says :)
- return &scope.FindScopeNodeChildrenResults{}
-}
-
-func (r *findREST) Destroy() {}
-
-func (r *findREST) NamespaceScoped() bool {
- return true
-}
-
-func (r *findREST) GetSingularName() string {
- return "FindScopeNodeChildrenResults" // Used for the
-}
-
-func (r *findREST) ProducesMIMETypes(verb string) []string {
- return []string{"application/json"} // and parquet!
-}
-
-func (r *findREST) ProducesObject(verb string) interface{} {
- return &scope.FindScopeNodeChildrenResults{}
-}
-
-func (r *findREST) ConnectMethods() []string {
- return []string{"GET"}
-}
-
-func (r *findREST) NewConnectOptions() (runtime.Object, bool, string) {
- return nil, false, "" // true means you can use the trailing path as a variable
-}
-
-func (r *findREST) Connect(ctx context.Context, name string, opts 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" {
- return nil, errors.NewNotFound(schema.GroupResource{}, name)
- }
-
- return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- parent := req.URL.Query().Get("parent")
- query := req.URL.Query().Get("query")
- results := &scope.FindScopeNodeChildrenResults{}
-
- raw, err := r.scopeNodeStorage.List(ctx, &internalversion.ListOptions{
- Limit: 10000,
- })
-
- if err != nil {
- responder.Error(err)
- return
- }
-
- all, ok := raw.(*scope.ScopeNodeList)
-
- if !ok {
- responder.Error(fmt.Errorf("expected ScopeNodeList"))
- return
- }
-
- for _, item := range all.Items {
- filterAndAppendItem(item, parent, query, results)
- }
-
- logger.FromContext(req.Context()).Debug("find scopenode", "raw", len(all.Items), "filtered", len(results.Items))
-
- responder.Object(200, results)
- }), nil
-}
-
-func filterAndAppendItem(item scope.ScopeNode, parent string, query string, results *scope.FindScopeNodeChildrenResults) {
- if parent != item.Spec.ParentName {
- return // Someday this will have an index in raw storage on parentName
- }
-
- // skip if query is passed and title doesn't contain the query.
- if query != "" && !strings.Contains(item.Spec.Title, query) {
- return
- }
-
- results.Items = append(results.Items, item)
-}
diff --git a/pkg/registry/apis/scope/find_scope_dashboards.go b/pkg/registry/apis/scope/find_scope_dashboards.go
deleted file mode 100644
index b33f091907e..00000000000
--- a/pkg/registry/apis/scope/find_scope_dashboards.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package scope
-
-import (
- "context"
- "fmt"
- "net/http"
- "slices"
- "strings"
-
- scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
- "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/apis/meta/internalversion"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/apiserver/pkg/registry/rest"
-)
-
-type findScopeDashboardsREST struct {
- scopeDashboardStorage *storage
-}
-
-var (
- _ rest.Storage = (*findScopeDashboardsREST)(nil)
- _ rest.SingularNameProvider = (*findScopeDashboardsREST)(nil)
- _ rest.Connecter = (*findScopeDashboardsREST)(nil)
- _ rest.Scoper = (*findScopeDashboardsREST)(nil)
- _ rest.StorageMetadata = (*findScopeDashboardsREST)(nil)
-)
-
-func (f *findScopeDashboardsREST) New() runtime.Object {
- return &scope.FindScopeDashboardBindingsResults{}
-}
-
-func (f *findScopeDashboardsREST) Destroy() {}
-
-func (f *findScopeDashboardsREST) NamespaceScoped() bool {
- return true
-}
-
-func (f *findScopeDashboardsREST) GetSingularName() string {
- return "FindScopeDashboardsResult" // not sure if this is actually used, but it is required to exist
-}
-
-func (f *findScopeDashboardsREST) ProducesMIMETypes(verb string) []string {
- return []string{"application/json"} // and parquet!
-}
-
-func (f *findScopeDashboardsREST) ProducesObject(verb string) interface{} {
- return &scope.FindScopeDashboardBindingsResults{}
-}
-
-func (f *findScopeDashboardsREST) ConnectMethods() []string {
- return []string{"GET"}
-}
-
-func (f *findScopeDashboardsREST) NewConnectOptions() (runtime.Object, bool, string) {
- return nil, false, "" // true means you can use the trailing path as a variable
-}
-
-func (f *findScopeDashboardsREST) Connect(ctx context.Context, name string, opts 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" {
- return nil, errors.NewNotFound(schema.GroupResource{}, name)
- }
-
- return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- raw, err := f.scopeDashboardStorage.List(ctx, &internalversion.ListOptions{
- Limit: 10000,
- })
- if err != nil {
- w.WriteHeader(500)
- return
- }
- all, ok := raw.(*scope.ScopeDashboardBindingList)
- if !ok {
- w.WriteHeader(500)
- return
- }
-
- scopes := req.URL.Query()["scope"]
- results := &scope.FindScopeDashboardBindingsResults{
- Message: fmt.Sprintf("Find: %s", scopes),
- Items: make([]scope.ScopeDashboardBinding, 0),
- }
-
- // we can improve the performance by calling .List once per scope if they are index by labels.
- // The API stays the same thou.
- for _, item := range all.Items {
- for _, s := range scopes {
- if item.Spec.Scope == s {
- results.Items = append(results.Items, item)
- }
- }
- }
-
- // sort the dashboard lists based on dashboard title.
- slices.SortFunc(results.Items, func(i, j scope.ScopeDashboardBinding) int {
- return strings.Compare(i.Status.DashboardTitle, j.Status.DashboardTitle)
- })
-
- logger.FromContext(req.Context()).Debug("find scopedashboardbinding", "raw", len(all.Items), "filtered", len(results.Items), "scopeQueryParams", strings.Join(scopes, ","))
-
- responder.Object(200, results)
- }), nil
-}
diff --git a/pkg/registry/apis/scope/find_test.go b/pkg/registry/apis/scope/find_test.go
deleted file mode 100644
index 0f9ce99b6e4..00000000000
--- a/pkg/registry/apis/scope/find_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package scope
-
-import (
- "testing"
-
- scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
- "github.com/stretchr/testify/require"
-)
-
-func TestFilterAndAppendItem(t *testing.T) {
- tcs := []struct {
- Description string
-
- ParentName string
- Title string
-
- QueryParam string
- ParentParam string
-
- ExpectedMatches int
- }{
- {
- Description: "Matching parent without query param",
- ParentName: "ParentNumberOne",
- Title: "item",
- QueryParam: "",
- ParentParam: "ParentNumberOne",
- ExpectedMatches: 1,
- },
- {
- Description: "Not matching parent",
- ParentName: "ParentNumberOne",
- Title: "itemOne",
- QueryParam: "itemTwo",
- ParentParam: "ParentNumberTwo",
- ExpectedMatches: 0,
- },
- {
- Description: "Matching parent and query param",
- ParentName: "ParentNumberOne",
- Title: "itemOne",
- QueryParam: "itemOne",
- ParentParam: "ParentNumberOne",
- ExpectedMatches: 1,
- },
- {
- Description: "matching parent but not matching query param",
- ParentName: "ParentNumberOne",
- Title: "itemOne",
- QueryParam: "itemTwo",
- ParentParam: "ParentNumberOne",
- ExpectedMatches: 0,
- },
- }
-
- for _, tc := range tcs {
- results := &scope.FindScopeNodeChildrenResults{}
- item := scope.ScopeNode{
- Spec: scope.ScopeNodeSpec{
- ParentName: tc.ParentName,
- Title: tc.Title,
- Description: "item description",
- NodeType: "item type",
- LinkType: "item link type",
- LinkID: "item link ID",
- },
- }
- filterAndAppendItem(item, tc.ParentParam, tc.QueryParam, results)
- require.Equal(t, len(results.Items), tc.ExpectedMatches, tc.Description)
- }
-}
diff --git a/pkg/registry/apis/scope/register.go b/pkg/registry/apis/scope/register.go
deleted file mode 100644
index c1144f519a8..00000000000
--- a/pkg/registry/apis/scope/register.go
+++ /dev/null
@@ -1,224 +0,0 @@
-package scope
-
-import (
- "fmt"
-
- "github.com/prometheus/client_golang/prometheus"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/apiserver/pkg/authorization/authorizer"
- "k8s.io/apiserver/pkg/registry/rest"
- genericapiserver "k8s.io/apiserver/pkg/server"
- "k8s.io/kube-openapi/pkg/common"
- "k8s.io/kube-openapi/pkg/spec3"
- "k8s.io/kube-openapi/pkg/validation/spec"
-
- scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
- "github.com/grafana/grafana/pkg/services/apiserver/builder"
- "github.com/grafana/grafana/pkg/services/featuremgmt"
-)
-
-var _ builder.APIGroupBuilder = (*ScopeAPIBuilder)(nil)
-
-// This is used just so wire has something unique to return
-type ScopeAPIBuilder struct{}
-
-func NewScopeAPIBuilder() *ScopeAPIBuilder {
- return &ScopeAPIBuilder{}
-}
-
-func RegisterAPIService(features featuremgmt.FeatureToggles, apiregistration builder.APIRegistrar, reg prometheus.Registerer) *ScopeAPIBuilder {
- if !featuremgmt.AnyEnabled(features,
- featuremgmt.FlagScopeApi,
- featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) {
- return nil // skip registration unless opting into experimental apis
- }
- builder := NewScopeAPIBuilder()
- apiregistration.RegisterAPI(builder)
- return builder
-}
-
-func (b *ScopeAPIBuilder) GetAuthorizer() authorizer.Authorizer {
- return nil // default authorizer is fine
-}
-
-func (b *ScopeAPIBuilder) GetGroupVersion() schema.GroupVersion {
- return scope.SchemeGroupVersion
-}
-
-func (b *ScopeAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
- err := scope.AddToScheme(scheme)
- if err != nil {
- return err
- }
-
- err = scheme.AddFieldLabelConversionFunc(
- scope.ScopeResourceInfo.GroupVersionKind(),
- func(label, value string) (string, string, error) {
- fieldSet := SelectableScopeFields(&scope.Scope{})
- for key := range fieldSet {
- if label == key {
- return label, value, nil
- }
- }
- return "", "", fmt.Errorf("field label not supported for %s: %s", scope.ScopeResourceInfo.GroupVersionKind(), label)
- },
- )
- if err != nil {
- return err
- }
-
- err = scheme.AddFieldLabelConversionFunc(
- scope.ScopeDashboardBindingResourceInfo.GroupVersionKind(),
- func(label, value string) (string, string, error) {
- fieldSet := SelectableScopeDashboardBindingFields(&scope.ScopeDashboardBinding{})
- for key := range fieldSet {
- if label == key {
- return label, value, nil
- }
- }
- return "", "", fmt.Errorf("field label not supported for %s: %s", scope.ScopeDashboardBindingResourceInfo.GroupVersionKind(), label)
- },
- )
- if err != nil {
- return err
- }
-
- err = scheme.AddFieldLabelConversionFunc(
- scope.ScopeNodeResourceInfo.GroupVersionKind(),
- func(label, value string) (string, string, error) {
- fieldSet := SelectableScopeNodeFields(&scope.ScopeNode{})
- for key := range fieldSet {
- if label == key {
- return label, value, nil
- }
- }
- return "", "", fmt.Errorf("field label not supported for %s: %s", scope.ScopeNodeResourceInfo.GroupVersionKind(), label)
- },
- )
- if err != nil {
- return err
- }
-
- // This is required for --server-side apply
- err = scope.AddKnownTypes(scope.InternalGroupVersion, scheme)
- if err != nil {
- return err
- }
-
- // Only one version right now
- return scheme.SetVersionPriority(scope.SchemeGroupVersion)
-}
-
-func (b *ScopeAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error {
- scheme := opts.Scheme
- optsGetter := opts.OptsGetter
-
- scopeResourceInfo := scope.ScopeResourceInfo
- scopeDashboardResourceInfo := scope.ScopeDashboardBindingResourceInfo
- scopeNodeResourceInfo := scope.ScopeNodeResourceInfo
-
- storage := map[string]rest.Storage{}
-
- scopeStorage, err := newScopeStorage(scheme, optsGetter)
- if err != nil {
- return err
- }
- storage[scopeResourceInfo.StoragePath()] = scopeStorage
-
- scopeDashboardStorage, scopedDashboardStatusStorage, err := newScopeDashboardBindingStorage(scheme, optsGetter)
- if err != nil {
- return err
- }
- storage[scopeDashboardResourceInfo.StoragePath()] = scopeDashboardStorage
- storage[scopeDashboardResourceInfo.StoragePath()+"/status"] = scopedDashboardStatusStorage
-
- scopeNodeStorage, err := newScopeNodeStorage(scheme, optsGetter)
- if err != nil {
- return err
- }
- storage[scopeNodeResourceInfo.StoragePath()] = scopeNodeStorage
-
- // Adds a rest.Connector
- // NOTE! the server has a hardcoded rewrite filter that fills in a name
- // so the standard k8s plumbing continues to work
- storage["scope_node_children"] = &findREST{scopeNodeStorage: scopeNodeStorage}
-
- // Adds a rest.Connector
- // NOTE! the server has a hardcoded rewrite filter that fills in a name
- // so the standard k8s plumbing continues to work
- storage["scope_dashboard_bindings"] = &findScopeDashboardsREST{scopeDashboardStorage: scopeDashboardStorage}
-
- apiGroupInfo.VersionedResourcesStorageMap[scope.VERSION] = storage
- return nil
-}
-
-func (b *ScopeAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
- return scope.GetOpenAPIDefinitions
-}
-
-func (b *ScopeAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) {
- // The plugin description
- oas.Info.Description = "Grafana scopes"
-
- // The root api URL
- root := "/apis/" + b.GetGroupVersion().String() + "/"
-
- // Add query parameters to the rest.Connector
- sub := oas.Paths.Paths[root+"namespaces/{namespace}/scope_node_children/{name}"]
- if sub != nil && sub.Get != nil {
- sub.Parameters = []*spec3.Parameter{
- {
- ParameterProps: spec3.ParameterProps{
- Name: "namespace",
- In: "path",
- Description: "object name and auth scope, such as for teams and projects",
- Example: "default",
- Required: true,
- Schema: spec.StringProperty().UniqueValues(),
- },
- },
- }
- sub.Get.Description = "Navigate the scopes tree"
- sub.Get.Parameters = []*spec3.Parameter{
- {
- ParameterProps: spec3.ParameterProps{
- Name: "parent",
- In: "query",
- Description: "The parent scope node",
- },
- },
- }
- delete(oas.Paths.Paths, root+"namespaces/{namespace}/scope_node_children/{name}")
- oas.Paths.Paths[root+"namespaces/{namespace}/find/scope_node_children"] = sub
- }
-
- findDashboardPath := oas.Paths.Paths[root+"namespaces/{namespace}/scope_dashboard_bindings/{name}"]
- if findDashboardPath != nil && sub.Get != nil {
- sub.Parameters = []*spec3.Parameter{
- {
- ParameterProps: spec3.ParameterProps{
- Name: "namespace",
- In: "path",
- Description: "object name and auth scope, such as for teams and projects",
- Example: "default",
- Required: true,
- },
- },
- }
- findDashboardPath.Get.Description = "find scope dashboard bindings that match any of the given scopes."
- findDashboardPath.Get.Parameters = []*spec3.Parameter{
- {
- ParameterProps: spec3.ParameterProps{
- Name: "scope",
- In: "query",
- Description: "A scope name (id) to match against, this parameter may be repeated",
- },
- },
- }
- delete(oas.Paths.Paths, root+"namespaces/{namespace}/scope_dashboard_bindings/{name}")
- oas.Paths.Paths[root+"namespaces/{namespace}/find/scope_dashboard_bindings"] = findDashboardPath
- }
-
- return oas, nil
-}
diff --git a/pkg/registry/apis/scope/storage.go b/pkg/registry/apis/scope/storage.go
deleted file mode 100644
index 23b4d4c21f9..00000000000
--- a/pkg/registry/apis/scope/storage.go
+++ /dev/null
@@ -1,142 +0,0 @@
-package scope
-
-import (
- "fmt"
-
- "k8s.io/apimachinery/pkg/fields"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apiserver/pkg/registry/generic"
- genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
- apistore "k8s.io/apiserver/pkg/storage"
-
- scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
- grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic"
- grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
-)
-
-var _ grafanarest.Storage = (*storage)(nil)
-
-type storage struct {
- *genericregistry.Store
-}
-
-func newScopeStorage(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*storage, error) {
- resourceInfo := scope.ScopeResourceInfo
- strategy := grafanaregistry.NewStrategy(scheme, resourceInfo.GroupVersion())
- store := &genericregistry.Store{
- NewFunc: resourceInfo.NewFunc,
- NewListFunc: resourceInfo.NewListFunc,
- KeyRootFunc: grafanaregistry.KeyRootFunc(resourceInfo.GroupResource()),
- KeyFunc: grafanaregistry.NamespaceKeyFunc(resourceInfo.GroupResource()),
- PredicateFunc: Matcher,
- DefaultQualifiedResource: resourceInfo.GroupResource(),
- SingularQualifiedResource: resourceInfo.SingularGroupResource(),
- TableConvertor: resourceInfo.TableConverter(),
- CreateStrategy: strategy,
- UpdateStrategy: strategy,
- DeleteStrategy: strategy,
- }
- options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
- if err := store.CompleteWithOptions(options); err != nil {
- return nil, err
- }
- return &storage{Store: store}, nil
-}
-
-func newScopeDashboardBindingStorage(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*storage, *grafanaregistry.StatusREST, error) {
- resourceInfo := scope.ScopeDashboardBindingResourceInfo
- strategy := grafanaregistry.NewStrategy(scheme, resourceInfo.GroupVersion())
-
- store := &genericregistry.Store{
- NewFunc: resourceInfo.NewFunc,
- NewListFunc: resourceInfo.NewListFunc,
- KeyRootFunc: grafanaregistry.KeyRootFunc(resourceInfo.GroupResource()),
- KeyFunc: grafanaregistry.NamespaceKeyFunc(resourceInfo.GroupResource()),
- PredicateFunc: Matcher,
- DefaultQualifiedResource: resourceInfo.GroupResource(),
- SingularQualifiedResource: resourceInfo.SingularGroupResource(),
- TableConvertor: resourceInfo.TableConverter(),
- CreateStrategy: strategy,
- UpdateStrategy: strategy,
- DeleteStrategy: strategy,
- }
- options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
- if err := store.CompleteWithOptions(options); err != nil {
- return nil, nil, err
- }
-
- statusStrategy := grafanaregistry.NewStatusStrategy(scheme, resourceInfo.GroupVersion())
- statusREST := grafanaregistry.NewStatusREST(store, statusStrategy)
- return &storage{Store: store}, statusREST, nil
-}
-
-func newScopeNodeStorage(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*storage, error) {
- resourceInfo := scope.ScopeNodeResourceInfo
- strategy := grafanaregistry.NewStrategy(scheme, resourceInfo.GroupVersion())
-
- store := &genericregistry.Store{
- NewFunc: resourceInfo.NewFunc,
- NewListFunc: resourceInfo.NewListFunc,
- KeyRootFunc: grafanaregistry.KeyRootFunc(resourceInfo.GroupResource()),
- KeyFunc: grafanaregistry.NamespaceKeyFunc(resourceInfo.GroupResource()),
- PredicateFunc: Matcher,
- DefaultQualifiedResource: resourceInfo.GroupResource(),
- SingularQualifiedResource: resourceInfo.SingularGroupResource(),
- TableConvertor: resourceInfo.TableConverter(),
- CreateStrategy: strategy,
- UpdateStrategy: strategy,
- DeleteStrategy: strategy,
- }
- options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
- if err := store.CompleteWithOptions(options); err != nil {
- return nil, err
- }
- return &storage{Store: store}, nil
-}
-
-func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
- if s, ok := obj.(*scope.Scope); ok {
- return labels.Set(s.Labels), SelectableScopeFields(s), nil
- }
- if s, ok := obj.(*scope.ScopeDashboardBinding); ok {
- return labels.Set(s.Labels), SelectableScopeDashboardBindingFields(s), nil
- }
- if s, ok := obj.(*scope.ScopeNode); ok {
- return labels.Set(s.Labels), SelectableScopeNodeFields(s), nil
- }
- return nil, nil, fmt.Errorf("not a scope or ScopeDashboardBinding object")
-}
-
-// Matcher returns a generic.SelectionPredicate that matches on label and field selectors.
-func Matcher(label labels.Selector, field fields.Selector) apistore.SelectionPredicate {
- return apistore.SelectionPredicate{
- Label: label,
- Field: field,
- GetAttrs: GetAttrs,
- }
-}
-
-func SelectableScopeFields(obj *scope.Scope) fields.Set {
- return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{
- "spec.title": obj.Spec.Title,
- })
-}
-
-func SelectableScopeDashboardBindingFields(obj *scope.ScopeDashboardBinding) fields.Set {
- return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{
- "spec.scope": obj.Spec.Scope,
- })
-}
-
-func SelectableScopeNodeFields(obj *scope.ScopeNode) fields.Set {
- parentName := ""
-
- if obj != nil {
- parentName = obj.Spec.ParentName
- }
-
- return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{
- "spec.parentName": parentName,
- })
-}
diff --git a/pkg/registry/apis/wireset.go b/pkg/registry/apis/wireset.go
index 22734abadbb..c98c4da67be 100644
--- a/pkg/registry/apis/wireset.go
+++ b/pkg/registry/apis/wireset.go
@@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/iam"
"github.com/grafana/grafana/pkg/registry/apis/provisioning"
"github.com/grafana/grafana/pkg/registry/apis/query"
- "github.com/grafana/grafana/pkg/registry/apis/scope"
"github.com/grafana/grafana/pkg/registry/apis/service"
"github.com/grafana/grafana/pkg/registry/apis/userstorage"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
@@ -42,7 +41,6 @@ var WireSet = wire.NewSet(
provisioning.RegisterAPIService,
service.RegisterAPIService,
query.RegisterAPIService,
- scope.RegisterAPIService,
notifications.RegisterAPIService,
userstorage.RegisterAPIService,
)
diff --git a/pkg/services/accesscontrol/pluginutils/utils.go b/pkg/services/accesscontrol/pluginutils/utils.go
index 0fe7a46b199..8b7500a97cd 100644
--- a/pkg/services/accesscontrol/pluginutils/utils.go
+++ b/pkg/services/accesscontrol/pluginutils/utils.go
@@ -12,6 +12,7 @@ import (
var (
allowedCoreActions = map[string]string{
+ "plugins:write": "plugins:id:",
"plugins.app:access": "plugins:id:",
"folders:create": "folders:uid:",
"folders:read": "folders:uid:",
diff --git a/pkg/services/accesscontrol/pluginutils/utils_test.go b/pkg/services/accesscontrol/pluginutils/utils_test.go
index 80289ec77e7..746d92289f4 100644
--- a/pkg/services/accesscontrol/pluginutils/utils_test.go
+++ b/pkg/services/accesscontrol/pluginutils/utils_test.go
@@ -172,6 +172,29 @@ func TestValidatePluginRole(t *testing.T) {
},
wantErr: &ac.ErrorInvalidRole{},
},
+ {
+ name: "valid core plugin permission targets plugin",
+ pluginID: "test-app",
+ role: ac.RoleDTO{
+ Name: "plugins:test-app:reader",
+ DisplayName: "Plugin Configurator",
+ Permissions: []ac.Permission{
+ {Action: "plugins:write", Scope: "plugins:id:test-app"},
+ },
+ },
+ },
+ {
+ name: "invalid core plugin permission targets other plugin",
+ pluginID: "test-app",
+ role: ac.RoleDTO{
+ Name: "plugins:test-app:reader",
+ DisplayName: "Plugin Configurator",
+ Permissions: []ac.Permission{
+ {Action: "plugins:write", Scope: "plugins:id:other-app"},
+ },
+ },
+ wantErr: &ac.ErrorInvalidRole{},
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
diff --git a/pkg/tests/apis/scopes/scope_nodes_example_test.go b/pkg/tests/apis/scopes/scope_nodes_example_test.go
deleted file mode 100644
index 71846d207df..00000000000
--- a/pkg/tests/apis/scopes/scope_nodes_example_test.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package scopes
-
-import (
- "context"
- "encoding/json"
- "os"
- "testing"
-
- "github.com/grafana/grafana/pkg/services/featuremgmt"
- "github.com/grafana/grafana/pkg/tests/apis"
- "github.com/grafana/grafana/pkg/tests/testinfra"
- "github.com/stretchr/testify/require"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/runtime/schema"
-)
-
-func TestIntegrationScopeNodesExample(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping integration test in short mode.")
- }
-
- ctx := context.Background()
- helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
- AppModeProduction: false, // required for experimental APIs
- EnableFeatureToggles: []string{
- featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs, // Required to start the example service
- },
- })
-
- scopeClient := helper.GetResourceClient(apis.ResourceClientArgs{
- User: helper.Org1.Admin,
- Namespace: "default", // actually org1
- GVR: schema.GroupVersionResource{
- Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopes",
- },
- })
-
- scopeNodesClient := helper.GetResourceClient(apis.ResourceClientArgs{
- User: helper.Org1.Admin,
- Namespace: "default", // actually org1
- GVR: schema.GroupVersionResource{
- Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopenodes",
- },
- })
-
- createOptions := metav1.CreateOptions{FieldValidation: "Strict"}
-
- t.Run("Create scopes", func(t *testing.T) {
- ul := jsonListToUnstructuredList(t, "testdata/scopeNodesExample/scopes.json")
-
- for _, item := range ul.Items {
- _, err := scopeClient.Resource.Create(ctx, &item, createOptions)
- require.NoError(t, err)
- }
-
- found, err := scopeClient.Resource.List(ctx, metav1.ListOptions{})
- require.NoError(t, err)
- require.Len(t, found.Items, 5)
- })
-
- t.Run("Create scopeNodes", func(t *testing.T) {
- ul := jsonListToUnstructuredList(t, "testdata/scopeNodesExample/scopeNodes.json")
-
- for _, item := range ul.Items {
- _, err := scopeNodesClient.Resource.Create(ctx, &item, createOptions)
- require.NoError(t, err)
- }
-
- found, err := scopeNodesClient.Resource.List(ctx, metav1.ListOptions{})
- require.NoError(t, err)
- require.Len(t, found.Items, 12)
- })
-}
-
-func jsonListToUnstructuredList(t *testing.T, fname string) (ul unstructured.UnstructuredList) {
- // nolint:gosec
- f, err := os.ReadFile(fname)
- require.NoError(t, err)
-
- err = json.Unmarshal(f, &ul)
- require.NoError(t, err)
- return
-}
diff --git a/pkg/tests/apis/scopes/scopes_test.go b/pkg/tests/apis/scopes/scopes_test.go
deleted file mode 100644
index bf8fd293286..00000000000
--- a/pkg/tests/apis/scopes/scopes_test.go
+++ /dev/null
@@ -1,221 +0,0 @@
-package scopes
-
-import (
- "context"
- "encoding/json"
- "strings"
- "testing"
-
- "github.com/stretchr/testify/require"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/runtime/schema"
-
- "github.com/grafana/grafana/pkg/services/featuremgmt"
- "github.com/grafana/grafana/pkg/tests/apis"
- "github.com/grafana/grafana/pkg/tests/testinfra"
- "github.com/grafana/grafana/pkg/tests/testsuite"
-)
-
-func TestMain(m *testing.M) {
- testsuite.Run(m)
-}
-
-func TestIntegrationScopes(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping integration test")
- }
-
- ctx := context.Background()
- helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
- AppModeProduction: true,
- EnableFeatureToggles: []string{
- featuremgmt.FlagScopeApi, // Required to register the API
- },
- })
-
- t.Run("Check discovery client", func(t *testing.T) {
- disco := helper.NewDiscoveryClient()
- resources, err := disco.ServerResourcesForGroupVersion("scope.grafana.app/v0alpha1")
- require.NoError(t, err)
-
- v1Disco, err := json.MarshalIndent(resources, "", " ")
- require.NoError(t, err)
- //fmt.Printf("%s", string(v1Disco))
-
- require.JSONEq(t, `{
- "kind": "APIResourceList",
- "apiVersion": "v1",
- "groupVersion": "scope.grafana.app/v0alpha1",
- "resources": [
- {
- "name": "scope_dashboard_bindings",
- "singularName": "FindScopeDashboardsResult",
- "namespaced": true,
- "kind": "FindScopeDashboardBindingsResults",
- "verbs": [
- "get"
- ]
- },
- {
- "name": "scope_node_children",
- "singularName": "FindScopeNodeChildrenResults",
- "namespaced": true,
- "kind": "FindScopeNodeChildrenResults",
- "verbs": [
- "get"
- ]
- },
- {
- "name": "scopedashboardbindings",
- "singularName": "scopedashboardbinding",
- "namespaced": true,
- "kind": "ScopeDashboardBinding",
- "verbs": [
- "create",
- "delete",
- "deletecollection",
- "get",
- "list",
- "patch",
- "update",
- "watch"
- ]
- },
- {
- "name": "scopedashboardbindings/status",
- "singularName": "",
- "namespaced": true,
- "kind": "ScopeDashboardBinding",
- "verbs": [
- "get",
- "patch",
- "update"
- ]
- },
- {
- "name": "scopenodes",
- "singularName": "scopenode",
- "namespaced": true,
- "kind": "ScopeNode",
- "verbs": [
- "create",
- "delete",
- "deletecollection",
- "get",
- "list",
- "patch",
- "update",
- "watch"
- ]
- },
- {
- "name": "scopes",
- "singularName": "scope",
- "namespaced": true,
- "kind": "Scope",
- "verbs": [
- "create",
- "delete",
- "deletecollection",
- "get",
- "list",
- "patch",
- "update",
- "watch"
- ]
- }
- ]
- }`, string(v1Disco))
- })
-
- t.Run("Check create and list", func(t *testing.T) {
- // Scope create+get
- scopeClient := helper.GetResourceClient(apis.ResourceClientArgs{
- User: helper.Org1.Admin,
- Namespace: "default", // actually org1
- GVR: schema.GroupVersionResource{
- Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopes",
- },
- })
- createOptions := metav1.CreateOptions{FieldValidation: "Strict"}
-
- s0, err := scopeClient.Resource.Create(ctx,
- helper.LoadYAMLOrJSONFile("testdata/example-scope.yaml"),
- createOptions,
- )
-
- require.NoError(t, err)
- require.Equal(t, "example", s0.GetName())
- s1, err := scopeClient.Resource.Get(ctx, "example", metav1.GetOptions{})
- require.NoError(t, err)
- require.Equal(t,
- mustNestedString(s0.Object, "spec", "title"),
- mustNestedString(s1.Object, "spec", "title"),
- )
-
- _, err = scopeClient.Resource.Create(ctx,
- helper.LoadYAMLOrJSONFile("testdata/example-scope2.yaml"),
- createOptions,
- )
- require.NoError(t, err)
-
- // Name length test
- scope3 := helper.LoadYAMLOrJSONFile("testdata/example-scope3.yaml")
-
- // Name too long (>253)
- scope3.SetName(strings.Repeat("0", 254))
- _, err = scopeClient.Resource.Create(ctx,
- scope3,
- createOptions,
- )
- require.Error(t, err)
-
- // Maximum allowed length for name (253)
- scope3.SetName(strings.Repeat("0", 253))
- _, err = scopeClient.Resource.Create(ctx,
- scope3,
- createOptions,
- )
- require.NoError(t, err)
-
- // Field Selector test
- found, err := scopeClient.Resource.List(ctx, metav1.ListOptions{
- FieldSelector: "spec.title=foo-scope",
- })
- require.NoError(t, err)
- require.Len(t, found.Items, 1)
- require.Equal(t,
- "example2",
- mustNestedString(found.Items[0].Object, "metadata", "name"),
- )
-
- // Create bindings
- scopeDashboardBindingClient := helper.GetResourceClient(apis.ResourceClientArgs{
- User: helper.Org1.Admin,
- Namespace: "default", // actually org1
- GVR: schema.GroupVersionResource{
- Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopedashboardbindings",
- },
- })
- _, err = scopeDashboardBindingClient.Resource.Create(ctx,
- helper.LoadYAMLOrJSONFile("testdata/example-scope-dashboard-binding-abc.yaml"),
- createOptions,
- )
- require.NoError(t, err)
- _, err = scopeDashboardBindingClient.Resource.Create(ctx,
- helper.LoadYAMLOrJSONFile("testdata/example-scope-dashboard-binding-xyz.yaml"),
- createOptions,
- )
- require.NoError(t, err)
-
- found, err = scopeDashboardBindingClient.Resource.List(ctx, metav1.ListOptions{})
- require.NoError(t, err)
- require.Len(t, found.Items, 2)
- })
-}
-
-func mustNestedString(obj map[string]interface{}, fields ...string) string {
- v, _, _ := unstructured.NestedString(obj, fields...)
- return v
-}
diff --git a/pkg/tests/apis/scopes/testdata/example-scope-dashboard-binding-abc.yaml b/pkg/tests/apis/scopes/testdata/example-scope-dashboard-binding-abc.yaml
deleted file mode 100644
index 190d006cca6..00000000000
--- a/pkg/tests/apis/scopes/testdata/example-scope-dashboard-binding-abc.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: scope.grafana.app/v0alpha1
-kind: ScopeDashboardBinding
-metadata:
- name: example_abc
-spec:
- scope: example
- dashboard: abc
-status:
- dashboardTitle: "Example Dashboard ABC"
- groups: ["group1", "group2"]
\ No newline at end of file
diff --git a/pkg/tests/apis/scopes/testdata/example-scope-dashboard-binding-xyz.yaml b/pkg/tests/apis/scopes/testdata/example-scope-dashboard-binding-xyz.yaml
deleted file mode 100644
index 4d289e8d8c6..00000000000
--- a/pkg/tests/apis/scopes/testdata/example-scope-dashboard-binding-xyz.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: scope.grafana.app/v0alpha1
-kind: ScopeDashboardBinding
-metadata:
- name: example_xyz
-spec:
- scope: example
- dashboard: xyz
-status:
- dashboardTitle: "Example Dashboard XYZ"
- groups: ["group2", "group3"]
\ No newline at end of file
diff --git a/pkg/tests/apis/scopes/testdata/example-scope.yaml b/pkg/tests/apis/scopes/testdata/example-scope.yaml
deleted file mode 100644
index b5a7eccf009..00000000000
--- a/pkg/tests/apis/scopes/testdata/example-scope.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: scope.grafana.app/v0alpha1
-kind: Scope
-metadata:
- name: example
-spec:
- title: bar-scope
- description: Longer description for a scope
- filters:
- - key: aaa
- operator: equals
- value: bbb
- - key: ccc
- operator: not-equals
- value: ddd
diff --git a/pkg/tests/apis/scopes/testdata/example-scope2.yaml b/pkg/tests/apis/scopes/testdata/example-scope2.yaml
deleted file mode 100644
index aa6e38513b3..00000000000
--- a/pkg/tests/apis/scopes/testdata/example-scope2.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: scope.grafana.app/v0alpha1
-kind: Scope
-metadata:
- name: example2
-spec:
- title: foo-scope
- description: Longer description for a scope
- filters:
- - key: aaa
- operator: equals
- value: zzz
- - key: ccc
- operator: not-equals
- value: yyy
diff --git a/pkg/tests/apis/scopes/testdata/example-scope3.yaml b/pkg/tests/apis/scopes/testdata/example-scope3.yaml
deleted file mode 100644
index e1f36c39d87..00000000000
--- a/pkg/tests/apis/scopes/testdata/example-scope3.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: scope.grafana.app/v0alpha1
-kind: Scope
-metadata:
- name: example-long
-spec:
- title: baz-scope
- description: Longer description for a scope
- filters:
- - key: aaa
- operator: equals
- value: eee
- - key: ccc
- operator: not-equals
- value: fff
diff --git a/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopeNodes.json b/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopeNodes.json
deleted file mode 100644
index b5163d5b5c6..00000000000
--- a/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopeNodes.json
+++ /dev/null
@@ -1,179 +0,0 @@
-{
- "kind": "List",
- "items": [
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "applications"
- },
- "spec": {
- "description": "Application Scopes",
- "title": "Applications",
- "nodeType": "container"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "applications-clusters"
- },
- "spec": {
- "description": "Application/Clusters Scopes",
- "title": "Clusters",
- "nodeType": "container",
- "parentName": "applications",
- "linkId": "indexHelperCluster",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "clusters"
- },
- "spec": {
- "description": "Cluster Scopes",
- "title": "Clusters",
- "nodeType": "container",
- "linkId": "indexHelperCluster",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "clusters-application"
- },
- "spec": {
- "description": "Clusters/Application Scopes",
- "title": "Applications",
- "nodeType": "container",
- "parentName": "clusters"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "applications-slothPictureFactory"
- },
- "spec": {
- "description": "slothPictureFactory",
- "title": "slothPictureFactory",
- "nodeType": "leaf",
- "parentName": "applications",
- "linkId": "slothPictureFactory",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "applications-slothVoteTracker"
- },
- "spec": {
- "description": "slothVoteTracker",
- "title": "slothVoteTracker",
- "nodeType": "leaf",
- "parentName": "applications",
- "linkId": "slothVoteTracker",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "applications-clusters-slothClusterNorth"
- },
- "spec": {
- "description": "slothClusterNorth",
- "title": "slothClusterNorth",
- "nodeType": "leaf",
- "parentName": "applications-clusters",
- "linkId": "slothClusterNorth",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "applications-clusters-slothClusterSouth"
- },
- "spec": {
- "description": "slothClusterSouth",
- "title": "slothClusterSouth",
- "nodeType": "leaf",
- "parentName": "applications-clusters",
- "linkId": "slothClusterSouth",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "clusters-slothClusterNorth"
- },
- "spec": {
- "description": "slothClusterNorth",
- "title": "slothClusterNorth",
- "nodeType": "leaf",
- "parentName": "clusters",
- "linkId": "slothClusterNorth",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "clusters-slothClusterSouth"
- },
- "spec": {
- "description": "slothClusterSouth",
- "title": "slothClusterSouth",
- "nodeType": "leaf",
- "parentName": "clusters",
- "linkId": "slothClusterSouth",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "clusters-applications-slothPictureFactory"
- },
- "spec": {
- "description": "slothPictureFactory",
- "title": "slothPictureFactory",
- "nodeType": "leaf",
- "parentName": "clusters-applications",
- "linkId": "slothPictureFactory",
- "linkType": "scope"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "ScopeNode",
- "metadata": {
- "name": "clusters-applications-slothVoteTracker"
- },
- "spec": {
- "description": "slothVoteTracker",
- "title": "slothVoteTracker",
- "nodeType": "leaf",
- "parentName": "clusters-applications",
- "linkId": "slothVoteTracker",
- "linkType": "scope"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopes.json b/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopes.json
deleted file mode 100644
index 13b3d2bb4f8..00000000000
--- a/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopes.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
- "kind": "List",
- "items": [
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "Scope",
- "metadata": {
- "name": "slothClusterNorth"
- },
- "spec": {
- "description": "slothClusterNorth",
- "filters": [
- {
- "key": "cluster",
- "operator": "equals",
- "value": "slothClusterNorth"
- }
- ],
- "title": "slothClusterNorth"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "Scope",
- "metadata": {
- "name": "slothClusterSouth"
- },
- "spec": {
- "description": "slothClusterSouth",
- "filters": [
- {
- "key": "cluster",
- "operator": "equals",
- "value": "slothClusterSouth"
- }
- ],
- "title": "slothClusterSouth"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "Scope",
- "metadata": {
- "name": "slothPictureFactory"
- },
- "spec": {
- "description": "slothPictureFactory",
- "filters": [
- {
- "key": "app",
- "operator": "equals",
- "value": "slothPictureFactory"
- }
- ],
- "title": "slothPictureFactory"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "Scope",
- "metadata": {
- "name": "slothVoteTracker"
- },
- "spec": {
- "description": "slothVoteTracker",
- "filters": [
- {
- "key": "app",
- "operator": "equals",
- "value": "slothVoteTracker"
- }
- ],
- "title": "slothVoteTracker"
- }
- },
- {
- "apiVersion": "scope.grafana.app/v0alpha1",
- "kind": "Scope",
- "metadata": {
- "name": "indexHelperCluster"
- },
- "spec": {
- "description": "redundant label filter but makes queries faster",
- "filters": [
- {
- "key": "indexHelper",
- "operator": "equals",
- "value": "cluster"
- }
- ],
- "title": "Cluster Index Helper"
- }
- }
- ]
-}
\ No newline at end of file