Advertisement
Guest User

Untitled

a guest
Jul 16th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 4.33 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "encoding/json"
  5.     "fmt"
  6.     "github.com/networkservicemesh/networkservicemesh/pkg/tools"
  7.     "github.com/networkservicemesh/networkservicemesh/sdk/client"
  8.     "github.com/sirupsen/logrus"
  9.     admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
  10.     corev1 "k8s.io/api/core/v1"
  11.     "k8s.io/apimachinery/pkg/api/resource"
  12.     metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  13.     "k8s.io/apimachinery/pkg/runtime"
  14.     "k8s.io/apimachinery/pkg/runtime/serializer"
  15.     "k8s.io/kubernetes/pkg/apis/core/v1"
  16. )
  17.  
  18. const (
  19.     certFile = "/etc/webhook/certs/cert.pem"
  20.     keyFile  = "/etc/webhook/certs/key.pem"
  21. )
  22.  
  23. type patchOperation struct {
  24.     Op    string      `json:"op"`
  25.     Path  string      `json:"path"`
  26.     Value interface{} `json:"value,omitempty"`
  27. }
  28.  
  29. var (
  30.     deserializer      runtime.Decoder
  31.     ignoredNamespaces = []string{
  32.         metav1.NamespaceSystem,
  33.         metav1.NamespacePublic,
  34.     }
  35.  
  36.     repo          string
  37.     initContainer string
  38.     tag           string
  39. )
  40.  
  41. const (
  42.     nsmAnnotationKey = "ns.networkservicemesh.io"
  43.  
  44.     repoEnv          = "REPO"
  45.     initContainerEnv = "INITCONTAINER"
  46.     tagEnv           = "TAG"
  47.  
  48.     repoDefault          = "networkservicemesh"
  49.     initContainerDefault = "nsm-init"
  50.     tagDefault           = "latest"
  51.  
  52.     initContainerName = "nsm-init-container"
  53.  
  54.     pathDeploymentSpec = "/spec/template/spec"
  55.     pathPodSpec        = "/spec"
  56. )
  57.  
  58. func init() {
  59.     runtimeScheme := runtime.NewScheme()
  60.     _ = corev1.AddToScheme(runtimeScheme)
  61.     _ = admissionregistrationv1beta1.AddToScheme(runtimeScheme)
  62.     // defaulting with webhooks:
  63.     // https://github.com/kubernetes/kubernetes/issues/57982
  64.     _ = v1.AddToScheme(runtimeScheme)
  65.  
  66.     deserializer = serializer.NewCodecFactory(runtimeScheme).UniversalDeserializer()
  67. }
  68.  
  69. func getAnnotationValue(ignoredNamespaceList []string, metadata *metav1.ObjectMeta, spec *corev1.PodSpec) (string, bool) {
  70.  
  71.     // check if InitContainer already injected
  72.     for i := range spec.InitContainers {
  73.         c := &spec.InitContainers[i]
  74.         if c.Name == initContainerName {
  75.             return "", false
  76.         }
  77.     }
  78.  
  79.     // skip special kubernetes system namespaces
  80.     for _, namespace := range ignoredNamespaceList {
  81.         if metadata.Namespace == namespace {
  82.             logrus.Infof("Skip validation for %v for it's in special namespace:%v", metadata.Name, metadata.Namespace)
  83.             return "", false
  84.         }
  85.     }
  86.  
  87.     annotations := metadata.GetAnnotations()
  88.     if annotations == nil {
  89.         return "", false
  90.     }
  91.  
  92.     value, ok := annotations[nsmAnnotationKey]
  93.     return value, ok
  94. }
  95.  
  96. func validateAnnotationValue(value string) error {
  97.     urls, err := tools.ParseAnnotationValue(value)
  98.     logrus.Infof("Annotation nsurls: %v", urls)
  99.     return err
  100. }
  101.  
  102. func createPatch(podSpec *corev1.PodSpec, annotationValue, pathToSpec string) ([]byte, error) {
  103.     var patch []patchOperation
  104.     patch = append(patch, patchOperation{
  105.         Op:   "add",
  106.         Path: pathToSpec + "/initContainers",
  107.         Value: []corev1.Container{
  108.             {
  109.                 Name:            initContainerName,
  110.                 Image:           fmt.Sprintf("%s/%s:%s", repo, initContainer, tag),
  111.                 ImagePullPolicy: corev1.PullIfNotPresent,
  112.                 Env: []corev1.EnvVar{
  113.                     {
  114.                         Name:  client.AnnotationEnv,
  115.                         Value: annotationValue,
  116.                     },
  117.                 },
  118.                 VolumeMounts: []corev1.VolumeMount{
  119.                     {
  120.                         Name:      "spire-agent-socket",
  121.                         MountPath: "/run/spire/sockets",
  122.                         ReadOnly:  true,
  123.                     },
  124.                 },
  125.                 Resources: corev1.ResourceRequirements{
  126.                     Limits: corev1.ResourceList{
  127.                         "networkservicemesh.io/socket": resource.NewQuantity(1, resource.DecimalSI).DeepCopy(),
  128.                     },
  129.                 },
  130.             },
  131.         },
  132.     })
  133.  
  134.     ht := new(corev1.HostPathType)
  135.     *ht = corev1.HostPathDirectoryOrCreate
  136.  
  137.     patch = append(patch, addVolume(podSpec.Volumes, []corev1.Volume{
  138.         {
  139.             Name: "spire-agent-socket",
  140.             VolumeSource: corev1.VolumeSource{
  141.                 HostPath: &corev1.HostPathVolumeSource{
  142.                     Path: "/run/spire/sockets",
  143.                     Type: ht,
  144.                 },
  145.             },
  146.         },
  147.     }, pathToSpec+"/volumes")...)
  148.  
  149.     return json.Marshal(patch)
  150. }
  151.  
  152. func addVolume(target, added []corev1.Volume, basePath string) (patch []patchOperation) {
  153.     first := len(target) == 0
  154.     var value interface{}
  155.     for _, add := range added {
  156.         value = add
  157.         path := basePath
  158.         if first {
  159.             first = false
  160.             value = []corev1.Volume{add}
  161.         } else {
  162.             path = path + "/-"
  163.         }
  164.         patch = append(patch, patchOperation{
  165.             Op:    "add",
  166.             Path:  path,
  167.             Value: value,
  168.         })
  169.     }
  170.     return patch
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement