Merge pull request #12544 from justinsb/decode_non_kops

Show additional ("addon") objects in kops get
This commit is contained in:
Kubernetes Prow Robot 2021-11-14 11:02:47 -08:00 committed by GitHub
commit 0b696d3076
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 209 additions and 18 deletions

2
cmd/kops/BUILD.bazel generated
View File

@ -28,6 +28,7 @@ go_library(
"export_kubeconfig.go",
"gen_cli_docs.go",
"get.go",
"get_addons.go",
"get_assets.go",
"get_cluster.go",
"get_instancegroups.go",
@ -114,6 +115,7 @@ go_library(
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",

View File

@ -25,6 +25,7 @@ import (
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kops/cmd/kops/util"
api "k8s.io/kops/pkg/apis/kops"
@ -128,25 +129,39 @@ func RunGet(ctx context.Context, f commandutils.Factory, out io.Writer, options
instancegroups = append(instancegroups, &igList.Items[i])
}
var obj []runtime.Object
var addonObjects []*unstructured.Unstructured
{
addons, err := client.AddonsFor(cluster).List()
if err != nil {
return err
}
for _, addon := range addons {
addonObjects = append(addonObjects, addon.ToUnstructured())
}
}
var allObjects []runtime.Object
if options.Output != OutputTable {
obj = append(obj, cluster)
allObjects = append(allObjects, cluster)
for _, group := range instancegroups {
obj = append(obj, group)
allObjects = append(allObjects, group)
}
for _, additionalObject := range addonObjects {
allObjects = append(allObjects, additionalObject)
}
}
switch options.Output {
case OutputYaml:
if err := fullOutputYAML(out, obj...); err != nil {
return fmt.Errorf("error writing cluster yaml to stdout: %v", err)
if err := fullOutputYAML(out, allObjects...); err != nil {
return fmt.Errorf("error writing yaml to stdout: %v", err)
}
return nil
case OutputJSON:
if err := fullOutputJSON(out, obj...); err != nil {
return fmt.Errorf("error writing cluster json to stdout: %v", err)
if err := fullOutputJSON(out, allObjects...); err != nil {
return fmt.Errorf("error writing json to stdout: %v", err)
}
return nil
@ -161,6 +176,13 @@ func RunGet(ctx context.Context, f commandutils.Factory, out io.Writer, options
if err != nil {
return err
}
if len(addonObjects) != 0 {
fmt.Fprintf(out, "\nAddon Objects\n")
err = addonsOutputTable(cluster, addonObjects, out)
if err != nil {
return err
}
}
default:
return fmt.Errorf("Unknown output format: %q", options.Output)

40
cmd/kops/get_addons.go Normal file
View File

@ -0,0 +1,40 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"io"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/util/pkg/tables"
)
func addonsOutputTable(cluster *api.Cluster, addons []*unstructured.Unstructured, out io.Writer) error {
t := &tables.Table{}
t.AddColumn("NAME", func(o *unstructured.Unstructured) string {
return o.GetName()
})
t.AddColumn("KIND", func(o *unstructured.Unstructured) string {
return o.GroupVersionKind().Kind
})
t.AddColumn("VERSION", func(o *unstructured.Unstructured) string {
s, _, _ := unstructured.NestedString(o.Object, "spec", "version")
return s
})
return t.Render(addons, out, "NAME", "KIND", "VERSION")
}

View File

@ -14,6 +14,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/yaml:go_default_library",
],
)

View File

@ -26,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
kubeyaml "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/install"
"k8s.io/kops/pkg/apis/kops/v1alpha2"
@ -40,13 +41,6 @@ func init() {
install.Install(Scheme)
}
func decoder() runtime.Decoder {
// TODO: Cache?
// Codecs provides access to encoding and decoding for the scheme
codec := Codecs.UniversalDecoder(kops.SchemeGroupVersion)
return codec
}
// ToVersionedYaml encodes the object to YAML
func ToVersionedYaml(obj runtime.Object) ([]byte, error) {
return ToVersionedYamlWithVersion(obj, v1alpha2.SchemeGroupVersion)
@ -92,12 +86,29 @@ func ToVersionedJSONWithVersion(obj runtime.Object, version runtime.GroupVersion
// Decode decodes the specified data, with the specified default version
func Decode(data []byte, defaultReadVersion *schema.GroupVersionKind) (runtime.Object, *schema.GroupVersionKind, error) {
data = rewriteAPIGroup(data)
u := &unstructured.Unstructured{}
decoder := decoder()
// First decode into unstructured.Unstructured so we get the GVK
unstructuredDecoder := kubeyaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme)
obj, gvk, err := unstructuredDecoder.Decode(data, nil, u)
if err != nil {
return obj, gvk, err
}
object, gvk, err := decoder.Decode(data, defaultReadVersion, nil)
return object, gvk, err
// If this isn't a kOps type, return it as unstructured
if gvk.Group != "kops.k8s.io" && gvk.Group != "kops" {
return u, gvk, nil
}
// Remap the "kops" group => kops.k8s.io
if gvk.Group == "kops" {
data = rewriteAPIGroup(data)
}
// Decode into kops types
// TODO: Cache kopsDecoder?
kopsDecoder := Codecs.UniversalDecoder(kops.SchemeGroupVersion)
return kopsDecoder.Decode(data, defaultReadVersion, nil)
}
// rewriteAPIGroup rewrites the apiVersion from kops/v1alphaN -> kops.k8s.io/v1alphaN

View File

@ -0,0 +1,18 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"meta.go",
"yaml.go",
],
importmap = "k8s.io/kops/vendor/k8s.io/apimachinery/pkg/runtime/serializer/yaml",
importpath = "k8s.io/apimachinery/pkg/runtime/serializer/yaml",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//vendor/sigs.k8s.io/yaml:go_default_library",
],
)

View File

@ -0,0 +1,50 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package yaml
import (
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/yaml"
)
// DefaultMetaFactory is a default factory for versioning objects in JSON or
// YAML. The object in memory and in the default serialization will use the
// "kind" and "apiVersion" fields.
var DefaultMetaFactory = SimpleMetaFactory{}
// SimpleMetaFactory provides default methods for retrieving the type and version of objects
// that are identified with an "apiVersion" and "kind" fields in their JSON
// serialization. It may be parameterized with the names of the fields in memory, or an
// optional list of base structs to search for those fields in memory.
type SimpleMetaFactory struct{}
// Interpret will return the APIVersion and Kind of the JSON wire-format
// encoding of an object, or an error.
func (SimpleMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error) {
gvk := runtime.TypeMeta{}
if err := yaml.Unmarshal(data, &gvk); err != nil {
return nil, fmt.Errorf("could not interpret GroupVersionKind; unmarshal error: %v", err)
}
gv, err := schema.ParseGroupVersion(gvk.APIVersion)
if err != nil {
return nil, err
}
return &schema.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: gvk.Kind}, nil
}

View File

@ -0,0 +1,46 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package yaml
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/yaml"
)
// yamlSerializer converts YAML passed to the Decoder methods to JSON.
type yamlSerializer struct {
// the nested serializer
runtime.Serializer
}
// yamlSerializer implements Serializer
var _ runtime.Serializer = yamlSerializer{}
// NewDecodingSerializer adds YAML decoding support to a serializer that supports JSON.
func NewDecodingSerializer(jsonSerializer runtime.Serializer) runtime.Serializer {
return &yamlSerializer{jsonSerializer}
}
func (c yamlSerializer) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
out, err := yaml.ToJSON(data)
if err != nil {
return nil, nil, err
}
data = out
return c.Serializer.Decode(data, gvk, into)
}

1
vendor/modules.txt generated vendored
View File

@ -1143,6 +1143,7 @@ k8s.io/apimachinery/pkg/runtime/serializer/protobuf
k8s.io/apimachinery/pkg/runtime/serializer/recognizer
k8s.io/apimachinery/pkg/runtime/serializer/streaming
k8s.io/apimachinery/pkg/runtime/serializer/versioning
k8s.io/apimachinery/pkg/runtime/serializer/yaml
k8s.io/apimachinery/pkg/selection
k8s.io/apimachinery/pkg/types
k8s.io/apimachinery/pkg/util/cache