Skip to content

Instantly share code, notes, and snippets.

@NishanthSpShetty
Created February 11, 2022 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NishanthSpShetty/a1da2cd64d7f9b639a77402f0c27db03 to your computer and use it in GitHub Desktop.
Save NishanthSpShetty/a1da2cd64d7f9b639a77402f0c27db03 to your computer and use it in GitHub Desktop.
Apply kubernetes manifest yaml file using k8s golang client
package kubectl
import (
"context"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strings"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/restmapper"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func getObjectKind(obj runtime.Object) string {
switch obj.(type) {
case *appsv1.Deployment:
return "deployment"
case *rbacv1.ClusterRole:
return "clusterrole"
case *rbacv1.ClusterRoleBinding:
return "clusterrolebinding"
case *corev1.Secret:
return "secret"
case *corev1.Namespace:
return "namespace"
case *corev1.ServiceAccount:
return "serviceaccount"
default:
return "unknown"
}
}
func getObjectMap(byts []byte) [][]byte {
splits := strings.Split(string(byts), "---")
objectList := make([][]byte, 0, len(splits))
for _, v := range splits {
v = strings.TrimSpace(v)
if v == "" {
continue
}
objectList = append(objectList, []byte(v))
}
return objectList
}
func GetObjects(manifestData []byte) ([]runtime.Object, error) {
list := getObjectMap(manifestData)
m := make([]runtime.Object, 0, len(list))
for _, v := range list {
var Codec = serializer.NewCodecFactory(Scheme).
UniversalDecoder(Scheme.PrioritizedVersionsAllGroups()...)
//LegacyCodec(Scheme.PrioritizedVersionsAllGroups()...)
data, err := runtime.Decode(Codec, v)
if err != nil {
return nil, err
}
m = append(m, data)
}
return m, nil
}
func GetManifestFromURL(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
if resp.StatusCode == 200 {
byts, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
return byts, err
}
return nil, errors.New("failed to read yaml")
}
func Apply(ctx context.Context, client *kubernetes.Clientset, dynamicClient dynamic.Interface, objects []runtime.Object) error {
for _, obj := range objects {
gvk := obj.GetObjectKind().GroupVersionKind()
fmt.Printf("applying %+v\n ", gvk)
gk := schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}
groupResources, err := restmapper.GetAPIGroupResources(client.Discovery())
if err != nil {
return err
}
rm := restmapper.NewDiscoveryRESTMapper(groupResources)
mapping, err := rm.RESTMapping(gk, gvk.Version)
if err != nil {
return err
}
objMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil {
return err
}
resp, err := dynamicClient.Resource(mapping.Resource).Create(ctx, &unstructured.Unstructured{Object: objMap}, metav1.CreateOptions{})
if err != nil {
fmt.Println("failed to apply resources ...", err)
continue
}
fmt.Println(resp)
//result := client.RESTClient().Post().VersionedParams(obj, runtime.NewParameterCodec(Scheme)).Do(ctx)
//fmt.Printf("Err %+v --- %+v\n\n", result.Error(), result)
}
return nil
}
package kubectl
//There is a issue with importing schema from the k8s.io/api/pkg/scheme
//I dont have the patience to resolve that yet,
//so implementing the whole schema package for the codec
import (
admissionv1 "k8s.io/api/admission/v1"
admissionv1beta1 "k8s.io/api/admission/v1beta1"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
appsv1 "k8s.io/api/apps/v1"
appsv1beta1 "k8s.io/api/apps/v1beta1"
appsv1beta2 "k8s.io/api/apps/v1beta2"
authenticationv1 "k8s.io/api/authentication/v1"
authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
authorizationv1 "k8s.io/api/authorization/v1"
authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
autoscalingv1 "k8s.io/api/autoscaling/v1"
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
certificatesv1 "k8s.io/api/certificates/v1"
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
corev1 "k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
imagepolicyv1alpha1 "k8s.io/api/imagepolicy/v1alpha1"
networkingv1 "k8s.io/api/networking/v1"
policyv1 "k8s.io/api/policy/v1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
rbacv1 "k8s.io/api/rbac/v1"
rbacv1alpha1 "k8s.io/api/rbac/v1alpha1"
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1"
storagev1 "k8s.io/api/storage/v1"
storagev1beta1 "k8s.io/api/storage/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/kubernetes/scheme"
)
var Scheme = runtime.NewScheme()
func init() {
// Register external types for Scheme
metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(metav1beta1.AddMetaToScheme(Scheme))
utilruntime.Must(metav1.AddMetaToScheme(Scheme))
utilruntime.Must(scheme.AddToScheme(Scheme))
utilruntime.Must(Scheme.SetVersionPriority(corev1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(admissionv1beta1.SchemeGroupVersion, admissionv1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(admissionregistrationv1beta1.SchemeGroupVersion, admissionregistrationv1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(appsv1beta1.SchemeGroupVersion, appsv1beta2.SchemeGroupVersion, appsv1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(authenticationv1.SchemeGroupVersion, authenticationv1beta1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(authorizationv1.SchemeGroupVersion, authorizationv1beta1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(autoscalingv1.SchemeGroupVersion, autoscalingv2beta1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(batchv1.SchemeGroupVersion, batchv1beta1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(certificatesv1.SchemeGroupVersion, certificatesv1beta1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(extensionsv1beta1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(imagepolicyv1alpha1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(networkingv1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(policyv1beta1.SchemeGroupVersion, policyv1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(rbacv1.SchemeGroupVersion, rbacv1beta1.SchemeGroupVersion, rbacv1alpha1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(schedulingv1alpha1.SchemeGroupVersion))
utilruntime.Must(Scheme.SetVersionPriority(storagev1.SchemeGroupVersion, storagev1beta1.SchemeGroupVersion))
}
@NishanthSpShetty
Copy link
Author

lightweight implementation of kubectl apply -f some.yaml using go client

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment