diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go index 5d0d6801fcb..ccb68473004 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go @@ -24,6 +24,15 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAnnotationPanelFilter": schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationPanelFilter(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQueryKind": schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationQueryKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQuerySpec": schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationQuerySpec(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingDataKind": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingDataKind(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingDataSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingDataSpec(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupKind": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingGroupKind(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingGroupSpec(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingTimeIntervalKind": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingTimeIntervalKind(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingTimeIntervalSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingTimeIntervalSpec(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingVariableKind(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingVariableSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardConstantVariableKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardConstantVariableSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConversionStatus": schema_pkg_apis_dashboard_v2alpha1_DashboardConversionStatus(ref), @@ -634,6 +643,255 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationQuerySpec(ref common. } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingDataKind(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{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingDataSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingDataSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingDataSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "value": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"value"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingGroupKind(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{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingGroupSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "condition": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind"), + }, + }, + }, + }, + }, + }, + Required: []string{"condition", "items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingTimeIntervalKind(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{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingTimeIntervalSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingTimeIntervalSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingTimeIntervalSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "value": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"value"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingVariableKind(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{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ConditionalRenderingVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableKind"), + }, + }, + "ConditionalRenderingDataKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingDataKind"), + }, + }, + "ConditionalRenderingTimeIntervalKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingTimeIntervalKind"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingDataKind", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingTimeIntervalKind", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingVariableKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConditionalRenderingVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "variable": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "operator": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"variable", "operator", "value"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardConstantVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -3116,12 +3374,17 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutItemSpec(re Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridRepeatOptions"), }, }, + "conditionalRendering": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupKind"), + }, + }, }, Required: []string{"element"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardElementReference", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridRepeatOptions"}, + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupKind", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardElementReference", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridRepeatOptions"}, } } @@ -3324,6 +3587,11 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutRowSpec(ref common.Re Format: "", }, }, + "conditionalRendering": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupKind"), + }, + }, "repeat": { SchemaProps: spec.SchemaProps{ Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions"), @@ -3339,7 +3607,7 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutRowSpec(ref common.Re }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions"}, + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardConditionalRenderingGroupKind", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions"}, } } diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list index 66ecc8175bb..31084da6e9f 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list @@ -3,6 +3,7 @@ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,BaseFilters API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,DefaultKeys API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,Filters +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardConditionalRenderingGroupSpec,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardCustomVariableSpec,Options API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardDashboardLink,Tags API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardDatasourceVariableSpec,Options @@ -31,6 +32,9 @@ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardTimeSettingsSpec,QuickRanges API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardV2alpha1FieldConfigSourceOverrides,Properties API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,LibraryPanelStatus,Warnings +API rule violation: names_match,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind,ConditionalRenderingDataKind +API rule violation: names_match,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind,ConditionalRenderingTimeIntervalKind +API rule violation: names_match,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardConditionalRenderingVariableKindOrConditionalRenderingDataKindOrConditionalRenderingTimeIntervalKind,ConditionalRenderingVariableKind API rule violation: names_match,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutItemKindOrGridLayoutRowKind,GridLayoutItemKind API rule violation: names_match,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutItemKindOrGridLayoutRowKind,GridLayoutRowKind API rule violation: names_match,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,GridLayoutKind diff --git a/pkg/apis/secret/README.md b/pkg/apis/secret/README.md new file mode 100644 index 00000000000..a375b20df06 --- /dev/null +++ b/pkg/apis/secret/README.md @@ -0,0 +1,20 @@ +# pkg/apis/secret + +General documentation on the Secrets API for App Platform. + +## Regenerating codegen files + +Currently the generated files are not using `grafana-app-sdk` and does not have a CUE schema definition. + +In order to regenerate the codegen files (those prefixed by `zz_`), you can run: +```sh +./hack/update-codegen.sh secret +``` + +More details [here](https://github.com/grafana/grafana/tree/main/hack#kubernetes-hack-alert). + +## Regenerating Protobuf files + +```sh +make protobuf +``` diff --git a/pkg/apis/secret/v0alpha1/decrypt/buf.gen.yaml b/pkg/apis/secret/v0alpha1/decrypt/buf.gen.yaml new file mode 100644 index 00000000000..f725fb6452d --- /dev/null +++ b/pkg/apis/secret/v0alpha1/decrypt/buf.gen.yaml @@ -0,0 +1,12 @@ +version: v1 + +plugins: + - plugin: go + out: pkg/apis/secret/v0alpha1/decrypt + opt: + - paths=source_relative + - plugin: go-grpc + out: pkg/apis/secret/v0alpha1/decrypt + opt: + - paths=source_relative + - require_unimplemented_servers=false diff --git a/pkg/apis/secret/v0alpha1/decrypt/buf.yaml b/pkg/apis/secret/v0alpha1/decrypt/buf.yaml new file mode 100644 index 00000000000..1a5194568a9 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/decrypt/buf.yaml @@ -0,0 +1,7 @@ +version: v1 +breaking: + use: + - FILE +lint: + use: + - DEFAULT diff --git a/pkg/apis/secret/v0alpha1/decrypt/decrypt.pb.go b/pkg/apis/secret/v0alpha1/decrypt/decrypt.pb.go new file mode 100644 index 00000000000..58bcba20ae0 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/decrypt/decrypt.pb.go @@ -0,0 +1,214 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.4 +// protoc (unknown) +// source: decrypt.proto + +package decrypt + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SecureValueDecryptRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The stack_id or org_id. + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` + // A list of secure value names to decrypt. + Names []string `protobuf:"bytes,2,rep,name=names,proto3" json:"names,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SecureValueDecryptRequest) Reset() { + *x = SecureValueDecryptRequest{} + mi := &file_decrypt_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SecureValueDecryptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecureValueDecryptRequest) ProtoMessage() {} + +func (x *SecureValueDecryptRequest) ProtoReflect() protoreflect.Message { + mi := &file_decrypt_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecureValueDecryptRequest.ProtoReflect.Descriptor instead. +func (*SecureValueDecryptRequest) Descriptor() ([]byte, []int) { + return file_decrypt_proto_rawDescGZIP(), []int{0} +} + +func (x *SecureValueDecryptRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *SecureValueDecryptRequest) GetNames() []string { + if x != nil { + return x.Names + } + return nil +} + +type SecureValueDecryptResponseCollection struct { + state protoimpl.MessageState `protogen:"open.v1"` + // A map of secure value names and their decrypted values. + // The value may be empty if the requestor does not have permissions to read it, or if the value does not exist. + // It will never return a 404 Not Found to avoid scanning of valid secure values. + DecryptedValues map[string]string `protobuf:"bytes,1,rep,name=decrypted_values,json=decryptedValues,proto3" json:"decrypted_values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SecureValueDecryptResponseCollection) Reset() { + *x = SecureValueDecryptResponseCollection{} + mi := &file_decrypt_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SecureValueDecryptResponseCollection) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecureValueDecryptResponseCollection) ProtoMessage() {} + +func (x *SecureValueDecryptResponseCollection) ProtoReflect() protoreflect.Message { + mi := &file_decrypt_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecureValueDecryptResponseCollection.ProtoReflect.Descriptor instead. +func (*SecureValueDecryptResponseCollection) Descriptor() ([]byte, []int) { + return file_decrypt_proto_rawDescGZIP(), []int{1} +} + +func (x *SecureValueDecryptResponseCollection) GetDecryptedValues() map[string]string { + if x != nil { + return x.DecryptedValues + } + return nil +} + +var File_decrypt_proto protoreflect.FileDescriptor + +var file_decrypt_proto_rawDesc = string([]byte{ + 0x0a, 0x0d, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x07, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x22, 0x4f, 0x0a, 0x19, 0x53, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x24, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x6d, 0x0a, 0x10, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x64, + 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0f, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x1a, 0x42, 0x0a, 0x14, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0x80, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x72, 0x12, 0x68, + 0x0a, 0x13, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x64, 0x65, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, + 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x67, + 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x2f, 0x76, 0x30, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, + 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +}) + +var ( + file_decrypt_proto_rawDescOnce sync.Once + file_decrypt_proto_rawDescData []byte +) + +func file_decrypt_proto_rawDescGZIP() []byte { + file_decrypt_proto_rawDescOnce.Do(func() { + file_decrypt_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_decrypt_proto_rawDesc), len(file_decrypt_proto_rawDesc))) + }) + return file_decrypt_proto_rawDescData +} + +var file_decrypt_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_decrypt_proto_goTypes = []any{ + (*SecureValueDecryptRequest)(nil), // 0: decrypt.SecureValueDecryptRequest + (*SecureValueDecryptResponseCollection)(nil), // 1: decrypt.SecureValueDecryptResponseCollection + nil, // 2: decrypt.SecureValueDecryptResponseCollection.DecryptedValuesEntry +} +var file_decrypt_proto_depIdxs = []int32{ + 2, // 0: decrypt.SecureValueDecryptResponseCollection.decrypted_values:type_name -> decrypt.SecureValueDecryptResponseCollection.DecryptedValuesEntry + 0, // 1: decrypt.SecureValueDecrypter.DecryptSecureValues:input_type -> decrypt.SecureValueDecryptRequest + 1, // 2: decrypt.SecureValueDecrypter.DecryptSecureValues:output_type -> decrypt.SecureValueDecryptResponseCollection + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_decrypt_proto_init() } +func file_decrypt_proto_init() { + if File_decrypt_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_decrypt_proto_rawDesc), len(file_decrypt_proto_rawDesc)), + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_decrypt_proto_goTypes, + DependencyIndexes: file_decrypt_proto_depIdxs, + MessageInfos: file_decrypt_proto_msgTypes, + }.Build() + File_decrypt_proto = out.File + file_decrypt_proto_goTypes = nil + file_decrypt_proto_depIdxs = nil +} diff --git a/pkg/apis/secret/v0alpha1/decrypt/decrypt.proto b/pkg/apis/secret/v0alpha1/decrypt/decrypt.proto new file mode 100644 index 00000000000..402ef684efd --- /dev/null +++ b/pkg/apis/secret/v0alpha1/decrypt/decrypt.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package decrypt; + +option go_package = "github.com/grafana/grafana/pkg/apis/secret/v0alpha1/decrypt"; + +message SecureValueDecryptRequest { + // The stack_id or org_id. + string namespace = 1; + + // A list of secure value names to decrypt. + repeated string names = 2; +} + +message SecureValueDecryptResponseCollection { + // A map of secure value names and their decrypted values. + // The value may be empty if the requestor does not have permissions to read it, or if the value does not exist. + // It will never return a 404 Not Found to avoid scanning of valid secure values. + map decrypted_values = 1; +} + +service SecureValueDecrypter { + // Decrypts a list of secure values and returns them as a map. + rpc DecryptSecureValues(SecureValueDecryptRequest) returns (SecureValueDecryptResponseCollection); +} diff --git a/pkg/apis/secret/v0alpha1/decrypt/decrypt_grpc.pb.go b/pkg/apis/secret/v0alpha1/decrypt/decrypt_grpc.pb.go new file mode 100644 index 00000000000..9b14a013678 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/decrypt/decrypt_grpc.pb.go @@ -0,0 +1,110 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.4.0 +// - protoc (unknown) +// source: decrypt.proto + +package decrypt + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 + +const ( + SecureValueDecrypter_DecryptSecureValues_FullMethodName = "/decrypt.SecureValueDecrypter/DecryptSecureValues" +) + +// SecureValueDecrypterClient is the client API for SecureValueDecrypter service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type SecureValueDecrypterClient interface { + // Decrypts a list of secure values and returns them as a map. + DecryptSecureValues(ctx context.Context, in *SecureValueDecryptRequest, opts ...grpc.CallOption) (*SecureValueDecryptResponseCollection, error) +} + +type secureValueDecrypterClient struct { + cc grpc.ClientConnInterface +} + +func NewSecureValueDecrypterClient(cc grpc.ClientConnInterface) SecureValueDecrypterClient { + return &secureValueDecrypterClient{cc} +} + +func (c *secureValueDecrypterClient) DecryptSecureValues(ctx context.Context, in *SecureValueDecryptRequest, opts ...grpc.CallOption) (*SecureValueDecryptResponseCollection, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SecureValueDecryptResponseCollection) + err := c.cc.Invoke(ctx, SecureValueDecrypter_DecryptSecureValues_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SecureValueDecrypterServer is the server API for SecureValueDecrypter service. +// All implementations should embed UnimplementedSecureValueDecrypterServer +// for forward compatibility +type SecureValueDecrypterServer interface { + // Decrypts a list of secure values and returns them as a map. + DecryptSecureValues(context.Context, *SecureValueDecryptRequest) (*SecureValueDecryptResponseCollection, error) +} + +// UnimplementedSecureValueDecrypterServer should be embedded to have forward compatible implementations. +type UnimplementedSecureValueDecrypterServer struct { +} + +func (UnimplementedSecureValueDecrypterServer) DecryptSecureValues(context.Context, *SecureValueDecryptRequest) (*SecureValueDecryptResponseCollection, error) { + return nil, status.Errorf(codes.Unimplemented, "method DecryptSecureValues not implemented") +} + +// UnsafeSecureValueDecrypterServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SecureValueDecrypterServer will +// result in compilation errors. +type UnsafeSecureValueDecrypterServer interface { + mustEmbedUnimplementedSecureValueDecrypterServer() +} + +func RegisterSecureValueDecrypterServer(s grpc.ServiceRegistrar, srv SecureValueDecrypterServer) { + s.RegisterService(&SecureValueDecrypter_ServiceDesc, srv) +} + +func _SecureValueDecrypter_DecryptSecureValues_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SecureValueDecryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SecureValueDecrypterServer).DecryptSecureValues(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SecureValueDecrypter_DecryptSecureValues_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SecureValueDecrypterServer).DecryptSecureValues(ctx, req.(*SecureValueDecryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// SecureValueDecrypter_ServiceDesc is the grpc.ServiceDesc for SecureValueDecrypter service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SecureValueDecrypter_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "decrypt.SecureValueDecrypter", + HandlerType: (*SecureValueDecrypterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "DecryptSecureValues", + Handler: _SecureValueDecrypter_DecryptSecureValues_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "decrypt.proto", +} diff --git a/pkg/apis/secret/v0alpha1/decrypt/go.mod b/pkg/apis/secret/v0alpha1/decrypt/go.mod new file mode 100644 index 00000000000..3a12c5c052a --- /dev/null +++ b/pkg/apis/secret/v0alpha1/decrypt/go.mod @@ -0,0 +1,18 @@ +module github.com/grafana/grafana/apis/secret/v0alpha1/decrypt + +go 1.23.5 + +require ( + google.golang.org/grpc v1.70.0 + google.golang.org/protobuf v1.36.5 +) + +require ( + github.com/google/go-cmp v0.7.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + golang.org/x/net v0.36.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect +) diff --git a/pkg/apis/secret/v0alpha1/decrypt/go.sum b/pkg/apis/secret/v0alpha1/decrypt/go.sum new file mode 100644 index 00000000000..0307d41f5ed --- /dev/null +++ b/pkg/apis/secret/v0alpha1/decrypt/go.sum @@ -0,0 +1,34 @@ +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= diff --git a/pkg/apis/secret/v0alpha1/doc.go b/pkg/apis/secret/v0alpha1/doc.go new file mode 100644 index 00000000000..f986c4ac24c --- /dev/null +++ b/pkg/apis/secret/v0alpha1/doc.go @@ -0,0 +1,6 @@ +// +k8s:deepcopy-gen=package +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta +// +groupName=secret.grafana.app + +package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" diff --git a/pkg/apis/secret/v0alpha1/exposed_secure_value.go b/pkg/apis/secret/v0alpha1/exposed_secure_value.go new file mode 100644 index 00000000000..1f77cca2112 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/exposed_secure_value.go @@ -0,0 +1,66 @@ +package v0alpha1 + +import ( + "encoding/json" + "fmt" + "strconv" + + "gopkg.in/yaml.v3" +) + +const redacted = "[REDACTED]" + +// ExposedSecureValue contains the raw decrypted secure value. +type ExposedSecureValue string + +var ( + _ fmt.Stringer = (*ExposedSecureValue)(nil) + _ fmt.Formatter = (*ExposedSecureValue)(nil) + _ fmt.GoStringer = (*ExposedSecureValue)(nil) + _ json.Marshaler = (*ExposedSecureValue)(nil) + _ yaml.Marshaler = (*ExposedSecureValue)(nil) +) + +// NewExposedSecureValue creates a new exposed secure value wrapper. +func NewExposedSecureValue(v string) ExposedSecureValue { + return ExposedSecureValue(v) +} + +// DangerouslyExposeAndConsumeValue will move the decrypted secure value out of the wrapper and return it. +// Further attempts to call this method will panic. +// The function name is intentionally kept long and weird because this is a dangerous operation and should be used carefully! +func (s *ExposedSecureValue) DangerouslyExposeAndConsumeValue() string { + if *s == "" { + panic("underlying value is empty or was consumed") + } + + tmp := *s + *s = "" + + return string(tmp) +} + +// String must not return the exposed secure value. +func (s ExposedSecureValue) String() string { + return redacted +} + +// Format must not return the exposed secure value. +func (s ExposedSecureValue) Format(f fmt.State, _verb rune) { + _, _ = fmt.Fprint(f, redacted) +} + +// GoString must not return the exposed secure value. +func (s ExposedSecureValue) GoString() string { + return redacted +} + +// MarshalJSON must not return the exposed secure value. +func (s ExposedSecureValue) MarshalJSON() ([]byte, error) { + return []byte(strconv.Quote(redacted)), nil +} + +// MarshalYAML must not return the exposed secure value. +func (s ExposedSecureValue) MarshalYAML() (any, error) { + return redacted, nil +} diff --git a/pkg/apis/secret/v0alpha1/exposed_secure_value_test.go b/pkg/apis/secret/v0alpha1/exposed_secure_value_test.go new file mode 100644 index 00000000000..1d21e0505bc --- /dev/null +++ b/pkg/apis/secret/v0alpha1/exposed_secure_value_test.go @@ -0,0 +1,48 @@ +package v0alpha1_test + +import ( + "bytes" + "encoding/json" + "fmt" + "testing" + + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +func TestExposedSecureValue(t *testing.T) { + expected := "[REDACTED]" + + rawValue := "a-password" + esv := v0alpha1.NewExposedSecureValue(rawValue) + + // String must not return the exposed secure value. + require.Equal(t, expected, esv.String()) + + // Format/GoString must not return the exposed secure value. + require.Equal(t, expected, fmt.Sprintf("%+#v", esv)) + require.Equal(t, expected, fmt.Sprintf("%v", esv)) + require.Equal(t, expected, fmt.Sprintf("%s", esv)) + + buf := new(bytes.Buffer) + _, err := fmt.Fprintf(buf, "%#v", esv) + require.NoError(t, err) + require.Equal(t, expected, buf.String()) + + // MarshalJSON must not return the exposed secure value. + bytes, err := json.Marshal(esv) + require.NoError(t, err) + require.Equal(t, `"`+expected+`"`, string(bytes)) + + // MarshalYAML must not return the exposed secure value. + bytes, err = yaml.Marshal(esv) + require.NoError(t, err) + require.Equal(t, "'"+expected+"'\n", string(bytes)) + + // DangerouslyExposeAndConsumeValue returns the raw value. + require.Equal(t, rawValue, esv.DangerouslyExposeAndConsumeValue()) + + // Further calls to DangerouslyExposeAndConsumeValue will panic. + require.Panics(t, func() { esv.DangerouslyExposeAndConsumeValue() }) +} diff --git a/pkg/apis/secret/v0alpha1/keeper.go b/pkg/apis/secret/v0alpha1/keeper.go new file mode 100644 index 00000000000..d45e481db3a --- /dev/null +++ b/pkg/apis/secret/v0alpha1/keeper.go @@ -0,0 +1,145 @@ +package v0alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type Keeper struct { + metav1.TypeMeta `json:",inline"` + + // Standard object's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // This is the actual keeper schema. + // +patchStrategy=replace + // +patchMergeKey=name + Spec KeeperSpec `json:"spec,omitempty" patchStrategy:"replace" patchMergeKey:"name"` +} + +func (k *Keeper) IsSqlKeeper() bool { + return k.Spec.SQL != nil && k.Spec.SQL.Encryption != nil +} + +type KeeperConfig interface { + Type() string +} + +type KeeperSpec struct { + // Human friendly name for the keeper. + Title string `json:"title"` + + // You can only chose one of the following. + SQL *SQLKeeperConfig `json:"sql,omitempty"` + AWS *AWSKeeperConfig `json:"aws,omitempty"` + Azure *AzureKeeperConfig `json:"azurekeyvault,omitempty"` + GCP *GCPKeeperConfig `json:"gcp,omitempty"` + HashiCorp *HashiCorpKeeperConfig `json:"hashivault,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type KeeperList struct { + metav1.TypeMeta `json:",inline"` + + // Standard list's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + // Slice containing all keepers. + Items []Keeper `json:"items,omitempty"` +} + +// The default SQL keeper. +type SQLKeeperConfig struct { + Encryption *Encryption `json:"encryption,omitempty"` +} + +func (s *SQLKeeperConfig) Type() string { + return "sql" +} + +// Encryption of default SQL keeper. +type Encryption struct { + Envelope *Envelope `json:"envelope,omitempty"` // TODO: what would this be + + AWS *AWSCredentials `json:"aws,omitempty"` + Azure *AzureCredentials `json:"azure,omitempty"` + GCP *GCPCredentials `json:"gcp,omitempty"` + HashiCorp *HashiCorpCredentials `json:"hashicorp,omitempty"` +} + +// Credentials of remote keepers. +type AWSCredentials struct { + AccessKeyID CredentialValue `json:"accessKeyId"` + SecretAccessKey CredentialValue `json:"secretAccessKey"` + KMSKeyID string `json:"kmsKeyId,omitempty"` +} + +type AzureCredentials struct { + KeyVaultName string `json:"keyVaultName"` + TenantID string `json:"tenantId"` + ClientID string `json:"clientId"` + ClientSecret CredentialValue `json:"clientSecret"` +} + +type GCPCredentials struct { + ProjectID string `json:"projectId"` + CredentialsFile string `json:"credentialsFile"` +} + +type HashiCorpCredentials struct { + Address string `json:"address"` + Token CredentialValue `json:"token"` +} + +// Envelope encrytion details. +type Envelope struct{} + +// Holds the way credentials are obtained. +type CredentialValue struct { + // The name of the secure value that holds the actual value. + SecureValueName string `json:"secureValueName,omitempty"` + + // The value is taken from the environment variable. + ValueFromEnv string `json:"valueFromEnv,omitempty"` + + // The value is taken from the Grafana config file. + // TODO: how do we explain that this is a path to the config file? + ValueFromConfig string `json:"valueFromConfig,omitempty"` +} + +// Remote Keepers. +type AWSKeeperConfig struct { + AWSCredentials `json:",inline"` +} + +type AzureKeeperConfig struct { + AzureCredentials `json:",inline"` +} + +type GCPKeeperConfig struct { + GCPCredentials `json:",inline"` +} + +type HashiCorpKeeperConfig struct { + HashiCorpCredentials `json:",inline"` +} + +func (s *AWSKeeperConfig) Type() string { + return "aws" +} + +func (s *AzureKeeperConfig) Type() string { + return "azure" +} + +func (s *GCPKeeperConfig) Type() string { + return "gcp" +} + +func (s *HashiCorpKeeperConfig) Type() string { + return "hashicorp" +} diff --git a/pkg/apis/secret/v0alpha1/register.go b/pkg/apis/secret/v0alpha1/register.go new file mode 100644 index 00000000000..e2d7c065487 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/register.go @@ -0,0 +1,131 @@ +package v0alpha1 + +import ( + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/registry/generic" + + "github.com/grafana/grafana/pkg/apimachinery/utils" +) + +const ( + GROUP = "secret.grafana.app" + VERSION = "v0alpha1" +) + +// SecureValuesResourceInfo is used when registering the API service. +var SecureValuesResourceInfo = utils.NewResourceInfo( + GROUP, + VERSION, + "securevalues", // resource name (e.g. `kubectl get securevalues`). + "securevalue", // singular name. Used when creating a resource (e.g. `securevalue-xxx`). + "SecureValue", // kind. + func() runtime.Object { return &SecureValue{} }, // constructor for single object. This is used by the rest storage layer `Create` method. + func() runtime.Object { return &SecureValueList{} }, // constructor for list object. This is used by the rest storage layer `List` method. + utils.TableColumns{ + // This defines the fields we view in `kubectl get`. Not related with the storage layer. + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Format: "string", Description: "The display name of the secure value"}, + {Name: "Keeper", Type: "string", Format: "string", Description: "Storage of the secure value"}, + {Name: "Ref", Type: "string", Format: "string", Description: "If present, the reference to a secret"}, + {Name: "Status", Type: "string", Format: "string", Description: "The status of the secure value"}, + }, + // Decodes the object into a concrete type. Return order in the slice must be the same as in `Definition`. + Reader: func(obj any) ([]interface{}, error) { + r, ok := obj.(*SecureValue) + if ok { + return []interface{}{ + r.Name, + r.Spec.Title, + r.Spec.Keeper, + r.Spec.Ref, + r.Status.Phase, + }, nil + } + + return nil, fmt.Errorf("expected SecureValue but got %T", obj) + }, + }, +) + +var KeeperResourceInfo = utils.NewResourceInfo( + GROUP, + VERSION, + "keepers", // resource name (e.g. `kubectl get keepers`). + "keeper", // singular name. Used when creating a resource (e.g. `keeper-xxx`). + "Keeper", // kind. + func() runtime.Object { return &Keeper{} }, // constructor for single object. This is used by the rest storage layer `Create` method. + func() runtime.Object { return &KeeperList{} }, // constructor for list object. This is used by the rest storage layer `List` method. + utils.TableColumns{ + // This defines the fields we view in `kubectl get`. Not related with the storage layer. + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Format: "string", Description: "The display name of the keeper"}, + }, + // Decodes the object into a concrete type. Return order in the slice must be the same as in `Definition`. + Reader: func(obj any) ([]interface{}, error) { + r, ok := obj.(*Keeper) + if ok { + return []interface{}{ + r.Name, + r.Spec.Title, + }, nil + } + + return nil, fmt.Errorf("expected Keeper but got %T", obj) + }, + }, +) + +var ( + // SchemeGroupVersion is group version used to register these objects. + SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION} + + // SchemaBuilder is used by standard codegen, this is not used in the code otherwise. + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the status phase to the selectable fields, besides the generic metadata name and namespace. +func SelectableSecureValueFields(obj *SecureValue) fields.Set { + return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{ + "status.phase": string(obj.Status.Phase), + }) +} + +// Adds the list of known types to the given scheme. +func AddKnownTypes(scheme *runtime.Scheme, version string) error { + // TODO: do we need a type for the secure value decrypt? + // Since it is a subresource, it could be interesting to not use `SecureValue`, but rather something distinct like `DecryptedSecureValue`? + scheme.AddKnownTypes( + schema.GroupVersion{Group: GROUP, Version: version}, + &SecureValue{}, + &SecureValueList{}, + &Keeper{}, + &KeeperList{}, + // &secretV0.SecureValueActivityList{}, + ) + + err := scheme.AddFieldLabelConversionFunc( + SecureValuesResourceInfo.GroupVersionKind(), + func(label, value string) (string, string, error) { + fieldSet := SelectableSecureValueFields(&SecureValue{}) + for key := range fieldSet { + if label == key { + return label, value, nil + } + } + return "", "", fmt.Errorf("field label not supported for %s: %s", SecureValuesResourceInfo.GroupVersionKind(), label) + }, + ) + if err != nil { + return err + } + return nil +} diff --git a/pkg/apis/secret/v0alpha1/secure_value.go b/pkg/apis/secret/v0alpha1/secure_value.go new file mode 100644 index 00000000000..9e476f298a7 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/secure_value.go @@ -0,0 +1,91 @@ +package v0alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type SecureValue struct { + metav1.TypeMeta `json:",inline"` + + // Standard object's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // This is the actual secure value schema. + Spec SecureValueSpec `json:"spec,omitempty"` + + // Read-only observed status of the `SecureValue`. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + Status SecureValueStatus `json:"status"` +} + +// +enum +type SecureValuePhase string + +const ( + // When the `SecureValue` is created, it will start in `Pending` phase to create the underlying secret asynchronously. + SecureValuePhasePending SecureValuePhase = "Pending" + + // If the creation of the secret is successful, it will move to the `Succeeded` phase. + SecureValuePhaseSucceeded SecureValuePhase = "Succeeded" + + // If the creation of the secret fails, it will move to the `Failed` phase. + // Check the additional `status` fields for more information on what caused the failure. + // This state is unrecoverable. + SecureValuePhaseFailed SecureValuePhase = "Failed" +) + +type SecureValueStatus struct { + // High-level summary of where the `SecureValue` is in its lifecycle. + // One of: `Pending`, `Succeeded` or `Failed`. + Phase SecureValuePhase `json:"phase"` + + // A human readable message indicating details about why the `SecureValue` is in this phase. + // Only applicable if the `phase=Failed`. + // +optional + Message string `json:"message,omitempty"` +} + +type SecureValueSpec struct { + // Human friendly name for the secure value. + Title string `json:"title"` + + // The raw value is only valid for write. Read/List will always be empty. + // There is no support for mixing `value` and `ref`, you can't create a secret in a third-party keeper with a specified `ref`. + Value ExposedSecureValue `json:"value,omitempty"` + + // When using a remote Key manager, the ref is used to reference a value inside the remote storage. + // This should not contain sensitive information. + Ref string `json:"ref,omitempty"` + + // Name of the keeper, being the actual storage of the secure value. + Keeper string `json:"keeper,omitempty"` + + // The Decrypters that are allowed to decrypt this secret. + // An empty list means no service can decrypt it. + // Support and behavior is still TBD, but could likely look like: + // * testdata.grafana.app/{name1} + // * testdata.grafana.app/{name2} + // * runner.k6.grafana.app/* -- allow any k6 test runner + // Rather than a string pattern, we may want a more explicit object: + // [{ group:"testdata.grafana.app", name="name1"}, + // { group:"runner.k6.grafana.app"}] + // +listType=atomic + // +optional + Decrypters []string `json:"decrypters"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type SecureValueList struct { + metav1.TypeMeta `json:",inline"` + + // Standard list's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + // Slice containing all secure values. This will NOT output decrypted values. + Items []SecureValue `json:"items,omitempty"` +} diff --git a/pkg/apis/secret/v0alpha1/zz_generated.deepcopy.go b/pkg/apis/secret/v0alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..96491535452 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/zz_generated.deepcopy.go @@ -0,0 +1,441 @@ +//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 *AWSCredentials) DeepCopyInto(out *AWSCredentials) { + *out = *in + out.AccessKeyID = in.AccessKeyID + out.SecretAccessKey = in.SecretAccessKey + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSCredentials. +func (in *AWSCredentials) DeepCopy() *AWSCredentials { + if in == nil { + return nil + } + out := new(AWSCredentials) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSKeeperConfig) DeepCopyInto(out *AWSKeeperConfig) { + *out = *in + out.AWSCredentials = in.AWSCredentials + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSKeeperConfig. +func (in *AWSKeeperConfig) DeepCopy() *AWSKeeperConfig { + if in == nil { + return nil + } + out := new(AWSKeeperConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureCredentials) DeepCopyInto(out *AzureCredentials) { + *out = *in + out.ClientSecret = in.ClientSecret + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureCredentials. +func (in *AzureCredentials) DeepCopy() *AzureCredentials { + if in == nil { + return nil + } + out := new(AzureCredentials) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureKeeperConfig) DeepCopyInto(out *AzureKeeperConfig) { + *out = *in + out.AzureCredentials = in.AzureCredentials + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureKeeperConfig. +func (in *AzureKeeperConfig) DeepCopy() *AzureKeeperConfig { + if in == nil { + return nil + } + out := new(AzureKeeperConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialValue) DeepCopyInto(out *CredentialValue) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialValue. +func (in *CredentialValue) DeepCopy() *CredentialValue { + if in == nil { + return nil + } + out := new(CredentialValue) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Encryption) DeepCopyInto(out *Encryption) { + *out = *in + if in.Envelope != nil { + in, out := &in.Envelope, &out.Envelope + *out = new(Envelope) + **out = **in + } + if in.AWS != nil { + in, out := &in.AWS, &out.AWS + *out = new(AWSCredentials) + **out = **in + } + if in.Azure != nil { + in, out := &in.Azure, &out.Azure + *out = new(AzureCredentials) + **out = **in + } + if in.GCP != nil { + in, out := &in.GCP, &out.GCP + *out = new(GCPCredentials) + **out = **in + } + if in.HashiCorp != nil { + in, out := &in.HashiCorp, &out.HashiCorp + *out = new(HashiCorpCredentials) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Encryption. +func (in *Encryption) DeepCopy() *Encryption { + if in == nil { + return nil + } + out := new(Encryption) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Envelope) DeepCopyInto(out *Envelope) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Envelope. +func (in *Envelope) DeepCopy() *Envelope { + if in == nil { + return nil + } + out := new(Envelope) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GCPCredentials) DeepCopyInto(out *GCPCredentials) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GCPCredentials. +func (in *GCPCredentials) DeepCopy() *GCPCredentials { + if in == nil { + return nil + } + out := new(GCPCredentials) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GCPKeeperConfig) DeepCopyInto(out *GCPKeeperConfig) { + *out = *in + out.GCPCredentials = in.GCPCredentials + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GCPKeeperConfig. +func (in *GCPKeeperConfig) DeepCopy() *GCPKeeperConfig { + if in == nil { + return nil + } + out := new(GCPKeeperConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HashiCorpCredentials) DeepCopyInto(out *HashiCorpCredentials) { + *out = *in + out.Token = in.Token + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashiCorpCredentials. +func (in *HashiCorpCredentials) DeepCopy() *HashiCorpCredentials { + if in == nil { + return nil + } + out := new(HashiCorpCredentials) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HashiCorpKeeperConfig) DeepCopyInto(out *HashiCorpKeeperConfig) { + *out = *in + out.HashiCorpCredentials = in.HashiCorpCredentials + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashiCorpKeeperConfig. +func (in *HashiCorpKeeperConfig) DeepCopy() *HashiCorpKeeperConfig { + if in == nil { + return nil + } + out := new(HashiCorpKeeperConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Keeper) DeepCopyInto(out *Keeper) { + *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 Keeper. +func (in *Keeper) DeepCopy() *Keeper { + if in == nil { + return nil + } + out := new(Keeper) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Keeper) 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 *KeeperList) DeepCopyInto(out *KeeperList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Keeper, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeeperList. +func (in *KeeperList) DeepCopy() *KeeperList { + if in == nil { + return nil + } + out := new(KeeperList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KeeperList) 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 *KeeperSpec) DeepCopyInto(out *KeeperSpec) { + *out = *in + if in.SQL != nil { + in, out := &in.SQL, &out.SQL + *out = new(SQLKeeperConfig) + (*in).DeepCopyInto(*out) + } + if in.AWS != nil { + in, out := &in.AWS, &out.AWS + *out = new(AWSKeeperConfig) + **out = **in + } + if in.Azure != nil { + in, out := &in.Azure, &out.Azure + *out = new(AzureKeeperConfig) + **out = **in + } + if in.GCP != nil { + in, out := &in.GCP, &out.GCP + *out = new(GCPKeeperConfig) + **out = **in + } + if in.HashiCorp != nil { + in, out := &in.HashiCorp, &out.HashiCorp + *out = new(HashiCorpKeeperConfig) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeeperSpec. +func (in *KeeperSpec) DeepCopy() *KeeperSpec { + if in == nil { + return nil + } + out := new(KeeperSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SQLKeeperConfig) DeepCopyInto(out *SQLKeeperConfig) { + *out = *in + if in.Encryption != nil { + in, out := &in.Encryption, &out.Encryption + *out = new(Encryption) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLKeeperConfig. +func (in *SQLKeeperConfig) DeepCopy() *SQLKeeperConfig { + if in == nil { + return nil + } + out := new(SQLKeeperConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecureValue) DeepCopyInto(out *SecureValue) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecureValue. +func (in *SecureValue) DeepCopy() *SecureValue { + if in == nil { + return nil + } + out := new(SecureValue) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SecureValue) 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 *SecureValueList) DeepCopyInto(out *SecureValueList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SecureValue, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecureValueList. +func (in *SecureValueList) DeepCopy() *SecureValueList { + if in == nil { + return nil + } + out := new(SecureValueList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SecureValueList) 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 *SecureValueSpec) DeepCopyInto(out *SecureValueSpec) { + *out = *in + if in.Decrypters != nil { + in, out := &in.Decrypters, &out.Decrypters + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecureValueSpec. +func (in *SecureValueSpec) DeepCopy() *SecureValueSpec { + if in == nil { + return nil + } + out := new(SecureValueSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecureValueStatus) DeepCopyInto(out *SecureValueStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecureValueStatus. +func (in *SecureValueStatus) DeepCopy() *SecureValueStatus { + if in == nil { + return nil + } + out := new(SecureValueStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/secret/v0alpha1/zz_generated.defaults.go b/pkg/apis/secret/v0alpha1/zz_generated.defaults.go new file mode 100644 index 00000000000..238fc2f4edc --- /dev/null +++ b/pkg/apis/secret/v0alpha1/zz_generated.defaults.go @@ -0,0 +1,19 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by defaulter-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// RegisterDefaults adds defaulters functions to the given scheme. +// Public to allow building arbitrary schemes. +// All generated defaulters are covering - they call all nested defaulters. +func RegisterDefaults(scheme *runtime.Scheme) error { + return nil +} diff --git a/pkg/apis/secret/v0alpha1/zz_generated.openapi.go b/pkg/apis/secret/v0alpha1/zz_generated.openapi.go new file mode 100644 index 00000000000..dab5ab27215 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/zz_generated.openapi.go @@ -0,0 +1,740 @@ +//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/secret/v0alpha1.AWSCredentials": schema_pkg_apis_secret_v0alpha1_AWSCredentials(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AWSKeeperConfig": schema_pkg_apis_secret_v0alpha1_AWSKeeperConfig(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AzureCredentials": schema_pkg_apis_secret_v0alpha1_AzureCredentials(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AzureKeeperConfig": schema_pkg_apis_secret_v0alpha1_AzureKeeperConfig(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue": schema_pkg_apis_secret_v0alpha1_CredentialValue(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Encryption": schema_pkg_apis_secret_v0alpha1_Encryption(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Envelope": schema_pkg_apis_secret_v0alpha1_Envelope(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.GCPCredentials": schema_pkg_apis_secret_v0alpha1_GCPCredentials(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.GCPKeeperConfig": schema_pkg_apis_secret_v0alpha1_GCPKeeperConfig(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.HashiCorpCredentials": schema_pkg_apis_secret_v0alpha1_HashiCorpCredentials(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.HashiCorpKeeperConfig": schema_pkg_apis_secret_v0alpha1_HashiCorpKeeperConfig(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Keeper": schema_pkg_apis_secret_v0alpha1_Keeper(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.KeeperList": schema_pkg_apis_secret_v0alpha1_KeeperList(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.KeeperSpec": schema_pkg_apis_secret_v0alpha1_KeeperSpec(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SQLKeeperConfig": schema_pkg_apis_secret_v0alpha1_SQLKeeperConfig(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValue": schema_pkg_apis_secret_v0alpha1_SecureValue(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValueList": schema_pkg_apis_secret_v0alpha1_SecureValueList(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValueSpec": schema_pkg_apis_secret_v0alpha1_SecureValueSpec(ref), + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValueStatus": schema_pkg_apis_secret_v0alpha1_SecureValueStatus(ref), + } +} + +func schema_pkg_apis_secret_v0alpha1_AWSCredentials(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Credentials of remote keepers.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "accessKeyId": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + "secretAccessKey": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + "kmsKeyId": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"accessKeyId", "secretAccessKey"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_AWSKeeperConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Remote Keepers.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "accessKeyId": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + "secretAccessKey": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + "kmsKeyId": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"accessKeyId", "secretAccessKey"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_AzureCredentials(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "keyVaultName": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "tenantId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "clientId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "clientSecret": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + }, + Required: []string{"keyVaultName", "tenantId", "clientId", "clientSecret"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_AzureKeeperConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "keyVaultName": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "tenantId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "clientId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "clientSecret": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + }, + Required: []string{"keyVaultName", "tenantId", "clientId", "clientSecret"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_CredentialValue(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Holds the way credentials are obtained.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "secureValueName": { + SchemaProps: spec.SchemaProps{ + Description: "The name of the secure value that holds the actual value.", + Type: []string{"string"}, + Format: "", + }, + }, + "valueFromEnv": { + SchemaProps: spec.SchemaProps{ + Description: "The value is taken from the environment variable.", + Type: []string{"string"}, + Format: "", + }, + }, + "valueFromConfig": { + SchemaProps: spec.SchemaProps{ + Description: "The value is taken from the Grafana config file.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_secret_v0alpha1_Encryption(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Encryption of default SQL keeper.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "envelope": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Envelope"), + }, + }, + "aws": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AWSCredentials"), + }, + }, + "azure": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AzureCredentials"), + }, + }, + "gcp": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.GCPCredentials"), + }, + }, + "hashicorp": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.HashiCorpCredentials"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AWSCredentials", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AzureCredentials", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Envelope", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.GCPCredentials", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.HashiCorpCredentials"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_Envelope(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Envelope encrytion details.", + Type: []string{"object"}, + }, + }, + } +} + +func schema_pkg_apis_secret_v0alpha1_GCPCredentials(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "projectId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "credentialsFile": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"projectId", "credentialsFile"}, + }, + }, + } +} + +func schema_pkg_apis_secret_v0alpha1_GCPKeeperConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "projectId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "credentialsFile": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"projectId", "credentialsFile"}, + }, + }, + } +} + +func schema_pkg_apis_secret_v0alpha1_HashiCorpCredentials(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "address": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "token": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + }, + Required: []string{"address", "token"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_HashiCorpKeeperConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "address": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "token": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"), + }, + }, + }, + Required: []string{"address", "token"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.CredentialValue"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_Keeper(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{ + Description: "Standard object's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "replace", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "This is the actual keeper schema.", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.KeeperSpec"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.KeeperSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_KeeperList(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{ + Description: "Standard list's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "Slice containing all keepers.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Keeper"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Keeper", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_KeeperSpec(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{ + Description: "Human friendly name for the keeper.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "sql": { + SchemaProps: spec.SchemaProps{ + Description: "You can only chose one of the following.", + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SQLKeeperConfig"), + }, + }, + "aws": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AWSKeeperConfig"), + }, + }, + "azurekeyvault": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AzureKeeperConfig"), + }, + }, + "gcp": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.GCPKeeperConfig"), + }, + }, + "hashivault": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.HashiCorpKeeperConfig"), + }, + }, + }, + Required: []string{"title"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AWSKeeperConfig", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.AzureKeeperConfig", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.GCPKeeperConfig", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.HashiCorpKeeperConfig", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SQLKeeperConfig"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_SQLKeeperConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "The default SQL keeper.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "encryption": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Encryption"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.Encryption"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_SecureValue(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{ + Description: "Standard object's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "This is the actual secure value schema.", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValueSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Description: "Read-only observed status of the `SecureValue`. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValueStatus"), + }, + }, + }, + Required: []string{"status"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValueSpec", "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValueStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_SecureValueList(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{ + Description: "Standard list's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "Slice containing all secure values. This will NOT output decrypted values.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValue"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/secret/v0alpha1.SecureValue", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_secret_v0alpha1_SecureValueSpec(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{ + Description: "Human friendly name for the secure value.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Description: "The raw value is only valid for write. Read/List will always be empty. There is no support for mixing `value` and `ref`, you can't create a secret in a third-party keeper with a specified `ref`.", + Type: []string{"string"}, + Format: "", + }, + }, + "ref": { + SchemaProps: spec.SchemaProps{ + Description: "When using a remote Key manager, the ref is used to reference a value inside the remote storage. This should not contain sensitive information.", + Type: []string{"string"}, + Format: "", + }, + }, + "keeper": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the keeper, being the actual storage of the secure value.", + Type: []string{"string"}, + Format: "", + }, + }, + "decrypters": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "The Decrypters that are allowed to decrypt this secret. An empty list means no service can decrypt it. Support and behavior is still TBD, but could likely look like: * testdata.grafana.app/{name1} * testdata.grafana.app/{name2} * runner.k6.grafana.app/* -- allow any k6 test runner Rather than a string pattern, we may want a more explicit object: [{ group:\"testdata.grafana.app\", name=\"name1\"},\n { group:\"runner.k6.grafana.app\"}]", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"title"}, + }, + }, + } +} + +func schema_pkg_apis_secret_v0alpha1_SecureValueStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "phase": { + SchemaProps: spec.SchemaProps{ + Description: "High-level summary of where the `SecureValue` is in its lifecycle. One of: `Pending`, `Succeeded` or `Failed`.\n\nPossible enum values:\n - `\"Failed\"` If the creation of the secret fails, it will move to the `Failed` phase. Check the additional `status` fields for more information on what caused the failure. This state is unrecoverable.\n - `\"Pending\"` When the `SecureValue` is created, it will start in `Pending` phase to create the underlying secret asynchronously.\n - `\"Succeeded\"` If the creation of the secret is successful, it will move to the `Succeeded` phase.", + Default: "", + Type: []string{"string"}, + Format: "", + Enum: []interface{}{"Failed", "Pending", "Succeeded"}, + }, + }, + "message": { + SchemaProps: spec.SchemaProps{ + Description: "A human readable message indicating details about why the `SecureValue` is in this phase. Only applicable if the `phase=Failed`.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"phase"}, + }, + }, + } +} diff --git a/pkg/apis/secret/v0alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/secret/v0alpha1/zz_generated.openapi_violation_exceptions.list new file mode 100644 index 00000000000..48af67bb3b5 --- /dev/null +++ b/pkg/apis/secret/v0alpha1/zz_generated.openapi_violation_exceptions.list @@ -0,0 +1,8 @@ +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,AWSCredentials,AccessKeyID +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,AWSCredentials,KMSKeyID +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,AzureCredentials,ClientID +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,AzureCredentials,TenantID +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,Encryption,HashiCorp +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,GCPCredentials,ProjectID +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,KeeperSpec,Azure +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,KeeperSpec,HashiCorp