Merge "Sample consumer to get kafka broker from ICS"
[nonrtric.git] / service-exposure / rapps-istio-mgr.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         "bytes"
24         "context"
25         "fmt"
26         netv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
27         netv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
28         secv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
29         versioned "istio.io/client-go/pkg/clientset/versioned"
30         metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31         k8Yaml "k8s.io/apimachinery/pkg/util/yaml"
32         "k8s.io/client-go/rest"
33         clientcmd "k8s.io/client-go/tools/clientcmd"
34         "log"
35         "net/http"
36         "os"
37         "path/filepath"
38         "text/template"
39 )
40
41 const (
42         NAMESPACE = "istio-nonrtric"
43 )
44
45 type TemplateConfig struct {
46         Name          string
47         Namespace     string
48         Realm         string
49         Client        string
50         Authenticator string
51         Role          string
52         Method        string
53         TlsCrt        string
54         TlsKey        string
55         CaCrt         string
56 }
57
58 var inputs TemplateConfig
59 var appName string
60
61 var config *template.Template
62
63 func connectToK8s() *versioned.Clientset {
64         config, err := rest.InClusterConfig()
65         if err != nil {
66                 // fallback to kubeconfig
67                 home, exists := os.LookupEnv("HOME")
68                 if !exists {
69                         home = "/root"
70                 }
71
72                 kubeconfig := filepath.Join(home, ".kube", "config")
73                 if envvar := os.Getenv("KUBECONFIG"); len(envvar) > 0 {
74                         kubeconfig = envvar
75                 }
76                 config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
77                 if err != nil {
78                         log.Fatalln("failed to create K8s config")
79                 }
80         }
81
82         ic, err := versioned.NewForConfig(config)
83         if err != nil {
84                 log.Fatalf("Failed to create istio client: %s", err)
85         }
86
87         return ic
88 }
89
90 func createGateway(clientset *versioned.Clientset) (string, error) {
91         gtClient := clientset.NetworkingV1beta1().Gateways(NAMESPACE)
92         config = template.Must(template.ParseFiles("./templates/Gateway-template.txt"))
93         var manifest bytes.Buffer
94         err := config.Execute(&manifest, inputs)
95         if err != nil {
96                 return "", err
97         }
98
99         gt := &netv1beta1.Gateway{}
100         dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000)
101
102         if err := dec.Decode(&gt); err != nil {
103                 return "", err
104         }
105
106         result, err := gtClient.Create(context.TODO(), gt, metav1.CreateOptions{})
107
108         if err != nil {
109                 return "", err
110         }
111
112         fmt.Printf("Create Gateway %s \n", result.GetName())
113         return result.GetName(), nil
114 }
115
116 func createVirtualService(clientset *versioned.Clientset) (string, error) {
117         vsClient := clientset.NetworkingV1beta1().VirtualServices(NAMESPACE)
118         config = template.Must(template.ParseFiles("./templates/VirtualService-template.txt"))
119         var manifest bytes.Buffer
120         err := config.Execute(&manifest, inputs)
121         if err != nil {
122                 return "", err
123         }
124
125         vs := &netv1beta1.VirtualService{}
126         dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000)
127
128         if err := dec.Decode(&vs); err != nil {
129                 return "", err
130         }
131
132         result, err := vsClient.Create(context.TODO(), vs, metav1.CreateOptions{})
133
134         if err != nil {
135                 return "", err
136         }
137
138         fmt.Printf("Create Virtual Service %s \n", result.GetName())
139         return result.GetName(), nil
140 }
141
142 func createRequestAuthentication(clientset *versioned.Clientset) (string, error) {
143         raClient := clientset.SecurityV1beta1().RequestAuthentications(NAMESPACE)
144         config = template.Must(template.ParseFiles("./templates/RequestAuthentication-template.txt"))
145         var manifest bytes.Buffer
146         err := config.Execute(&manifest, inputs)
147         if err != nil {
148                 return "", err
149         }
150
151         ra := &secv1beta1.RequestAuthentication{}
152         dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000)
153
154         if err := dec.Decode(&ra); err != nil {
155                 return "", err
156         }
157
158         result, err := raClient.Create(context.TODO(), ra, metav1.CreateOptions{})
159
160         if err != nil {
161                 return "", err
162         }
163
164         fmt.Printf("Create Request Authentication %s \n", result.GetName())
165         return result.GetName(), nil
166 }
167
168 func createAuthorizationPolicy(clientset *versioned.Clientset) (string, error) {
169         apClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE)
170         config = template.Must(template.ParseFiles("./templates/AuthorizationPolicy-template.txt"))
171         var manifest bytes.Buffer
172         err := config.Execute(&manifest, inputs)
173         if err != nil {
174                 return "", err
175         }
176
177         ap := &secv1beta1.AuthorizationPolicy{}
178         dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000)
179
180         if err := dec.Decode(&ap); err != nil {
181                 return "", err
182         }
183
184         result, err := apClient.Create(context.TODO(), ap, metav1.CreateOptions{})
185
186         if err != nil {
187                 return "", err
188         }
189
190         fmt.Printf("Create Authorization Policy %s \n", result.GetName())
191         return result.GetName(), nil
192 }
193
194 func createEnvoyFilter(clientset *versioned.Clientset) (string, error) {
195         efClient := clientset.NetworkingV1alpha3().EnvoyFilters(NAMESPACE)
196         config = template.Must(template.ParseFiles("./templates/EnvoyFilter-template.txt"))
197         var manifest bytes.Buffer
198         err := config.Execute(&manifest, inputs)
199         if err != nil {
200                 return "", err
201         }
202
203         ef := &netv1alpha3.EnvoyFilter{}
204         dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000)
205
206         if err = dec.Decode(&ef); err != nil {
207                 return "", err
208         }
209
210         result, err := efClient.Create(context.TODO(), ef, metav1.CreateOptions{})
211
212         if err != nil {
213                 return "", err
214         }
215
216         fmt.Printf("Create Envoy Filter %s \n", result.GetName())
217         return result.GetName(), nil
218 }
219
220 func removeGateway(clientset *versioned.Clientset) {
221         gtClient := clientset.NetworkingV1beta1().Gateways(NAMESPACE)
222         err := gtClient.Delete(context.TODO(), "nonrtric-istio-"+appName+"-gateway", metav1.DeleteOptions{})
223         if err != nil {
224                 fmt.Println(err)
225         } else {
226                 fmt.Println("Deleted Gateway nonrtric-istio-" + appName + "-gateway")
227         }
228 }
229
230 func removeVirtualService(clientset *versioned.Clientset) {
231         vsClient := clientset.NetworkingV1beta1().VirtualServices(NAMESPACE)
232         err := vsClient.Delete(context.TODO(), "nonrtric-istio-"+appName+"-vs", metav1.DeleteOptions{})
233         if err != nil {
234                 fmt.Println(err)
235         } else {
236                 fmt.Println("Deleted VirtualServices nonrtric-istio-" + appName + "-vs")
237         }
238 }
239
240 func removeRequestAuthentication(clientset *versioned.Clientset) {
241         raClient := clientset.SecurityV1beta1().RequestAuthentications(NAMESPACE)
242         err := raClient.Delete(context.TODO(), "jwt-"+appName, metav1.DeleteOptions{})
243         if err != nil {
244                 fmt.Println(err)
245         } else {
246                 fmt.Println("Deleted RequestAuthentication jwt-" + appName)
247         }
248 }
249
250 func removeAuthorizationPolicy(clientset *versioned.Clientset) {
251         apClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE)
252         err := apClient.Delete(context.TODO(), appName+"-policy", metav1.DeleteOptions{})
253         if err != nil {
254                 fmt.Println(err)
255         } else {
256                 fmt.Println("Deleted AuthorizationPolicy " + appName + "-policy")
257         }
258 }
259
260 func removeEnvoyFilter(clientset *versioned.Clientset) {
261         efClient := clientset.NetworkingV1alpha3().EnvoyFilters(NAMESPACE)
262         err := efClient.Delete(context.TODO(), appName+"-outbound-filter", metav1.DeleteOptions{})
263         if err != nil {
264                 fmt.Println(err)
265         } else {
266                 fmt.Println("Deleted EnvoyFilter " + appName + "-outbound-filter")
267         }
268 }
269
270 func createIstioPolicy(res http.ResponseWriter, req *http.Request) {
271         query := req.URL.Query()
272         realmName := query.Get("realm")
273         appName := query.Get("name")
274         roleName := query.Get("role")
275         methodName := query.Get("method")
276         inputs = TemplateConfig{Name: appName, Namespace: NAMESPACE, Realm: realmName, Role: roleName, Method: methodName}
277         var msg string
278         clientset := connectToK8s()
279         _, err := createGateway(clientset)
280         if err != nil {
281                 msg = err.Error()
282                 fmt.Println(err.Error())
283         } else {
284                 _, err := createVirtualService(clientset)
285                 if err != nil {
286                         msg = err.Error()
287                         fmt.Println(err.Error())
288                 } else {
289                         _, err := createRequestAuthentication(clientset)
290                         if err != nil {
291                                 msg = err.Error()
292                                 fmt.Println(err.Error())
293                         } else {
294                                 _, err := createAuthorizationPolicy(clientset)
295                                 if err != nil {
296                                         msg = err.Error()
297                                         fmt.Println(err.Error())
298                                 } else {
299                                         msg = "Istio rapp security setup successfully"
300                                 }
301                         }
302                 }
303         }
304
305         // create response binary data
306         data := []byte(msg) // slice of bytes
307         // write `data` to response
308         res.Write(data)
309 }
310
311 func createIstioFilter(res http.ResponseWriter, req *http.Request) {
312         query := req.URL.Query()
313         realmName := query.Get("realm")
314         clientId := query.Get("client")
315         appName := query.Get("name")
316         authType := query.Get("authType")
317         tlsCrt := query.Get("tlsCrt")
318         tlsKey := query.Get("tlsKey")
319         caCrt := query.Get("caCrt")
320         inputs = TemplateConfig{Name: appName, Namespace: NAMESPACE, Realm: realmName, Client: clientId,
321                 Authenticator: authType, TlsCrt: tlsCrt, TlsKey: tlsKey, CaCrt: caCrt}
322         var msg string
323         clientset := connectToK8s()
324         _, err := createEnvoyFilter(clientset)
325         if err != nil {
326                 msg = err.Error()
327                 fmt.Println(err.Error())
328         }
329         // create response binary data
330         data := []byte(msg) // slice of bytes
331         // write `data` to response
332         res.Write(data)
333 }
334
335 func removeIstioPolicy(res http.ResponseWriter, req *http.Request) {
336         query := req.URL.Query()
337         appName = query.Get("name")
338         clientset := connectToK8s()
339         removeAuthorizationPolicy(clientset)
340         removeRequestAuthentication(clientset)
341         removeVirtualService(clientset)
342         removeGateway(clientset)
343 }
344
345 func removeIstioFilter(res http.ResponseWriter, req *http.Request) {
346         query := req.URL.Query()
347         appName = query.Get("name")
348         clientset := connectToK8s()
349         removeEnvoyFilter(clientset)
350 }
351
352 func main() {
353         createIstioPolicyHandler := http.HandlerFunc(createIstioPolicy)
354         http.Handle("/create-policy", createIstioPolicyHandler)
355         removeIstioPolicyHandler := http.HandlerFunc(removeIstioPolicy)
356         http.Handle("/remove-policy", removeIstioPolicyHandler)
357         createIstioFilterHandler := http.HandlerFunc(createIstioFilter)
358         http.Handle("/create-filter", createIstioFilterHandler)
359         removeIstioFilterHandler := http.HandlerFunc(removeIstioFilter)
360         http.Handle("/remove-filter", removeIstioFilterHandler)
361         http.ListenAndServe(":9000", nil)
362 }