diff --git a/client/cluster/v1/zz_generated_cluster.go b/client/cluster/v1/zz_generated_cluster.go index ce097ec5..b0efa95d 100644 --- a/client/cluster/v1/zz_generated_cluster.go +++ b/client/cluster/v1/zz_generated_cluster.go @@ -5,21 +5,35 @@ import ( ) const ( - ClusterType = "cluster" - ClusterFieldAPIVersion = "apiVersion" - ClusterFieldKind = "kind" - ClusterFieldObjectMeta = "objectMeta" - ClusterFieldSpec = "spec" - ClusterFieldStatus = "status" + ClusterType = "cluster" + ClusterFieldAKSConfig = "aksConfig" + ClusterFieldAPIVersion = "apiVersion" + ClusterFieldAnnotations = "annotations" + ClusterFieldCreated = "created" + ClusterFieldGKEConfig = "gkeConfig" + ClusterFieldKind = "kind" + ClusterFieldLabels = "labels" + ClusterFieldName = "name" + ClusterFieldNamespace = "namespace" + ClusterFieldRKEConfig = "rkeConfig" + ClusterFieldRemoved = "removed" + ClusterFieldUuid = "uuid" ) type Cluster struct { types.Resource - APIVersion string `json:"apiVersion,omitempty"` - Kind string `json:"kind,omitempty"` - ObjectMeta ObjectMeta `json:"objectMeta,omitempty"` - Spec ClusterSpec `json:"spec,omitempty"` - Status *ClusterStatus `json:"status,omitempty"` + AKSConfig *AKSConfig `json:"aksConfig,omitempty"` + APIVersion string `json:"apiVersion,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + Created string `json:"created,omitempty"` + GKEConfig *GKEConfig `json:"gkeConfig,omitempty"` + Kind string `json:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` + RKEConfig *RKEConfig `json:"rkeConfig,omitempty"` + Removed string `json:"removed,omitempty"` + Uuid string `json:"uuid,omitempty"` } type ClusterCollection struct { types.Collection diff --git a/client/cluster/v1/zz_generated_cluster_node.go b/client/cluster/v1/zz_generated_cluster_node.go index bd62cd45..e749042e 100644 --- a/client/cluster/v1/zz_generated_cluster_node.go +++ b/client/cluster/v1/zz_generated_cluster_node.go @@ -5,21 +5,41 @@ import ( ) const ( - ClusterNodeType = "clusterNode" - ClusterNodeFieldAPIVersion = "apiVersion" - ClusterNodeFieldKind = "kind" - ClusterNodeFieldObjectMeta = "objectMeta" - ClusterNodeFieldSpec = "spec" - ClusterNodeFieldStatus = "status" + ClusterNodeType = "clusterNode" + ClusterNodeFieldAPIVersion = "apiVersion" + ClusterNodeFieldAnnotations = "annotations" + ClusterNodeFieldConfigSource = "configSource" + ClusterNodeFieldCreated = "created" + ClusterNodeFieldExternalID = "externalID" + ClusterNodeFieldKind = "kind" + ClusterNodeFieldLabels = "labels" + ClusterNodeFieldName = "name" + ClusterNodeFieldNamespace = "namespace" + ClusterNodeFieldPodCIDR = "podCIDR" + ClusterNodeFieldProviderID = "providerID" + ClusterNodeFieldRemoved = "removed" + ClusterNodeFieldTaints = "taints" + ClusterNodeFieldUnschedulable = "unschedulable" + ClusterNodeFieldUuid = "uuid" ) type ClusterNode struct { types.Resource - APIVersion string `json:"apiVersion,omitempty"` - Kind string `json:"kind,omitempty"` - ObjectMeta ObjectMeta `json:"objectMeta,omitempty"` - Spec NodeSpec `json:"spec,omitempty"` - Status NodeStatus `json:"status,omitempty"` + APIVersion string `json:"apiVersion,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + ConfigSource *NodeConfigSource `json:"configSource,omitempty"` + Created string `json:"created,omitempty"` + ExternalID string `json:"externalID,omitempty"` + Kind string `json:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` + PodCIDR string `json:"podCIDR,omitempty"` + ProviderID string `json:"providerID,omitempty"` + Removed string `json:"removed,omitempty"` + Taints []Taint `json:"taints,omitempty"` + Unschedulable bool `json:"unschedulable,omitempty"` + Uuid string `json:"uuid,omitempty"` } type ClusterNodeCollection struct { types.Collection diff --git a/client/cluster/v1/zz_generated_object_meta.go b/client/cluster/v1/zz_generated_object_meta.go index 06f7d602..5bc5a332 100644 --- a/client/cluster/v1/zz_generated_object_meta.go +++ b/client/cluster/v1/zz_generated_object_meta.go @@ -1,40 +1,22 @@ package client const ( - ObjectMetaType = "objectMeta" - ObjectMetaFieldAnnotations = "annotations" - ObjectMetaFieldClusterName = "clusterName" - ObjectMetaFieldCreationTimestamp = "creationTimestamp" - ObjectMetaFieldDeletionGracePeriodSeconds = "deletionGracePeriodSeconds" - ObjectMetaFieldDeletionTimestamp = "deletionTimestamp" - ObjectMetaFieldFinalizers = "finalizers" - ObjectMetaFieldGenerateName = "generateName" - ObjectMetaFieldGeneration = "generation" - ObjectMetaFieldInitializers = "initializers" - ObjectMetaFieldLabels = "labels" - ObjectMetaFieldName = "name" - ObjectMetaFieldNamespace = "namespace" - ObjectMetaFieldOwnerReferences = "ownerReferences" - ObjectMetaFieldResourceVersion = "resourceVersion" - ObjectMetaFieldSelfLink = "selfLink" - ObjectMetaFieldUID = "uid" + ObjectMetaType = "objectMeta" + ObjectMetaFieldAnnotations = "annotations" + ObjectMetaFieldCreated = "created" + ObjectMetaFieldLabels = "labels" + ObjectMetaFieldName = "name" + ObjectMetaFieldNamespace = "namespace" + ObjectMetaFieldRemoved = "removed" + ObjectMetaFieldUuid = "uuid" ) type ObjectMeta struct { - Annotations map[string]string `json:"annotations,omitempty"` - ClusterName string `json:"clusterName,omitempty"` - CreationTimestamp string `json:"creationTimestamp,omitempty"` - DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty"` - DeletionTimestamp string `json:"deletionTimestamp,omitempty"` - Finalizers []string `json:"finalizers,omitempty"` - GenerateName string `json:"generateName,omitempty"` - Generation int64 `json:"generation,omitempty"` - Initializers *Initializers `json:"initializers,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Name string `json:"name,omitempty"` - Namespace string `json:"namespace,omitempty"` - OwnerReferences []OwnerReference `json:"ownerReferences,omitempty"` - ResourceVersion string `json:"resourceVersion,omitempty"` - SelfLink string `json:"selfLink,omitempty"` - UID string `json:"uid,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + Created string `json:"created,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` + Removed string `json:"removed,omitempty"` + Uuid string `json:"uuid,omitempty"` } diff --git a/client/workload/v1/zz_generated_object_meta.go b/client/workload/v1/zz_generated_object_meta.go index 80e5fae7..5bc5a332 100644 --- a/client/workload/v1/zz_generated_object_meta.go +++ b/client/workload/v1/zz_generated_object_meta.go @@ -1,24 +1,22 @@ package client const ( - ObjectMetaType = "objectMeta" - ObjectMetaFieldAnnotations = "annotations" - ObjectMetaFieldCreated = "created" - ObjectMetaFieldDeletionGracePeriodSeconds = "deletionGracePeriodSeconds" - ObjectMetaFieldLabels = "labels" - ObjectMetaFieldName = "name" - ObjectMetaFieldNamespace = "namespace" - ObjectMetaFieldRemoved = "removed" - ObjectMetaFieldUuid = "uuid" + ObjectMetaType = "objectMeta" + ObjectMetaFieldAnnotations = "annotations" + ObjectMetaFieldCreated = "created" + ObjectMetaFieldLabels = "labels" + ObjectMetaFieldName = "name" + ObjectMetaFieldNamespace = "namespace" + ObjectMetaFieldRemoved = "removed" + ObjectMetaFieldUuid = "uuid" ) type ObjectMeta struct { - Annotations map[string]string `json:"annotations,omitempty"` - Created string `json:"created,omitempty"` - DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Name string `json:"name,omitempty"` - Namespace string `json:"namespace,omitempty"` - Removed string `json:"removed,omitempty"` - Uuid string `json:"uuid,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + Created string `json:"created,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` + Removed string `json:"removed,omitempty"` + Uuid string `json:"uuid,omitempty"` } diff --git a/client/workload/v1/zz_generated_pod.go b/client/workload/v1/zz_generated_pod.go index dcc006f7..8e96ec82 100644 --- a/client/workload/v1/zz_generated_pod.go +++ b/client/workload/v1/zz_generated_pod.go @@ -13,7 +13,6 @@ const ( PodFieldContainers = "containers" PodFieldCreated = "created" PodFieldDNSPolicy = "dnsPolicy" - PodFieldDeletionGracePeriodSeconds = "deletionGracePeriodSeconds" PodFieldDeprecatedServiceAccount = "deprecatedServiceAccount" PodFieldFsgid = "fsgid" PodFieldGids = "gids" @@ -52,7 +51,6 @@ type Pod struct { Containers map[string]Container `json:"containers,omitempty"` Created string `json:"created,omitempty"` DNSPolicy string `json:"dnsPolicy,omitempty"` - DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty"` DeprecatedServiceAccount string `json:"deprecatedServiceAccount,omitempty"` Fsgid *int64 `json:"fsgid,omitempty"` Gids []int64 `json:"gids,omitempty"` diff --git a/commonmappers/setup.go b/commonmappers/setup.go new file mode 100644 index 00000000..d75a18a3 --- /dev/null +++ b/commonmappers/setup.go @@ -0,0 +1,28 @@ +package commonmappers + +import ( + "github.com/rancher/norman/types" + m "github.com/rancher/norman/types/mapping/mapper" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Add(version *types.APIVersion, schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(version, metav1.ObjectMeta{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + m.Drop{"generateName"}, + m.Drop{"selfLink"}, + m.Move{From: "uid", To: "uuid"}, + m.Drop{"resourceVersion"}, + m.Drop{"generation"}, + m.Move{From: "creationTimestamp", To: "created"}, + m.Move{From: "deletionTimestamp", To: "removed"}, + m.Drop{"deletionGracePeriodSeconds"}, + //DeletionGracePeriodSecondsMapper{}, + m.Drop{"initializers"}, + m.Drop{"finalizers"}, + m.Drop{"clusterName"}, + m.Drop{"ownerReferences"}, + }, + }) +} diff --git a/io.cattle.authorization/v1/zz_generated_k8s_client.go b/io.cattle.authorization/v1/zz_generated_k8s_client.go new file mode 100644 index 00000000..27ed682c --- /dev/null +++ b/io.cattle.authorization/v1/zz_generated_k8s_client.go @@ -0,0 +1,105 @@ +package v1 + +import ( + "sync" + + "github.com/rancher/norman/clientbase" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" +) + +type Interface interface { + RESTClient() rest.Interface + + ProjectsGetter + RoleTemplatesGetter + PodSecurityPolicyTemplatesGetter + ProjectRoleBindingsGetter +} + +type Client struct { + sync.Mutex + restClient rest.Interface + + projectControllers map[string]ProjectController + roleTemplateControllers map[string]RoleTemplateController + podSecurityPolicyTemplateControllers map[string]PodSecurityPolicyTemplateController + projectRoleBindingControllers map[string]ProjectRoleBindingController +} + +func NewForConfig(config rest.Config) (Interface, error) { + if config.NegotiatedSerializer == nil { + configConfig := dynamic.ContentConfig() + config.NegotiatedSerializer = configConfig.NegotiatedSerializer + } + + restClient, err := rest.UnversionedRESTClientFor(&config) + if err != nil { + return nil, err + } + + return &Client{ + restClient: restClient, + + projectControllers: map[string]ProjectController{}, + roleTemplateControllers: map[string]RoleTemplateController{}, + podSecurityPolicyTemplateControllers: map[string]PodSecurityPolicyTemplateController{}, + projectRoleBindingControllers: map[string]ProjectRoleBindingController{}, + }, nil +} + +func (c *Client) RESTClient() rest.Interface { + return c.restClient +} + +type ProjectsGetter interface { + Projects(namespace string) ProjectInterface +} + +func (c *Client) Projects(namespace string) ProjectInterface { + objectClient := clientbase.NewObjectClient(namespace, c.restClient, &ProjectResource, ProjectGroupVersionKind, projectFactory{}) + return &projectClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RoleTemplatesGetter interface { + RoleTemplates(namespace string) RoleTemplateInterface +} + +func (c *Client) RoleTemplates(namespace string) RoleTemplateInterface { + objectClient := clientbase.NewObjectClient(namespace, c.restClient, &RoleTemplateResource, RoleTemplateGroupVersionKind, roleTemplateFactory{}) + return &roleTemplateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type PodSecurityPolicyTemplatesGetter interface { + PodSecurityPolicyTemplates(namespace string) PodSecurityPolicyTemplateInterface +} + +func (c *Client) PodSecurityPolicyTemplates(namespace string) PodSecurityPolicyTemplateInterface { + objectClient := clientbase.NewObjectClient(namespace, c.restClient, &PodSecurityPolicyTemplateResource, PodSecurityPolicyTemplateGroupVersionKind, podSecurityPolicyTemplateFactory{}) + return &podSecurityPolicyTemplateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ProjectRoleBindingsGetter interface { + ProjectRoleBindings(namespace string) ProjectRoleBindingInterface +} + +func (c *Client) ProjectRoleBindings(namespace string) ProjectRoleBindingInterface { + objectClient := clientbase.NewObjectClient(namespace, c.restClient, &ProjectRoleBindingResource, ProjectRoleBindingGroupVersionKind, projectRoleBindingFactory{}) + return &projectRoleBindingClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/io.cattle.authorization/v1/zz_generated_pod_security_policy_template_controller.go b/io.cattle.authorization/v1/zz_generated_pod_security_policy_template_controller.go index 591ac7dc..2f6fb883 100644 --- a/io.cattle.authorization/v1/zz_generated_pod_security_policy_template_controller.go +++ b/io.cattle.authorization/v1/zz_generated_pod_security_policy_template_controller.go @@ -1,8 +1,6 @@ package v1 import ( - "sync" - "context" "github.com/rancher/norman/clientbase" @@ -11,7 +9,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" ) @@ -52,7 +49,7 @@ type PodSecurityPolicyTemplateInterface interface { List(opts metav1.ListOptions) (*PodSecurityPolicyTemplateList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error - Controller() (PodSecurityPolicyTemplateController, error) + Controller() PodSecurityPolicyTemplateController } type podSecurityPolicyTemplateController struct { @@ -83,35 +80,30 @@ func (c podSecurityPolicyTemplateFactory) List() runtime.Object { return &PodSecurityPolicyTemplateList{} } -func NewPodSecurityPolicyTemplateClient(namespace string, config rest.Config) (PodSecurityPolicyTemplateInterface, error) { - objectClient, err := clientbase.NewObjectClient(namespace, config, &PodSecurityPolicyTemplateResource, PodSecurityPolicyTemplateGroupVersionKind, podSecurityPolicyTemplateFactory{}) - return &podSecurityPolicyTemplateClient{ - objectClient: objectClient, - }, err -} +func (s *podSecurityPolicyTemplateClient) Controller() PodSecurityPolicyTemplateController { + s.client.Lock() + defer s.client.Unlock() -func (s *podSecurityPolicyTemplateClient) Controller() (PodSecurityPolicyTemplateController, error) { - s.Lock() - defer s.Unlock() - - if s.controller != nil { - return s.controller, nil + c, ok := s.client.podSecurityPolicyTemplateControllers[s.ns] + if ok { + return c } - controller, err := controller.NewGenericController(PodSecurityPolicyTemplateGroupVersionKind.Kind+"Controller", + genericController := controller.NewGenericController(PodSecurityPolicyTemplateGroupVersionKind.Kind+"Controller", s.objectClient) - if err != nil { - return nil, err + + c = &podSecurityPolicyTemplateController{ + GenericController: genericController, } - s.controller = &podSecurityPolicyTemplateController{ - GenericController: controller, - } - return s.controller, nil + s.client.podSecurityPolicyTemplateControllers[s.ns] = c + + return c } type podSecurityPolicyTemplateClient struct { - sync.Mutex + client *Client + ns string objectClient *clientbase.ObjectClient controller PodSecurityPolicyTemplateController } diff --git a/io.cattle.authorization/v1/zz_generated_project_controller.go b/io.cattle.authorization/v1/zz_generated_project_controller.go index dd47df79..4f4ba7d8 100644 --- a/io.cattle.authorization/v1/zz_generated_project_controller.go +++ b/io.cattle.authorization/v1/zz_generated_project_controller.go @@ -1,8 +1,6 @@ package v1 import ( - "sync" - "context" "github.com/rancher/norman/clientbase" @@ -11,7 +9,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" ) @@ -52,7 +49,7 @@ type ProjectInterface interface { List(opts metav1.ListOptions) (*ProjectList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error - Controller() (ProjectController, error) + Controller() ProjectController } type projectController struct { @@ -83,35 +80,30 @@ func (c projectFactory) List() runtime.Object { return &ProjectList{} } -func NewProjectClient(namespace string, config rest.Config) (ProjectInterface, error) { - objectClient, err := clientbase.NewObjectClient(namespace, config, &ProjectResource, ProjectGroupVersionKind, projectFactory{}) - return &projectClient{ - objectClient: objectClient, - }, err -} +func (s *projectClient) Controller() ProjectController { + s.client.Lock() + defer s.client.Unlock() -func (s *projectClient) Controller() (ProjectController, error) { - s.Lock() - defer s.Unlock() - - if s.controller != nil { - return s.controller, nil + c, ok := s.client.projectControllers[s.ns] + if ok { + return c } - controller, err := controller.NewGenericController(ProjectGroupVersionKind.Kind+"Controller", + genericController := controller.NewGenericController(ProjectGroupVersionKind.Kind+"Controller", s.objectClient) - if err != nil { - return nil, err + + c = &projectController{ + GenericController: genericController, } - s.controller = &projectController{ - GenericController: controller, - } - return s.controller, nil + s.client.projectControllers[s.ns] = c + + return c } type projectClient struct { - sync.Mutex + client *Client + ns string objectClient *clientbase.ObjectClient controller ProjectController } diff --git a/io.cattle.authorization/v1/zz_generated_project_role_binding_controller.go b/io.cattle.authorization/v1/zz_generated_project_role_binding_controller.go index efad4233..a32b78f3 100644 --- a/io.cattle.authorization/v1/zz_generated_project_role_binding_controller.go +++ b/io.cattle.authorization/v1/zz_generated_project_role_binding_controller.go @@ -1,8 +1,6 @@ package v1 import ( - "sync" - "context" "github.com/rancher/norman/clientbase" @@ -11,7 +9,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" ) @@ -52,7 +49,7 @@ type ProjectRoleBindingInterface interface { List(opts metav1.ListOptions) (*ProjectRoleBindingList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error - Controller() (ProjectRoleBindingController, error) + Controller() ProjectRoleBindingController } type projectRoleBindingController struct { @@ -83,35 +80,30 @@ func (c projectRoleBindingFactory) List() runtime.Object { return &ProjectRoleBindingList{} } -func NewProjectRoleBindingClient(namespace string, config rest.Config) (ProjectRoleBindingInterface, error) { - objectClient, err := clientbase.NewObjectClient(namespace, config, &ProjectRoleBindingResource, ProjectRoleBindingGroupVersionKind, projectRoleBindingFactory{}) - return &projectRoleBindingClient{ - objectClient: objectClient, - }, err -} +func (s *projectRoleBindingClient) Controller() ProjectRoleBindingController { + s.client.Lock() + defer s.client.Unlock() -func (s *projectRoleBindingClient) Controller() (ProjectRoleBindingController, error) { - s.Lock() - defer s.Unlock() - - if s.controller != nil { - return s.controller, nil + c, ok := s.client.projectRoleBindingControllers[s.ns] + if ok { + return c } - controller, err := controller.NewGenericController(ProjectRoleBindingGroupVersionKind.Kind+"Controller", + genericController := controller.NewGenericController(ProjectRoleBindingGroupVersionKind.Kind+"Controller", s.objectClient) - if err != nil { - return nil, err + + c = &projectRoleBindingController{ + GenericController: genericController, } - s.controller = &projectRoleBindingController{ - GenericController: controller, - } - return s.controller, nil + s.client.projectRoleBindingControllers[s.ns] = c + + return c } type projectRoleBindingClient struct { - sync.Mutex + client *Client + ns string objectClient *clientbase.ObjectClient controller ProjectRoleBindingController } diff --git a/io.cattle.authorization/v1/zz_generated_role_template_controller.go b/io.cattle.authorization/v1/zz_generated_role_template_controller.go index 5c493142..a39a3d23 100644 --- a/io.cattle.authorization/v1/zz_generated_role_template_controller.go +++ b/io.cattle.authorization/v1/zz_generated_role_template_controller.go @@ -1,8 +1,6 @@ package v1 import ( - "sync" - "context" "github.com/rancher/norman/clientbase" @@ -11,7 +9,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" ) @@ -52,7 +49,7 @@ type RoleTemplateInterface interface { List(opts metav1.ListOptions) (*RoleTemplateList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error - Controller() (RoleTemplateController, error) + Controller() RoleTemplateController } type roleTemplateController struct { @@ -83,35 +80,30 @@ func (c roleTemplateFactory) List() runtime.Object { return &RoleTemplateList{} } -func NewRoleTemplateClient(namespace string, config rest.Config) (RoleTemplateInterface, error) { - objectClient, err := clientbase.NewObjectClient(namespace, config, &RoleTemplateResource, RoleTemplateGroupVersionKind, roleTemplateFactory{}) - return &roleTemplateClient{ - objectClient: objectClient, - }, err -} +func (s *roleTemplateClient) Controller() RoleTemplateController { + s.client.Lock() + defer s.client.Unlock() -func (s *roleTemplateClient) Controller() (RoleTemplateController, error) { - s.Lock() - defer s.Unlock() - - if s.controller != nil { - return s.controller, nil + c, ok := s.client.roleTemplateControllers[s.ns] + if ok { + return c } - controller, err := controller.NewGenericController(RoleTemplateGroupVersionKind.Kind+"Controller", + genericController := controller.NewGenericController(RoleTemplateGroupVersionKind.Kind+"Controller", s.objectClient) - if err != nil { - return nil, err + + c = &roleTemplateController{ + GenericController: genericController, } - s.controller = &roleTemplateController{ - GenericController: controller, - } - return s.controller, nil + s.client.roleTemplateControllers[s.ns] = c + + return c } type roleTemplateClient struct { - sync.Mutex + client *Client + ns string objectClient *clientbase.ObjectClient controller RoleTemplateController } diff --git a/io.cattle.cluster/v1/schema/schema.go b/io.cattle.cluster/v1/schema/schema.go index c5120f24..885ea865 100644 --- a/io.cattle.cluster/v1/schema/schema.go +++ b/io.cattle.cluster/v1/schema/schema.go @@ -2,6 +2,8 @@ package schema import ( "github.com/rancher/norman/types" + m "github.com/rancher/norman/types/mapping/mapper" + "github.com/rancher/types/commonmappers" "github.com/rancher/types/io.cattle.cluster/v1" ) @@ -15,7 +17,9 @@ var ( }, } - Schemas = types.NewSchemas(). + Schemas = commonmappers.Add(&Version, types.NewSchemas()). + AddMapperForType(&Version, v1.Cluster{}, m.NewObject(nil)). + AddMapperForType(&Version, v1.ClusterNode{}, m.NewObject(nil)). MustImport(&Version, v1.Cluster{}). MustImport(&Version, v1.ClusterNode{}) ) diff --git a/io.cattle.cluster/v1/zz_generated_cluster_controller.go b/io.cattle.cluster/v1/zz_generated_cluster_controller.go index 56448571..b9975cba 100644 --- a/io.cattle.cluster/v1/zz_generated_cluster_controller.go +++ b/io.cattle.cluster/v1/zz_generated_cluster_controller.go @@ -1,8 +1,6 @@ package v1 import ( - "sync" - "context" "github.com/rancher/norman/clientbase" @@ -11,7 +9,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" ) @@ -22,7 +19,7 @@ var ( Kind: "Cluster", } ClusterResource = metav1.APIResource{ - Name: "clusters", + Name: "", SingularName: "cluster", Namespaced: false, Kind: ClusterGroupVersionKind.Kind, @@ -52,7 +49,7 @@ type ClusterInterface interface { List(opts metav1.ListOptions) (*ClusterList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error - Controller() (ClusterController, error) + Controller() ClusterController } type clusterController struct { @@ -83,35 +80,30 @@ func (c clusterFactory) List() runtime.Object { return &ClusterList{} } -func NewClusterClient(namespace string, config rest.Config) (ClusterInterface, error) { - objectClient, err := clientbase.NewObjectClient(namespace, config, &ClusterResource, ClusterGroupVersionKind, clusterFactory{}) - return &clusterClient{ - objectClient: objectClient, - }, err -} +func (s *clusterClient) Controller() ClusterController { + s.client.Lock() + defer s.client.Unlock() -func (s *clusterClient) Controller() (ClusterController, error) { - s.Lock() - defer s.Unlock() - - if s.controller != nil { - return s.controller, nil + c, ok := s.client.clusterControllers[s.ns] + if ok { + return c } - controller, err := controller.NewGenericController(ClusterGroupVersionKind.Kind+"Controller", + genericController := controller.NewGenericController(ClusterGroupVersionKind.Kind+"Controller", s.objectClient) - if err != nil { - return nil, err + + c = &clusterController{ + GenericController: genericController, } - s.controller = &clusterController{ - GenericController: controller, - } - return s.controller, nil + s.client.clusterControllers[s.ns] = c + + return c } type clusterClient struct { - sync.Mutex + client *Client + ns string objectClient *clientbase.ObjectClient controller ClusterController } diff --git a/io.cattle.cluster/v1/zz_generated_cluster_node_controller.go b/io.cattle.cluster/v1/zz_generated_cluster_node_controller.go index d3453f86..2ede1f77 100644 --- a/io.cattle.cluster/v1/zz_generated_cluster_node_controller.go +++ b/io.cattle.cluster/v1/zz_generated_cluster_node_controller.go @@ -1,8 +1,6 @@ package v1 import ( - "sync" - "context" "github.com/rancher/norman/clientbase" @@ -11,7 +9,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" ) @@ -22,7 +19,7 @@ var ( Kind: "ClusterNode", } ClusterNodeResource = metav1.APIResource{ - Name: "clusternodes", + Name: "", SingularName: "clusternode", Namespaced: false, Kind: ClusterNodeGroupVersionKind.Kind, @@ -52,7 +49,7 @@ type ClusterNodeInterface interface { List(opts metav1.ListOptions) (*ClusterNodeList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error - Controller() (ClusterNodeController, error) + Controller() ClusterNodeController } type clusterNodeController struct { @@ -83,35 +80,30 @@ func (c clusterNodeFactory) List() runtime.Object { return &ClusterNodeList{} } -func NewClusterNodeClient(namespace string, config rest.Config) (ClusterNodeInterface, error) { - objectClient, err := clientbase.NewObjectClient(namespace, config, &ClusterNodeResource, ClusterNodeGroupVersionKind, clusterNodeFactory{}) - return &clusterNodeClient{ - objectClient: objectClient, - }, err -} +func (s *clusterNodeClient) Controller() ClusterNodeController { + s.client.Lock() + defer s.client.Unlock() -func (s *clusterNodeClient) Controller() (ClusterNodeController, error) { - s.Lock() - defer s.Unlock() - - if s.controller != nil { - return s.controller, nil + c, ok := s.client.clusterNodeControllers[s.ns] + if ok { + return c } - controller, err := controller.NewGenericController(ClusterNodeGroupVersionKind.Kind+"Controller", + genericController := controller.NewGenericController(ClusterNodeGroupVersionKind.Kind+"Controller", s.objectClient) - if err != nil { - return nil, err + + c = &clusterNodeController{ + GenericController: genericController, } - s.controller = &clusterNodeController{ - GenericController: controller, - } - return s.controller, nil + s.client.clusterNodeControllers[s.ns] = c + + return c } type clusterNodeClient struct { - sync.Mutex + client *Client + ns string objectClient *clientbase.ObjectClient controller ClusterNodeController } diff --git a/io.cattle.cluster/v1/zz_generated_k8s_client.go b/io.cattle.cluster/v1/zz_generated_k8s_client.go new file mode 100644 index 00000000..0b6ce9ed --- /dev/null +++ b/io.cattle.cluster/v1/zz_generated_k8s_client.go @@ -0,0 +1,73 @@ +package v1 + +import ( + "sync" + + "github.com/rancher/norman/clientbase" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" +) + +type Interface interface { + RESTClient() rest.Interface + + ClustersGetter + ClusterNodesGetter +} + +type Client struct { + sync.Mutex + restClient rest.Interface + + clusterControllers map[string]ClusterController + clusterNodeControllers map[string]ClusterNodeController +} + +func NewForConfig(config rest.Config) (Interface, error) { + if config.NegotiatedSerializer == nil { + configConfig := dynamic.ContentConfig() + config.NegotiatedSerializer = configConfig.NegotiatedSerializer + } + + restClient, err := rest.UnversionedRESTClientFor(&config) + if err != nil { + return nil, err + } + + return &Client{ + restClient: restClient, + + clusterControllers: map[string]ClusterController{}, + clusterNodeControllers: map[string]ClusterNodeController{}, + }, nil +} + +func (c *Client) RESTClient() rest.Interface { + return c.restClient +} + +type ClustersGetter interface { + Clusters(namespace string) ClusterInterface +} + +func (c *Client) Clusters(namespace string) ClusterInterface { + objectClient := clientbase.NewObjectClient(namespace, c.restClient, &ClusterResource, ClusterGroupVersionKind, clusterFactory{}) + return &clusterClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterNodesGetter interface { + ClusterNodes(namespace string) ClusterNodeInterface +} + +func (c *Client) ClusterNodes(namespace string) ClusterNodeInterface { + objectClient := clientbase.NewObjectClient(namespace, c.restClient, &ClusterNodeResource, ClusterNodeGroupVersionKind, clusterNodeFactory{}) + return &clusterNodeClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/io.cattle.workload/v1/schema/schema.go b/io.cattle.workload/v1/schema/schema.go index 38640771..2f7862eb 100644 --- a/io.cattle.workload/v1/schema/schema.go +++ b/io.cattle.workload/v1/schema/schema.go @@ -3,9 +3,9 @@ package schema import ( "github.com/rancher/norman/types" m "github.com/rancher/norman/types/mapping/mapper" + "github.com/rancher/types/commonmappers" "github.com/rancher/types/io.cattle.workload/v1/schema/mapper" "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ( @@ -18,7 +18,7 @@ var ( }, } - Schemas = types.NewSchemas(). + Schemas = commonmappers.Add(&Version, types.NewSchemas()). AddMapperForType(&Version, v1.Capabilities{}, &types.TypeMapper{ Mappers: []types.Mapper{ m.Move{From: "add", To: "capAdd"}, @@ -101,22 +101,6 @@ var ( mapper.ResourceRequirementsMapper{}, }, }). - AddMapperForType(&Version, metav1.ObjectMeta{}, &types.TypeMapper{ - Mappers: []types.Mapper{ - m.Drop{"generateName"}, - m.Drop{"selfLink"}, - m.Move{From: "uid", To: "uuid"}, - m.Drop{"resourceVersion"}, - m.Drop{"generation"}, - m.Move{From: "creationTimestamp", To: "created"}, - m.Move{From: "deletionTimestamp", To: "removed"}, - //DeletionGracePeriodSecondsMapper{}, - m.Drop{"initializers"}, - m.Drop{"finalizers"}, - m.Drop{"clusterName"}, - m.Drop{"ownerReferences"}, - }, - }). MustImport(&Version, v1.Handler{}, handlerOverride{}). MustImport(&Version, v1.Probe{}, handlerOverride{}). MustImport(&Version, v1.Container{}, struct { diff --git a/vendor.conf b/vendor.conf index 1dad90b4..e82b8772 100644 --- a/vendor.conf +++ b/vendor.conf @@ -3,4 +3,4 @@ github.com/rancher/types k8s.io/kubernetes v1.8.3 transitive=true,staging=true bitbucket.org/ww/goautoneg a547fc61f48d567d5b4ec6f8aee5573d8efce11d https://github.com/rancher/goautoneg.git -github.com/rancher/norman 591b663b2d905f928000e43dbacad2ffdca8a478 +github.com/rancher/norman 068b9eb94326e2c566c5eed7636163b1b407c4c0 diff --git a/vendor/github.com/rancher/norman/clientbase/object_client.go b/vendor/github.com/rancher/norman/clientbase/object_client.go index 32e7558b..23443478 100644 --- a/vendor/github.com/rancher/norman/clientbase/object_client.go +++ b/vendor/github.com/rancher/norman/clientbase/object_client.go @@ -25,24 +25,14 @@ type ObjectClient struct { Factory ObjectFactory } -func NewObjectClient(namespace string, config rest.Config, apiResource *metav1.APIResource, gvk schema.GroupVersionKind, factory ObjectFactory) (*ObjectClient, error) { - if config.NegotiatedSerializer == nil { - configConfig := dynamic.ContentConfig() - config.NegotiatedSerializer = configConfig.NegotiatedSerializer - } - - restClient, err := rest.UnversionedRESTClientFor(&config) - if err != nil { - return nil, err - } - +func NewObjectClient(namespace string, restClient rest.Interface, apiResource *metav1.APIResource, gvk schema.GroupVersionKind, factory ObjectFactory) *ObjectClient { return &ObjectClient{ restClient: restClient, resource: apiResource, gvk: gvk, ns: namespace, Factory: factory, - }, nil + } } func (p *ObjectClient) Create(o runtime.Object) (runtime.Object, error) { diff --git a/vendor/github.com/rancher/norman/controller/generic_controller.go b/vendor/github.com/rancher/norman/controller/generic_controller.go index 4ebe911d..9d41235e 100644 --- a/vendor/github.com/rancher/norman/controller/generic_controller.go +++ b/vendor/github.com/rancher/norman/controller/generic_controller.go @@ -37,7 +37,7 @@ type genericController struct { running bool } -func NewGenericController(name string, objectClient *clientbase.ObjectClient) (GenericController, error) { +func NewGenericController(name string, objectClient *clientbase.ObjectClient) GenericController { informer := cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: objectClient.List, @@ -50,7 +50,7 @@ func NewGenericController(name string, objectClient *clientbase.ObjectClient) (G queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), name), name: name, - }, nil + } } func (g *genericController) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/rancher/norman/generator/controller_template.go b/vendor/github.com/rancher/norman/generator/controller_template.go index fd82b1d9..6cdca71e 100644 --- a/vendor/github.com/rancher/norman/generator/controller_template.go +++ b/vendor/github.com/rancher/norman/generator/controller_template.go @@ -54,7 +54,7 @@ type {{.schema.CodeName}}Interface interface { List(opts metav1.ListOptions) (*{{.schema.CodeName}}List, error) Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error - Controller() ({{.schema.CodeName}}Controller, error) + Controller() {{.schema.CodeName}}Controller } type {{.schema.ID}}Controller struct { @@ -85,35 +85,30 @@ func (c {{.schema.ID}}Factory) List() runtime.Object { return &{{.schema.CodeName}}List{} } -func New{{.schema.CodeName}}Client(namespace string, config rest.Config) ({{.schema.CodeName}}Interface, error) { - objectClient, err := clientbase.NewObjectClient(namespace, config, &{{.schema.CodeName}}Resource, {{.schema.CodeName}}GroupVersionKind, {{.schema.ID}}Factory{}) - return &{{.schema.ID}}Client{ - objectClient: objectClient, - }, err -} +func (s *{{.schema.ID}}Client) Controller() {{.schema.CodeName}}Controller { + s.client.Lock() + defer s.client.Unlock() -func (s *{{.schema.ID}}Client) Controller() ({{.schema.CodeName}}Controller, error) { - s.Lock() - defer s.Unlock() - - if s.controller != nil { - return s.controller, nil + c, ok := s.client.{{.schema.ID}}Controllers[s.ns] + if ok { + return c } - controller, err := controller.NewGenericController({{.schema.CodeName}}GroupVersionKind.Kind+"Controller", + genericController := controller.NewGenericController({{.schema.CodeName}}GroupVersionKind.Kind+"Controller", s.objectClient) - if err != nil { - return nil, err + + c = &{{.schema.ID}}Controller{ + GenericController: genericController, } - s.controller = &{{.schema.ID}}Controller{ - GenericController: controller, - } - return s.controller, nil + s.client.{{.schema.ID}}Controllers[s.ns] = c + + return c } type {{.schema.ID}}Client struct { - sync.Mutex + client *Client + ns string objectClient *clientbase.ObjectClient controller {{.schema.CodeName}}Controller } diff --git a/vendor/github.com/rancher/norman/generator/generator.go b/vendor/github.com/rancher/norman/generator/generator.go index ea905554..ba58244a 100644 --- a/vendor/github.com/rancher/norman/generator/generator.go +++ b/vendor/github.com/rancher/norman/generator/generator.go @@ -149,6 +149,27 @@ func generateController(outputDir string, schema *types.Schema, schemas *types.S }) } +func generateK8sClient(outputDir string, version *types.APIVersion, schemas []*types.Schema) error { + filePath := strings.ToLower("zz_generated_k8s_client.go") + output, err := os.Create(path.Join(outputDir, filePath)) + if err != nil { + return err + } + defer output.Close() + + typeTemplate, err := template.New("k8sClient.template"). + Funcs(funcs()). + Parse(strings.Replace(k8sClientTemplate, "%BACK%", "`", -1)) + if err != nil { + return err + } + + return typeTemplate.Execute(output, map[string]interface{}{ + "version": version, + "schemas": schemas, + }) +} + func generateClient(outputDir string, schemas []*types.Schema) error { template, err := template.New("client.template"). Funcs(funcs()). @@ -177,7 +198,7 @@ func Generate(schemas *types.Schemas, cattleOutputPackage, k8sOutputPackage stri return err } - doDeepCopy := false + controllers := []*types.Schema{} generated := []*types.Schema{} for _, schema := range schemas.Schemas() { @@ -192,7 +213,7 @@ func Generate(schemas *types.Schemas, cattleOutputPackage, k8sOutputPackage stri if contains(schema.CollectionMethods, http.MethodGet) && !strings.HasPrefix(schema.PkgName, "k8s.io") && !strings.Contains(schema.PkgName, "/vendor/") { - doDeepCopy = true + controllers = append(controllers, schema) if err := generateController(k8sDir, schema, schemas); err != nil { return err } @@ -205,10 +226,12 @@ func Generate(schemas *types.Schemas, cattleOutputPackage, k8sOutputPackage stri return err } - if doDeepCopy { + if len(controllers) > 0 { if err := deepCopyGen(baseDir, k8sOutputPackage); err != nil { return err } + + generateK8sClient(k8sDir, &controllers[0].Version, controllers) } if err := gofmt(baseDir, k8sOutputPackage); err != nil { diff --git a/vendor/github.com/rancher/norman/generator/k8s_client_template.go b/vendor/github.com/rancher/norman/generator/k8s_client_template.go new file mode 100644 index 00000000..3dc1770d --- /dev/null +++ b/vendor/github.com/rancher/norman/generator/k8s_client_template.go @@ -0,0 +1,62 @@ +package generator + +var k8sClientTemplate = `package {{.version.Version}} + +import ( + "sync" + + "github.com/rancher/norman/clientbase" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" +) + +type Interface interface { + RESTClient() rest.Interface + {{range .schemas}} + {{.CodeNamePlural}}Getter{{end}} +} + +type Client struct { + sync.Mutex + restClient rest.Interface + {{range .schemas}} + {{.ID}}Controllers map[string]{{.CodeName}}Controller{{end}} +} + +func NewForConfig(config rest.Config) (Interface, error) { + if config.NegotiatedSerializer == nil { + configConfig := dynamic.ContentConfig() + config.NegotiatedSerializer = configConfig.NegotiatedSerializer + } + + restClient, err := rest.UnversionedRESTClientFor(&config) + if err != nil { + return nil, err + } + + return &Client{ + restClient: restClient, + {{range .schemas}} + {{.ID}}Controllers: map[string]{{.CodeName}}Controller{},{{end}} + }, nil +} + +func (c *Client) RESTClient() rest.Interface { + return c.restClient +} + +{{range .schemas}} +type {{.CodeNamePlural}}Getter interface { + {{.CodeNamePlural}}(namespace string) {{.CodeName}}Interface +} + +func (c *Client) {{.CodeNamePlural}}(namespace string) {{.CodeName}}Interface { + objectClient := clientbase.NewObjectClient(namespace, c.restClient, &{{.CodeName}}Resource, {{.CodeName}}GroupVersionKind, {{.ID}}Factory{}) + return &{{.ID}}Client{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} +{{end}} +` diff --git a/vendor/github.com/rancher/norman/types/mapper.go b/vendor/github.com/rancher/norman/types/mapper.go index ba99c363..0b43e6c0 100644 --- a/vendor/github.com/rancher/norman/types/mapper.go +++ b/vendor/github.com/rancher/norman/types/mapper.go @@ -48,7 +48,7 @@ func (t *TypeMapper) FromInternal(data map[string]interface{}) { } func (t *TypeMapper) ToInternal(data map[string]interface{}) { - for i := len(t.Mappers) - 1; i <= 0; i-- { + for i := len(t.Mappers) - 1; i >= 0; i-- { t.Mappers[i].ToInternal(data) } diff --git a/vendor/github.com/rancher/norman/types/mapping/mapper/move.go b/vendor/github.com/rancher/norman/types/mapping/mapper/move.go index 6c7ba333..c47d29eb 100644 --- a/vendor/github.com/rancher/norman/types/mapping/mapper/move.go +++ b/vendor/github.com/rancher/norman/types/mapping/mapper/move.go @@ -12,13 +12,15 @@ type Move struct { } func (m Move) FromInternal(data map[string]interface{}) { - if v, ok := GetValue(data, m.From); ok { + if v, ok := data[m.From]; ok { + delete(data, m.From) data[m.To] = v } } func (m Move) ToInternal(data map[string]interface{}) { - if v, ok := GetValue(data, m.To); ok { + if v, ok := data[m.To]; ok { + delete(data, m.To) data[m.From] = v } } diff --git a/vendor/github.com/rancher/norman/types/mapping/mapper/object.go b/vendor/github.com/rancher/norman/types/mapping/mapper/object.go new file mode 100644 index 00000000..0c5f8f71 --- /dev/null +++ b/vendor/github.com/rancher/norman/types/mapping/mapper/object.go @@ -0,0 +1,19 @@ +package mapper + +import "github.com/rancher/norman/types" + +type Object struct { + types.TypeMapper +} + +func NewObject(mappers []types.Mapper) *Object { + return &Object{ + TypeMapper: types.TypeMapper{ + Mappers: append(mappers, + &Drop{"status"}, + &Embed{Field: "metadata"}, + &Embed{Field: "spec"}, + ), + }, + } +} diff --git a/vendor/github.com/rancher/norman/types/schemas.go b/vendor/github.com/rancher/norman/types/schemas.go index 949ffcdc..f7a69054 100644 --- a/vendor/github.com/rancher/norman/types/schemas.go +++ b/vendor/github.com/rancher/norman/types/schemas.go @@ -55,6 +55,9 @@ func (s *Schemas) AddSchema(schema *Schema) *Schemas { if schema.CodeName == "" { schema.CodeName = convert.Capitalize(schema.ID) } + if schema.CodeNamePlural == "" { + schema.CodeNamePlural = name.GuessPluralName(schema.CodeName) + } schemas, ok := s.schemasByPath[schema.Version.Path] if !ok { diff --git a/vendor/github.com/rancher/norman/types/types.go b/vendor/github.com/rancher/norman/types/types.go index 56951606..36eddca1 100644 --- a/vendor/github.com/rancher/norman/types/types.go +++ b/vendor/github.com/rancher/norman/types/types.go @@ -62,6 +62,7 @@ type APIVersion struct { type Schema struct { ID string `json:"id,omitempty"` CodeName string `json:"-"` + CodeNamePlural string `json:"-"` PkgName string `json:"-"` Type string `json:"type,omitempty"` Links map[string]string `json:"links"`