Merge pull request #21 from enj/enj/i/cleanup_apimachinery

Various clean ups
This commit is contained in:
Mo Khan 2020-07-19 01:39:05 -04:00 committed by GitHub
commit 240f9f86b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 8 deletions

View File

@ -22,6 +22,7 @@ import (
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
@ -30,7 +31,7 @@ import (
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
aggregationv1client "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" aggregationv1client "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
"github.com/suzerain-io/placeholder-name-api/pkg/apis/placeholder" placeholderv1alpha1 "github.com/suzerain-io/placeholder-name-api/pkg/apis/placeholder/v1alpha1"
"github.com/suzerain-io/placeholder-name/internal/autoregistration" "github.com/suzerain-io/placeholder-name/internal/autoregistration"
"github.com/suzerain-io/placeholder-name/internal/certauthority" "github.com/suzerain-io/placeholder-name/internal/certauthority"
"github.com/suzerain-io/placeholder-name/internal/downward" "github.com/suzerain-io/placeholder-name/internal/downward"
@ -73,19 +74,22 @@ credential from somewhere to an internal credential to be used for
authenticating to the Kubernetes API.`, authenticating to the Kubernetes API.`,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
// Load the Kubernetes client configuration (kubeconfig), // Load the Kubernetes client configuration (kubeconfig),
kubeconfig, err := restclient.InClusterConfig() kubeConfig, err := restclient.InClusterConfig()
if err != nil { if err != nil {
return fmt.Errorf("could not load in-cluster configuration: %w", err) return fmt.Errorf("could not load in-cluster configuration: %w", err)
} }
// explicitly use protobuf when talking to built-in kube APIs
protoKubeConfig := createProtoKubeConfig(kubeConfig)
// Connect to the core Kubernetes API. // Connect to the core Kubernetes API.
k8s, err := kubernetes.NewForConfig(kubeconfig) k8s, err := kubernetes.NewForConfig(protoKubeConfig)
if err != nil { if err != nil {
return fmt.Errorf("could not initialize Kubernetes client: %w", err) return fmt.Errorf("could not initialize Kubernetes client: %w", err)
} }
// Connect to the Kubernetes aggregation API. // Connect to the Kubernetes aggregation API.
aggregation, err := aggregationv1client.NewForConfig(kubeconfig) aggregation, err := aggregationv1client.NewForConfig(protoKubeConfig)
if err != nil { if err != nil {
return fmt.Errorf("could not initialize Kubernetes client: %w", err) return fmt.Errorf("could not initialize Kubernetes client: %w", err)
} }
@ -178,11 +182,11 @@ func (a *App) serve(ctx context.Context, k8s corev1client.CoreV1Interface, aggre
} }
apiService := apiregistrationv1.APIService{ apiService := apiregistrationv1.APIService{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "v1alpha1." + placeholder.GroupName, Name: placeholderv1alpha1.SchemeGroupVersion.Version + "." + placeholderv1alpha1.GroupName,
}, },
Spec: apiregistrationv1.APIServiceSpec{ Spec: apiregistrationv1.APIServiceSpec{
Group: placeholder.GroupName, Group: placeholderv1alpha1.GroupName,
Version: "v1alpha1", Version: placeholderv1alpha1.SchemeGroupVersion.Version,
CABundle: caBundle, CABundle: caBundle,
GroupPriorityMinimum: 2500, GroupPriorityMinimum: 2500,
VersionPriority: 10, VersionPriority: 10,
@ -259,3 +263,13 @@ func runGracefully(ctx context.Context, srv *http.Server, eg *errgroup.Group, f
defer cancel() defer cancel()
return srv.Shutdown(shutdownCtx) return srv.Shutdown(shutdownCtx)
} }
// createProtoKubeConfig returns a copy of the input config with the ContentConfig set to use protobuf.
// do not use this config to communicate with any CRD based APIs.
func createProtoKubeConfig(kubeConfig *restclient.Config) *restclient.Config {
protoKubeConfig := restclient.CopyConfig(kubeConfig)
const protoThenJSON = runtime.ContentTypeProtobuf + "," + runtime.ContentTypeJSON
protoKubeConfig.AcceptContentTypes = protoThenJSON
protoKubeConfig.ContentType = runtime.ContentTypeProtobuf
return protoKubeConfig
}

View File

@ -41,8 +41,16 @@ func Setup(ctx context.Context, options SetupOptions) error {
return fmt.Errorf("could not get namespace: %w", err) return fmt.Errorf("could not get namespace: %w", err)
} }
// Clayton ... 😒 // runtime.WithoutVersionDecoder clears the GVK set on the namespace because Clayton ... 😒
// https://github.com/kubernetes/kubernetes/pull/26251/files#diff-71b26e1e133ec6d3c4da26366b6502acR360-R361 // https://github.com/kubernetes/kubernetes/pull/26251/files#diff-71b26e1e133ec6d3c4da26366b6502acR360-R361
// I think this is legacy cruft from the internal rest clients combined with using the same codec
// in places where implicit conversion occurs from some external version to an internal or different external version
// i.e. the type meta we saw on the wire may not match the type meta of the struct in all cases
// however, in our case, we know that we directly called the rest API at a particular version and that no conversion occurred
// thus we know that the type meta we saw on the wire directly matches the struct that we are using
// said in a different way, we know that our GVR to GVK (and vice versa) mapping is 1:1
// this means we can recover the type meta by asking the Kube client-go scheme for it
// the below code will only error if some generated Kube client-go code is broken
gvks, _, err := scheme.Scheme.ObjectKinds(ns) gvks, _, err := scheme.Scheme.ObjectKinds(ns)
if err != nil || len(gvks) == 0 { if err != nil || len(gvks) == 0 {
return fmt.Errorf("could not get GVK: %w", err) return fmt.Errorf("could not get GVK: %w", err)