Added rapps prototype
Change-Id: Ifa7a78d3391dc74ba8fdc304bea47b76429d80c4
diff --git a/rapps/rapps-istio-mgr.go b/rapps/rapps-istio-mgr.go
new file mode 100644
index 0000000..bcbbbeb
--- /dev/null
+++ b/rapps/rapps-istio-mgr.go
@@ -0,0 +1,257 @@
+package main
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ netv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
+ secv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
+ versioned "istio.io/client-go/pkg/clientset/versioned"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ k8Yaml "k8s.io/apimachinery/pkg/util/yaml"
+ "k8s.io/client-go/rest"
+ clientcmd "k8s.io/client-go/tools/clientcmd"
+ "log"
+ "net/http"
+ "os"
+ "path/filepath"
+)
+
+const (
+ NAMESPACE = "istio-nonrtric"
+)
+
+const gatewayManifest = `
+apiVersion: networking.istio.io/v1beta1
+kind: Gateway
+metadata:
+ name: nonrtric-istio-hw-gateway
+ namespace: istio-nonrtric
+spec:
+ selector:
+ istio: ingressgateway # use Istio gateway implementation
+ servers:
+ - port:
+ number: 80
+ name: http
+ protocol: HTTP
+ hosts:
+ - "*"
+`
+
+const virtualServiceManifest = `
+apiVersion: networking.istio.io/v1beta1
+kind: VirtualService
+metadata:
+ name: nonrtric-istio-hw-vs
+ namespace: istio-nonrtric
+spec:
+ hosts:
+ - "*"
+ gateways:
+ - nonrtric-istio-hw-gateway
+ http:
+ - name: "hello-world-routes"
+ match:
+ - uri:
+ prefix: "/hello-world"
+ route:
+ - destination:
+ port:
+ number: 80
+ host: hello-world.istio-nonrtric.svc.cluster.local
+`
+
+const requestAuthenticationManifest = `
+apiVersion: security.istio.io/v1beta1
+kind: RequestAuthentication
+metadata:
+ name: "jwt-hw"
+ namespace: istio-nonrtric
+spec:
+ selector:
+ matchLabels:
+ app.kubernetes.io/instance: hello-world
+ jwtRules:
+ - issuer: "http://192.168.49.2:31560/auth/realms/hwrealm"
+ jwksUri: "http://192.168.49.2:31560/auth/realms/hwrealm/protocol/openid-connect/certs"
+ - issuer: "http://keycloak.default:8080/auth/realms/hwrealm"
+ jwksUri: "http://keycloak.default:8080/auth/realms/hwrealm/protocol/openid-connect/certs"
+`
+
+const authorizationPolicyManifest = `
+apiVersion: "security.istio.io/v1beta1"
+kind: "AuthorizationPolicy"
+metadata:
+ name: "hw-policy"
+ namespace: istio-nonrtric
+spec:
+ selector:
+ matchLabels:
+ app.kubernetes.io/instance: hello-world
+ action: ALLOW
+ rules:
+ - from:
+ - source:
+ requestPrincipals: ["http://192.168.49.2:31560/auth/realms/hwrealm/", "http://keycloak.default:8080/auth/realms/hwrealm/"]
+ - to:
+ - operation:
+ methods: ["GET"]
+ paths: ["/hello-world*"]
+ when:
+ - key: request.auth.claims[clientRole]
+ values: ["hwclientrole"]
+`
+
+func connectToK8s() *versioned.Clientset {
+ config, err := rest.InClusterConfig()
+ if err != nil {
+ // fallback to kubeconfig
+ home, exists := os.LookupEnv("HOME")
+ if !exists {
+ home = "/root"
+ }
+
+ kubeconfig := filepath.Join(home, ".kube", "config")
+ if envvar := os.Getenv("KUBECONFIG"); len(envvar) > 0 {
+ kubeconfig = envvar
+ }
+ config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
+ if err != nil {
+ log.Fatalln("failed to create K8s config")
+ }
+ }
+
+ ic, err := versioned.NewForConfig(config)
+ if err != nil {
+ log.Fatalf("Failed to create istio client: %s", err)
+ }
+
+ return ic
+}
+
+func createGateway(clientset *versioned.Clientset) (string, error) {
+ gtClient := clientset.NetworkingV1beta1().Gateways(NAMESPACE)
+
+ gt := &netv1beta1.Gateway{}
+ dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(gatewayManifest)), 1000)
+
+ if err := dec.Decode(>); err != nil {
+ return "", err
+ }
+
+ result, err := gtClient.Create(context.TODO(), gt, metav1.CreateOptions{})
+
+ if err != nil {
+ return "", err
+ }
+
+ fmt.Printf("Create Gateway %s \n", result.GetName())
+ return result.GetName(), nil
+}
+
+func createVirtualService(clientset *versioned.Clientset) (string, error) {
+ vsClient := clientset.NetworkingV1beta1().VirtualServices(NAMESPACE)
+
+ vs := &netv1beta1.VirtualService{}
+ dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(virtualServiceManifest)), 1000)
+
+ if err := dec.Decode(&vs); err != nil {
+ return "", err
+ }
+
+ result, err := vsClient.Create(context.TODO(), vs, metav1.CreateOptions{})
+
+ if err != nil {
+ return "", err
+ }
+
+ fmt.Printf("Create Virtual Service %s \n", result.GetName())
+ return result.GetName(), nil
+}
+
+func createRequestAuthentication(clientset *versioned.Clientset) (string, error) {
+ raClient := clientset.SecurityV1beta1().RequestAuthentications(NAMESPACE)
+
+ ra := &secv1beta1.RequestAuthentication{}
+ dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(requestAuthenticationManifest)), 1000)
+
+ if err := dec.Decode(&ra); err != nil {
+ return "", err
+ }
+
+ result, err := raClient.Create(context.TODO(), ra, metav1.CreateOptions{})
+
+ if err != nil {
+ return "", err
+ }
+
+ fmt.Printf("Create Request Authentication %s \n", result.GetName())
+ return result.GetName(), nil
+}
+
+func createAuthorizationPolicy(clientset *versioned.Clientset) (string, error) {
+ apClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE)
+
+ ap := &secv1beta1.AuthorizationPolicy{}
+ dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(authorizationPolicyManifest)), 1000)
+
+ if err := dec.Decode(&ap); err != nil {
+ return "", err
+ }
+
+ result, err := apClient.Create(context.TODO(), ap, metav1.CreateOptions{})
+
+ if err != nil {
+ return "", err
+ }
+
+ fmt.Printf("Create Authorization Policy %s \n", result.GetName())
+ return result.GetName(), nil
+}
+
+// create a handler struct
+type HttpHandler struct{}
+
+// implement `ServeHTTP` method on `HttpHandler` struct
+func (h HttpHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
+ var msg string
+ clientset := connectToK8s()
+ _, err := createGateway(clientset)
+ if err != nil {
+ msg = err.Error()
+ fmt.Println(err.Error())
+ } else {
+ _, err := createVirtualService(clientset)
+ if err != nil {
+ msg = err.Error()
+ fmt.Println(err.Error())
+ } else {
+ _, err := createRequestAuthentication(clientset)
+ if err != nil {
+ msg = err.Error()
+ fmt.Println(err.Error())
+ } else {
+ _, err := createAuthorizationPolicy(clientset)
+ if err != nil {
+ msg = err.Error()
+ fmt.Println(err.Error())
+ } else {
+ msg = "Istio rapp security setup successfully"
+ }
+ }
+ }
+ }
+
+ // create response binary data
+ data := []byte(msg) // slice of bytes
+ // write `data` to response
+ res.Write(data)
+}
+
+func main() {
+ // create a new handler
+ handler := HttpHandler{}
+ // listen and serve
+ http.ListenAndServe(":9000", handler)
+}