feat: add hello world subresource (#96425)
This adds the infrastructure we need for a basic subresource.
This commit is contained in:
1 parent
6e408f19fa
commit
f2ab3dfa18
6 files changed
+149
-1
No files matched your search
@@ -85,6 +85,7 @@ func AddKnownTypes(gv schema.GroupVersion, scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(gv,
|
||||
&Repository{},
|
||||
&RepositoryList{},
|
||||
&HelloWorld{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -109,3 +109,10 @@ type RepositoryList struct {
|
||||
|
||||
Items []Repository `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type HelloWorld struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
Whom string `json:"whom,omitempty"`
|
||||
}
|
||||
@@ -27,6 +27,31 @@ func (in *GitHubRepository) DeepCopy() *GitHubRepository {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelloWorld) DeepCopyInto(out *HelloWorld) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelloWorld.
|
||||
func (in *HelloWorld) DeepCopy() *HelloWorld {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelloWorld)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *HelloWorld) 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 *LocalRepository) DeepCopyInto(out *LocalRepository) {
|
||||
*out = *in
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||
return map[string]common.OpenAPIDefinition{
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepository": schema_pkg_apis_provisioning_v0alpha1_GitHubRepository(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.HelloWorld": schema_pkg_apis_provisioning_v0alpha1_HelloWorld(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepository": schema_pkg_apis_provisioning_v0alpha1_LocalRepository(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.Repository": schema_pkg_apis_provisioning_v0alpha1_Repository(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.RepositoryList": schema_pkg_apis_provisioning_v0alpha1_RepositoryList(ref),
|
||||
@@ -63,6 +64,38 @@ func schema_pkg_apis_provisioning_v0alpha1_GitHubRepository(ref common.Reference
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_provisioning_v0alpha1_HelloWorld(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: "",
|
||||
},
|
||||
},
|
||||
"whom": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_provisioning_v0alpha1_LocalRepository(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package provisioning
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
)
|
||||
|
||||
type helloWorldSubresource struct{}
|
||||
|
||||
func (*helloWorldSubresource) New() runtime.Object {
|
||||
// This is added as the "ResponseType" regardless what ProducesObject() returns
|
||||
return &v0alpha1.HelloWorld{}
|
||||
}
|
||||
|
||||
func (*helloWorldSubresource) Destroy() {}
|
||||
|
||||
func (*helloWorldSubresource) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (*helloWorldSubresource) GetSingularName() string {
|
||||
return "HelloWorld"
|
||||
}
|
||||
|
||||
func (*helloWorldSubresource) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"}
|
||||
}
|
||||
|
||||
func (*helloWorldSubresource) ProducesObject(verb string) any {
|
||||
return &v0alpha1.HelloWorld{}
|
||||
}
|
||||
|
||||
func (*helloWorldSubresource) ConnectMethods() []string {
|
||||
return []string{http.MethodGet}
|
||||
}
|
||||
|
||||
func (*helloWorldSubresource) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
return nil, false, ""
|
||||
}
|
||||
|
||||
func (*helloWorldSubresource) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
whom := r.URL.Query().Get("whom")
|
||||
if whom == "" {
|
||||
whom = "World"
|
||||
}
|
||||
|
||||
responder.Object(http.StatusTeapot, &v0alpha1.HelloWorld{Whom: whom})
|
||||
}), nil
|
||||
}
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*helloWorldSubresource)(nil)
|
||||
_ rest.Connecter = (*helloWorldSubresource)(nil)
|
||||
_ rest.Scoper = (*helloWorldSubresource)(nil)
|
||||
_ rest.SingularNameProvider = (*helloWorldSubresource)(nil)
|
||||
_ rest.StorageMetadata = (*helloWorldSubresource)(nil)
|
||||
)
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
var _ builder.APIGroupBuilder = (*ProvisioningAPIBuilder)(nil)
|
||||
@@ -69,8 +70,11 @@ func (b *ProvisioningAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserv
|
||||
return fmt.Errorf("failed to create repository storage: %w", err)
|
||||
}
|
||||
|
||||
helloWorld := &helloWorldSubresource{}
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
storage[v0alpha1.RepositoryResourceInfo.StoragePath()] = repositoryStorage
|
||||
storage[v0alpha1.RepositoryResourceInfo.StoragePath("hello")] = helloWorld
|
||||
apiGroupInfo.VersionedResourcesStorageMap[v0alpha1.VERSION] = storage
|
||||
return nil
|
||||
}
|
||||
@@ -89,9 +93,25 @@ func (b *ProvisioningAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.
|
||||
|
||||
root := "/apis/" + b.GetGroupVersion().String() + "/"
|
||||
// TODO: we might want to register some extras for subresources here.
|
||||
sub := oas.Paths.Paths[root+"namespaces/{namespace}/repositories/{name}/hello"]
|
||||
if sub != nil && sub.Get != nil {
|
||||
sub.Get.Description = "Get a nice hello :)"
|
||||
sub.Get.Parameters = []*spec3.Parameter{
|
||||
{
|
||||
ParameterProps: spec3.ParameterProps{
|
||||
Name: "whom",
|
||||
In: "query",
|
||||
Example: "World!",
|
||||
Description: "Who should get the nice greeting?",
|
||||
Schema: spec.StringProperty(),
|
||||
Required: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// The root API discovery list
|
||||
sub := oas.Paths.Paths[root]
|
||||
sub = oas.Paths.Paths[root]
|
||||
if sub != nil && sub.Get != nil {
|
||||
sub.Get.Tags = []string{"API Discovery"} // sorts first in the list
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user