Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Kubernetes client to support add-ons #617

Merged
merged 3 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 62 additions & 6 deletions pkg/addons/default/helpers.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,79 @@
package defaultaddons

import (
"bytes"
"io"
"strings"

"github.com/pkg/errors"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/kubernetes/scheme"

apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
)

func init() {
apiextensionsv1beta1.AddToScheme(scheme.Scheme)
}

// LoadAsset return embedded manifest as a runtime.Object
func LoadAsset(name string) (runtime.Object, error) {
data, err := Asset(name + ".yaml")
// TODO: we certainly need tests for this
func LoadAsset(name, ext string) (*metav1.List, error) {
data, err := Asset(name + "." + ext)
if err != nil {
return nil, errors.Wrapf(err, "decoding embedded manifest for %q", name)
}

obj, err := runtime.Decode(scheme.Codecs.UniversalDeserializer(), data)
if err != nil {
return nil, errors.Wrapf(err, "loading embedded manifest for %q", name)
list := metav1.List{}
decoder := yaml.NewYAMLOrJSONDecoder(bytes.NewBuffer(data), 4096)

for {
obj := new(runtime.RawExtension)
err := decoder.Decode(obj)
if err != nil {
if err == io.EOF {
return &list, nil
}
return nil, errors.Wrapf(err, "loading individual resources from manifest for %q", name)
}
// obj.Object, err = runtime.Decode(scheme.Codecs.UniversalDeserializer(), obj.Raw)
// if err != nil {
// return nil, errors.Wrapf(err, "converting object")
// }
// list.Items = append(list.Items, *obj)
if err := listAppendFlattened(&list, *obj); err != nil {
return nil, err
}
}
}

return obj, nil
// this was copied from kubegen
func listAppendFlattened(components *metav1.List, component runtime.RawExtension) error {
if component.Object != nil {
if strings.HasSuffix(component.Object.GetObjectKind().GroupVersionKind().Kind, "List") {
// must use corev1, as it panics on obj.(*metav1.List) with
// an amusing error message saying that *v1.List is not *v1.List
// TODO: test this to find out if the conversion is still required
list := component.Object.(*corev1.List)
for _, item := range (*list).Items {
// we attempt to recurse here, but most likely
// we will have to try decoding component.Raw
if err := listAppendFlattened(components, item); err != nil {
return err
}
}
return nil
}
components.Items = append(components.Items, component)
return nil
}
obj, err := runtime.Decode(scheme.Codecs.UniversalDeserializer(), component.Raw)
if err != nil {
return errors.Wrapf(err, "converting object")
}
return listAppendFlattened(components, runtime.RawExtension{Object: obj})
}
6 changes: 3 additions & 3 deletions pkg/ctl/create/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,13 +490,13 @@ func doCreateCluster(p *api.ProviderConfig, cfg *api.ClusterConfig, nameArg stri
var kubeconfigContextName string

if writeKubeconfig {
clientConfig, err := ctl.NewClientConfig(cfg, false)
client, err := ctl.NewClient(cfg, false)
if err != nil {
return err
}
kubeconfigContextName = clientConfig.ContextName
kubeconfigContextName = client.ContextName

kubeconfigPath, err = kubeconfig.Write(kubeconfigPath, *clientConfig.Client, setContext)
kubeconfigPath, err = kubeconfig.Write(kubeconfigPath, *client.Config, setContext)
if err != nil {
return errors.Wrap(err, "writing kubeconfig")
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/ctl/utils/write_kubeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ func doWriteKubeconfigCmd(p *api.ProviderConfig, cfg *api.ClusterConfig, nameArg
return err
}

config, err := ctl.NewClientConfig(cfg, false)
client, err := ctl.NewClient(cfg, false)
if err != nil {
return err
}

filename, err := kubeconfig.Write(writeKubeconfigOutputPath, *config.Client, writeKubeconfigSetContext)
filename, err := kubeconfig.Write(writeKubeconfigOutputPath, *client.Config, writeKubeconfigSetContext)
if err != nil {
return errors.Wrap(err, "writing kubeconfig")
}
Expand Down
77 changes: 0 additions & 77 deletions pkg/eks/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,11 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/sts"

"github.com/kubernetes-sigs/aws-iam-authenticator/pkg/token"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/kops/pkg/pki"

api "github.com/weaveworks/eksctl/pkg/apis/eksctl.io/v1alpha4"
"github.com/weaveworks/eksctl/pkg/utils"
"github.com/weaveworks/eksctl/pkg/utils/kubeconfig"
)

func (c *ClusterProvider) getKeyPairName(clusterName string, ng *api.NodeGroup, fingerprint *string) string {
Expand Down Expand Up @@ -150,74 +144,3 @@ func (c *ClusterProvider) getUsername() string {
}
return "iam-root-account"
}

// ClientConfig stores information about the client config
type ClientConfig struct {
Client *clientcmdapi.Config
ContextName string
}

// NewClientConfig creates a new client config, if withEmbeddedToken is true
// it will embed the STS token, otherwise it will use authenticator exec plugin
// and ensures that AWS_PROFILE environment variable gets set also
func (c *ClusterProvider) NewClientConfig(spec *api.ClusterConfig, withEmbeddedToken bool) (*ClientConfig, error) {
client, _, contextName := kubeconfig.New(spec, c.getUsername(), "")

config := &ClientConfig{
Client: client,
ContextName: contextName,
}

if withEmbeddedToken {
if err := config.useEmbeddedToken(spec, c.Provider.STS().(*sts.STS)); err != nil {
return nil, err
}
} else {
kubeconfig.AppendAuthenticator(config.Client, spec, utils.DetectAuthenticator(), c.Provider.Profile())
}

return config, nil
}

func (c *ClientConfig) useEmbeddedToken(spec *api.ClusterConfig, sts *sts.STS) error {
gen, err := token.NewGenerator(true)
if err != nil {
return errors.Wrap(err, "could not get token generator")
}

tok, err := gen.GetWithSTS(spec.Metadata.Name, sts)
if err != nil {
return errors.Wrap(err, "could not get token")
}

c.Client.AuthInfos[c.ContextName].Token = tok
return nil
}

// NewClientSet creates a new API client
func (c *ClientConfig) NewClientSet() (*kubernetes.Clientset, error) {
clientConfig, err := clientcmd.NewDefaultClientConfig(*c.Client, &clientcmd.ConfigOverrides{}).ClientConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to create API client configuration from client config")
}

client, err := kubernetes.NewForConfig(clientConfig)
if err != nil {
return nil, errors.Wrap(err, "failed to create API client")
}
return client, nil
}

// NewStdClientSet creates a new API client in one go with an embedded STS token, this is most commonly used option
func (c *ClusterProvider) NewStdClientSet(spec *api.ClusterConfig) (*kubernetes.Clientset, error) {
clientConfig, err := c.NewClientConfig(spec, true)
if err != nil {
return nil, errors.Wrap(err, "creating Kubernetes client config with embedded token")
}

clientSet, err := clientConfig.NewClientSet()
if err != nil {
return nil, errors.Wrap(err, "creating Kubernetes client")
}
return clientSet, nil
}
6 changes: 3 additions & 3 deletions pkg/eks/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var _ = Describe("eks auth helpers", func() {
}

It("should create config with authenticator", func() {
clientConfig, err := ctl.NewClientConfig(cfg, false)
clientConfig, err := ctl.NewClient(cfg, false)

Expect(err).To(Not(HaveOccurred()))

Expand All @@ -50,7 +50,7 @@ var _ = Describe("eks auth helpers", func() {
cluster := strings.Split(ctx, "@")[1]
Expect(ctx).To(Equal("iam-root-account@auth-test-cluster.eu-west-3.eksctl.io"))

k := clientConfig.Client
k := clientConfig.Config

Expect(k.CurrentContext).To(Equal(ctx))

Expand Down Expand Up @@ -88,7 +88,7 @@ var _ = Describe("eks auth helpers", func() {
})

It("should create clientset", func() {
clientConfig, err := ctl.NewClientConfig(cfg, false)
clientConfig, err := ctl.NewClient(cfg, false)

Expect(err).To(Not(HaveOccurred()))
Expect(clientConfig).To(Not(BeNil()))
Expand Down
Loading