Skip to content

Instantly share code, notes, and snippets.

@alexeldeib
Last active July 23, 2019 03:26
Show Gist options
  • Save alexeldeib/d9743896c2c8b6237ee05872dbee7618 to your computer and use it in GitHub Desktop.
Save alexeldeib/d9743896c2c8b6237ee05872dbee7618 to your computer and use it in GitHub Desktop.
Kubernetes deploy arbitrary runtime object
package main
import (
"context"
"fmt"
"io/ioutil"
"strings"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
func main() error {
config, err := ctrl.GetConfig()
if err != nil {
return errors.Wrap(err, "failed to get kubeconfig")
}
client, err := client.New(config, client.Options{})
if err != nil {
return errors.Wrap(err, "failed to create kubeclient")
}
// Assume `file` contains the output of Kustomization (i.e., multiple k8s resources in some desired order)
allResources, err := ioutil.ReadFile(file)
if err != nil {
return errors.Wrap(err, "failed to read resources file")
}
resources := strings.Split(string(allResources), "---")
errs := make([]error, 0)
// resourceErrors := map[string]error{}
for _, resource := range resources {
// scheme should contain all of the types you want to use in your client.
// this scheme is the default Kubernetes scheme with most core types.
// to add custom types, do something like `customTypev1alpha1.AddToScheme(scheme)
decode := scheme.Codecs.UniversalDeserializer().Decode
obj, _, err := decode([]byte(resource), nil, nil)
// TODO(ace): can switch here like this for type specific behavior:
// switch o := obj.(type) {
// case *v1.Pod:
// // o is a pod
// case *v1beta1.Role:
// // o is the actual role Object with all fields etc
// case *v1beta1.RoleBinding:
// case *v1beta1.ClusterRole:
// case *v1beta1.ClusterRoleBinding:
// case *v1.ServiceAccount:
// default:
// //o is unknown f
if err != nil {
errs = append(errs, err)
// return err
}
_, err = controllerutil.CreateOrUpdate(context.Background(), client, obj, controllerutil.MutateFn(func() error { return nil })) // this func can mutate an object and return errors, etc
if err != nil {
errs = append(errs, err)
// return errors.Wrap(err, "failed reconcile")
}
}
if len(errs) == 1 {
return errs[0]
}
if len(errs) > 1 {
for _, err := range errs {
fmt.Printf("ERROR: %s\n\n", errors.WithStack(err))
}
return errors.New("multiple errors deploying kubernetes objects")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment