blob: bcbbbeb5c76e17a0bc559f0254a4698a71cbc4c2 [file] [log] [blame]
ktimoney6be05292022-03-02 12:53:14 +00001package main
2
3import (
4 "bytes"
5 "context"
6 "fmt"
7 netv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
8 secv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
9 versioned "istio.io/client-go/pkg/clientset/versioned"
10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11 k8Yaml "k8s.io/apimachinery/pkg/util/yaml"
12 "k8s.io/client-go/rest"
13 clientcmd "k8s.io/client-go/tools/clientcmd"
14 "log"
15 "net/http"
16 "os"
17 "path/filepath"
18)
19
20const (
21 NAMESPACE = "istio-nonrtric"
22)
23
24const gatewayManifest = `
25apiVersion: networking.istio.io/v1beta1
26kind: Gateway
27metadata:
28 name: nonrtric-istio-hw-gateway
29 namespace: istio-nonrtric
30spec:
31 selector:
32 istio: ingressgateway # use Istio gateway implementation
33 servers:
34 - port:
35 number: 80
36 name: http
37 protocol: HTTP
38 hosts:
39 - "*"
40`
41
42const virtualServiceManifest = `
43apiVersion: networking.istio.io/v1beta1
44kind: VirtualService
45metadata:
46 name: nonrtric-istio-hw-vs
47 namespace: istio-nonrtric
48spec:
49 hosts:
50 - "*"
51 gateways:
52 - nonrtric-istio-hw-gateway
53 http:
54 - name: "hello-world-routes"
55 match:
56 - uri:
57 prefix: "/hello-world"
58 route:
59 - destination:
60 port:
61 number: 80
62 host: hello-world.istio-nonrtric.svc.cluster.local
63`
64
65const requestAuthenticationManifest = `
66apiVersion: security.istio.io/v1beta1
67kind: RequestAuthentication
68metadata:
69 name: "jwt-hw"
70 namespace: istio-nonrtric
71spec:
72 selector:
73 matchLabels:
74 app.kubernetes.io/instance: hello-world
75 jwtRules:
76 - issuer: "http://192.168.49.2:31560/auth/realms/hwrealm"
77 jwksUri: "http://192.168.49.2:31560/auth/realms/hwrealm/protocol/openid-connect/certs"
78 - issuer: "http://keycloak.default:8080/auth/realms/hwrealm"
79 jwksUri: "http://keycloak.default:8080/auth/realms/hwrealm/protocol/openid-connect/certs"
80`
81
82const authorizationPolicyManifest = `
83apiVersion: "security.istio.io/v1beta1"
84kind: "AuthorizationPolicy"
85metadata:
86 name: "hw-policy"
87 namespace: istio-nonrtric
88spec:
89 selector:
90 matchLabels:
91 app.kubernetes.io/instance: hello-world
92 action: ALLOW
93 rules:
94 - from:
95 - source:
96 requestPrincipals: ["http://192.168.49.2:31560/auth/realms/hwrealm/", "http://keycloak.default:8080/auth/realms/hwrealm/"]
97 - to:
98 - operation:
99 methods: ["GET"]
100 paths: ["/hello-world*"]
101 when:
102 - key: request.auth.claims[clientRole]
103 values: ["hwclientrole"]
104`
105
106func connectToK8s() *versioned.Clientset {
107 config, err := rest.InClusterConfig()
108 if err != nil {
109 // fallback to kubeconfig
110 home, exists := os.LookupEnv("HOME")
111 if !exists {
112 home = "/root"
113 }
114
115 kubeconfig := filepath.Join(home, ".kube", "config")
116 if envvar := os.Getenv("KUBECONFIG"); len(envvar) > 0 {
117 kubeconfig = envvar
118 }
119 config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
120 if err != nil {
121 log.Fatalln("failed to create K8s config")
122 }
123 }
124
125 ic, err := versioned.NewForConfig(config)
126 if err != nil {
127 log.Fatalf("Failed to create istio client: %s", err)
128 }
129
130 return ic
131}
132
133func createGateway(clientset *versioned.Clientset) (string, error) {
134 gtClient := clientset.NetworkingV1beta1().Gateways(NAMESPACE)
135
136 gt := &netv1beta1.Gateway{}
137 dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(gatewayManifest)), 1000)
138
139 if err := dec.Decode(&gt); err != nil {
140 return "", err
141 }
142
143 result, err := gtClient.Create(context.TODO(), gt, metav1.CreateOptions{})
144
145 if err != nil {
146 return "", err
147 }
148
149 fmt.Printf("Create Gateway %s \n", result.GetName())
150 return result.GetName(), nil
151}
152
153func createVirtualService(clientset *versioned.Clientset) (string, error) {
154 vsClient := clientset.NetworkingV1beta1().VirtualServices(NAMESPACE)
155
156 vs := &netv1beta1.VirtualService{}
157 dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(virtualServiceManifest)), 1000)
158
159 if err := dec.Decode(&vs); err != nil {
160 return "", err
161 }
162
163 result, err := vsClient.Create(context.TODO(), vs, metav1.CreateOptions{})
164
165 if err != nil {
166 return "", err
167 }
168
169 fmt.Printf("Create Virtual Service %s \n", result.GetName())
170 return result.GetName(), nil
171}
172
173func createRequestAuthentication(clientset *versioned.Clientset) (string, error) {
174 raClient := clientset.SecurityV1beta1().RequestAuthentications(NAMESPACE)
175
176 ra := &secv1beta1.RequestAuthentication{}
177 dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(requestAuthenticationManifest)), 1000)
178
179 if err := dec.Decode(&ra); err != nil {
180 return "", err
181 }
182
183 result, err := raClient.Create(context.TODO(), ra, metav1.CreateOptions{})
184
185 if err != nil {
186 return "", err
187 }
188
189 fmt.Printf("Create Request Authentication %s \n", result.GetName())
190 return result.GetName(), nil
191}
192
193func createAuthorizationPolicy(clientset *versioned.Clientset) (string, error) {
194 apClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE)
195
196 ap := &secv1beta1.AuthorizationPolicy{}
197 dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(authorizationPolicyManifest)), 1000)
198
199 if err := dec.Decode(&ap); err != nil {
200 return "", err
201 }
202
203 result, err := apClient.Create(context.TODO(), ap, metav1.CreateOptions{})
204
205 if err != nil {
206 return "", err
207 }
208
209 fmt.Printf("Create Authorization Policy %s \n", result.GetName())
210 return result.GetName(), nil
211}
212
213// create a handler struct
214type HttpHandler struct{}
215
216// implement `ServeHTTP` method on `HttpHandler` struct
217func (h HttpHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
218 var msg string
219 clientset := connectToK8s()
220 _, err := createGateway(clientset)
221 if err != nil {
222 msg = err.Error()
223 fmt.Println(err.Error())
224 } else {
225 _, err := createVirtualService(clientset)
226 if err != nil {
227 msg = err.Error()
228 fmt.Println(err.Error())
229 } else {
230 _, err := createRequestAuthentication(clientset)
231 if err != nil {
232 msg = err.Error()
233 fmt.Println(err.Error())
234 } else {
235 _, err := createAuthorizationPolicy(clientset)
236 if err != nil {
237 msg = err.Error()
238 fmt.Println(err.Error())
239 } else {
240 msg = "Istio rapp security setup successfully"
241 }
242 }
243 }
244 }
245
246 // create response binary data
247 data := []byte(msg) // slice of bytes
248 // write `data` to response
249 res.Write(data)
250}
251
252func main() {
253 // create a new handler
254 handler := HttpHandler{}
255 // listen and serve
256 http.ListenAndServe(":9000", handler)
257}