Merge "Sample consumer to get kafka broker from ICS"
[nonrtric.git] / service-exposure / rapps-webhook.go
1 // -
2 //
3 //      ========================LICENSE_START=================================
4 //      O-RAN-SC
5 //      %%
6 //      Copyright (C) 2022-2023: Nordix Foundation
7 //      %%
8 //      Licensed under the Apache License, Version 2.0 (the "License");
9 //      you may not use this file except in compliance with the License.
10 //      You may obtain a copy of the License at
11 //
12 //           http://www.apache.org/licenses/LICENSE-2.0
13 //
14 //      Unless required by applicable law or agreed to in writing, software
15 //      distributed under the License is distributed on an "AS IS" BASIS,
16 //      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 //      See the License for the specific language governing permissions and
18 //      limitations under the License.
19 //      ========================LICENSE_END===================================
20 package main
21
22 import (
23         "encoding/json"
24         "errors"
25         "flag"
26         "fmt"
27         "io/ioutil"
28         "k8s.io/api/admission/v1beta1"
29         v1 "k8s.io/api/core/v1"
30         "k8s.io/apimachinery/pkg/runtime"
31         "k8s.io/apimachinery/pkg/runtime/serializer"
32         "log"
33         "net/http"
34 )
35
36 type ServerParameters struct {
37         port     string // webhook server port
38         certFile string // path to the x509 cert
39         keyFile  string // path to the x509 private key
40         secret   string
41 }
42
43 type patchOperation struct {
44         Op    string      `json:"op"`
45         Path  string      `json:"path"`
46         Value interface{} `json:"value,omitempty"`
47 }
48
49 var parameters ServerParameters
50
51 var (
52         universalDeserializer = serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer()
53 )
54
55 func main() {
56         flag.StringVar(&parameters.port, "port", "8443", "Webhook server port.")
57         flag.StringVar(&parameters.certFile, "tlsCertFile", "/certs/tls.crt", "File containing the x509 certificate")
58         flag.StringVar(&parameters.keyFile, "tlsKeyFile", "/certs/tls.key", "File containing the x509 private key")
59         flag.StringVar(&parameters.secret, "secret", "cm-keycloak-client-certs", "Secret containing rapp cert files")
60         flag.Parse()
61
62         http.HandleFunc("/inject-sidecar", HandleSideCarInjection)
63         log.Fatal(http.ListenAndServeTLS(":"+parameters.port, parameters.certFile, parameters.keyFile, nil))
64 }
65
66 func HandleSideCarInjection(w http.ResponseWriter, r *http.Request) {
67
68         body, err := ioutil.ReadAll(r.Body)
69         err = ioutil.WriteFile("/tmp/request", body, 0644)
70         if err != nil {
71                 panic(err.Error())
72         }
73
74         var admissionReviewReq v1beta1.AdmissionReview
75
76         if _, _, err := universalDeserializer.Decode(body, nil, &admissionReviewReq); err != nil {
77                 w.WriteHeader(http.StatusBadRequest)
78                 fmt.Errorf("Could not deserialize request: %v", err)
79         } else if admissionReviewReq.Request == nil {
80                 w.WriteHeader(http.StatusBadRequest)
81                 errors.New("Malformed admission review - request is empty")
82         }
83
84         fmt.Printf("Received Admission Review Request - Type: %v \t Event: %v \t Name: %v \n",
85                 admissionReviewReq.Request.Kind,
86                 admissionReviewReq.Request.Operation,
87                 admissionReviewReq.Request.Name,
88         )
89
90         var pod v1.Pod
91
92         err = json.Unmarshal(admissionReviewReq.Request.Object.Raw, &pod)
93
94         if err != nil {
95                 fmt.Errorf("Could not unmarshal pod from admission request: %v", err)
96         }
97
98         var patches []patchOperation
99
100         labels := pod.ObjectMeta.Labels
101         labels["sidecar-injection-webhook"] = "jwt-proxy"
102
103         patches = append(patches, patchOperation{
104                 Op:    "add",
105                 Path:  "/metadata/labels",
106                 Value: labels,
107         })
108
109         var containers []v1.Container
110         containers = append(containers, pod.Spec.Containers...)
111         container := v1.Container{
112                 Name:            "jwt-proxy",
113                 Image:           "ktimoney/rapps-jwt",
114                 ImagePullPolicy: v1.PullIfNotPresent,
115                 Ports: []v1.ContainerPort{
116                         {
117                                 Name:          "http",
118                                 Protocol:      v1.ProtocolTCP,
119                                 ContainerPort: 8888,
120                         },
121                 },
122                 VolumeMounts: []v1.VolumeMount{
123                         {
124                                 Name:      "certsdir",
125                                 MountPath: "/certs",
126                                 ReadOnly:  true,
127                         },
128                 },
129         }
130
131         containers = append(containers, container)
132         fmt.Println(containers)
133
134         patches = append(patches, patchOperation{
135                 Op:    "add",
136                 Path:  "/spec/containers",
137                 Value: containers,
138         })
139
140         var volumes []v1.Volume
141         volumes = append(volumes, pod.Spec.Volumes...)
142         volume := v1.Volume{
143                 Name: "certsdir",
144                 VolumeSource: v1.VolumeSource{
145                         Secret: &v1.SecretVolumeSource{
146                                 SecretName: parameters.secret,
147                         },
148                 },
149         }
150         volumes = append(volumes, volume)
151         fmt.Println(volumes)
152
153         patches = append(patches, patchOperation{
154                 Op:    "add",
155                 Path:  "/spec/volumes",
156                 Value: volumes,
157         })
158         fmt.Println(patches)
159
160         patchBytes, err := json.Marshal(patches)
161
162         if err != nil {
163                 fmt.Errorf("Error occurred when trying to marshal JSON patch: %v", err)
164         }
165
166         admissionReviewResponse := v1beta1.AdmissionReview{
167                 Response: &v1beta1.AdmissionResponse{
168                         UID:     admissionReviewReq.Request.UID,
169                         Allowed: true,
170                 },
171         }
172
173         admissionReviewResponse.Response.Patch = patchBytes
174
175         bytes, err := json.Marshal(&admissionReviewResponse)
176         if err != nil {
177                 fmt.Errorf("Error occurred when trying to marshal Aadmission Review response: %v", err)
178         }
179
180         w.Write(bytes)
181
182 }