Last active
July 23, 2019 03:26
-
-
Save alexeldeib/d9743896c2c8b6237ee05872dbee7618 to your computer and use it in GitHub Desktop.
Kubernetes deploy arbitrary runtime object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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