blob: 4dc73591678aeb6aeea474cdde438b159e939669 [file] [log] [blame]
ktimoney3570d5a2022-05-24 13:54:55 +01001// -
2// ========================LICENSE_START=================================
3// O-RAN-SC
4// %%
5// Copyright (C) 2022: Nordix Foundation
6// %%
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License at
10//
11// http://www.apache.org/licenses/LICENSE-2.0
12//
13// Unless required by applicable law or agreed to in writing, software
14// distributed under the License is distributed on an "AS IS" BASIS,
15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16// See the License for the specific language governing permissions and
17// limitations under the License.
18// ========================LICENSE_END===================================
19//
20
ktimoneyf27b5132022-03-07 16:48:47 +000021package main
22
23import (
24 "bytes"
25 "context"
26 "encoding/json"
27 "flag"
28 "fmt"
29 "io/ioutil"
30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31 kubernetes "k8s.io/client-go/kubernetes"
32 "k8s.io/client-go/rest"
33 "net/http"
34 "net/url"
35 "strings"
36 "time"
37)
38
39type Jwttoken struct {
40 Access_token string
41 Expires_in int
42 Refresh_expires_in int
43 Refresh_token string
44 Token_type string
45 Not_before_policy int
46 Session_state string
47 Scope string
48}
49
50var gatewayHost string
51var gatewayPort string
52var keycloakHost string
53var keycloakPort string
54var securityEnabled string
55var useGateway string
56var role string
57var rapp string
58var methods string
59var healthy bool = true
60var ttime time.Time
61var jwt Jwttoken
62
63const (
64 namespace = "istio-nonrtric"
65)
66
67func getToken(secretName string) string {
68 if ttime.Before(time.Now()) {
69 clientSecret, clientId, realmName := getSecret(secretName)
70 keycloakUrl := "http://" + keycloakHost + ":" + keycloakPort + "/auth/realms/" + realmName + "/protocol/openid-connect/token"
71 resp, err := http.PostForm(keycloakUrl,
72 url.Values{"client_secret": {clientSecret}, "grant_type": {"client_credentials"}, "client_id": {clientId}})
73 if err != nil {
74 fmt.Println(err)
75 panic("Something wrong with the credentials or url ")
76 }
77 defer resp.Body.Close()
78 body, err := ioutil.ReadAll(resp.Body)
79 json.Unmarshal([]byte(body), &jwt)
80 ttime = time.Now()
81 ttime = ttime.Add(time.Second * time.Duration(jwt.Expires_in))
82 }
83 return jwt.Access_token
84}
85
86func getSecret(secretName string) (string, string, string) {
87 clientset := connectToK8s()
88 res, err := clientset.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, metav1.GetOptions{})
89 if err != nil {
90 fmt.Println(err.Error())
91 }
92 return string(res.Data["client_secret"]), string(res.Data["client_id"]), string(res.Data["realm"])
93}
94
95func MakeRequest(client *http.Client, prefix string, method string, ch chan string) {
96 var service = strings.Split(prefix, "/")[1]
97 var gatewayUrl = "http://" + gatewayHost + ":" + gatewayPort
98 var token = ""
99 var jsonValue []byte = []byte{}
100 var restUrl string = ""
101
ktimoney8ead72a2022-04-12 15:10:10 +0100102 if securityEnabled == "true" {
ktimoneyf27b5132022-03-07 16:48:47 +0000103 secretName := role + "-secret"
104 token = getToken(secretName)
105 } else {
106 useGateway = "N"
107 }
108
109 if strings.ToUpper(useGateway) != "Y" {
110 gatewayUrl = "http://" + service + "."+namespace+":80"
111 prefix = ""
112 }
113
114 restUrl = gatewayUrl + prefix
115
116 req, err := http.NewRequest(method, restUrl, bytes.NewBuffer(jsonValue))
117 if err != nil {
118 fmt.Printf("Got error %s", err.Error())
119 }
120 req.Header.Set("Content-type", "application/json")
121 req.Header.Set("Authorization", "Bearer "+token)
122
123 resp, err := client.Do(req)
124 if err != nil {
125 fmt.Printf("Got error %s", err.Error())
126 }
127 defer resp.Body.Close()
128 body, _ := ioutil.ReadAll(resp.Body)
129 respString := string(body[:])
130 if respString == "RBAC: access denied" {
131 respString += " for " + service + " " + strings.ToLower(method) + " request"
132 }
133 fmt.Printf("Received response for %s %s request - %s\n", service, strings.ToLower(method), respString)
134 ch <- prefix + "," + method
135}
136
137func connectToK8s() *kubernetes.Clientset {
138 config, err := rest.InClusterConfig()
139 if err != nil {
140 fmt.Println("failed to create K8s config")
141 }
142
143 clientset, err := kubernetes.NewForConfig(config)
144 if err != nil {
145 fmt.Println("Failed to create K8s clientset")
146 }
147
148 return clientset
149}
150
151func health(res http.ResponseWriter, req *http.Request) {
152 if healthy {
153 res.WriteHeader(http.StatusOK)
154 res.Write([]byte("healthy"))
155 } else {
156 res.WriteHeader(http.StatusInternalServerError)
157 res.Write([]byte("unhealthy"))
158 }
159}
160
161func main() {
162 ttime = time.Now()
163 time.Sleep(1 * time.Second)
164 flag.StringVar(&gatewayHost, "gatewayHost", "istio-ingressgateway.istio-system", "Gateway Host")
165 flag.StringVar(&gatewayPort, "gatewayPort", "80", "Gateway Port")
ktimoney8ead72a2022-04-12 15:10:10 +0100166 flag.StringVar(&keycloakHost, "keycloakHost", "istio-ingressgateway.istio-system", "Keycloak Host")
167 flag.StringVar(&keycloakPort, "keycloakPort", "80", "Keycloak Port")
ktimoneyf27b5132022-03-07 16:48:47 +0000168 flag.StringVar(&useGateway, "useGateway", "Y", "Connect to services through API gateway")
169 flag.StringVar(&securityEnabled, "securityEnabled", "true", "Security is required to use this application")
170 flag.StringVar(&role, "role", "provider-viewer", "Role granted to application")
171 flag.StringVar(&rapp, "rapp", "rapp-provider", "Name of rapp to invoke")
172 flag.StringVar(&methods, "methods", "GET", "Methods to access application")
173 flag.Parse()
174
175 healthHandler := http.HandlerFunc(health)
176 http.Handle("/health", healthHandler)
177 go func() {
178 http.ListenAndServe(":9000", nil)
179 }()
180
181 client := &http.Client{
182 Timeout: time.Second * 10,
183 }
184
185 ch := make(chan string)
186 var prefixArray []string = []string{"/" + rapp}
187 var methodArray []string = []string{methods}
188 for _, prefix := range prefixArray {
189 for _, method := range methodArray {
190 go MakeRequest(client, prefix, method, ch)
191 }
192 }
193
194 ioutil.WriteFile("init.txt", []byte("Initialization done."), 0644)
195
196 for r := range ch {
197 go func(resp string) {
198 time.Sleep(10 * time.Second)
199 elements := strings.Split(resp, ",")
200 prefix := elements[0]
201 method := elements[1]
202 MakeRequest(client, prefix, method, ch)
203 }(r)
204 }
205
206}