Added provider and invoker
Change-Id: I443b8b11a2304621109a9729473e05af8461f4f0
diff --git a/rapps/rapps-keycloak-mgr.go b/rapps/rapps-keycloak-mgr.go
index 9496a48..0d0a29c 100644
--- a/rapps/rapps-keycloak-mgr.go
+++ b/rapps/rapps-keycloak-mgr.go
@@ -4,19 +4,43 @@
"context"
"fmt"
"github.com/Nerzal/gocloak/v10"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ kubernetes "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/rest"
"net/http"
)
-// create a handler struct
-type HttpHandler struct{}
+const (
+ namespace = "istio-nonrtric"
+)
-// implement `ServeHTTP` method on `HttpHandler` struct
-func (h HttpHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
+func createClient(res http.ResponseWriter, req *http.Request) {
+ query := req.URL.Query()
+ realmName := query.Get("realm")
+ clientName := query.Get("name")
+ role := query.Get("role")
var msg string
- msg, err := createClient()
+ msg, err := create(realmName, clientName, role)
if err != nil {
msg = err.Error()
}
+ createSecret(msg, clientName, realmName, role, namespace)
+ // create response binary data
+ data := []byte(msg) // slice of bytes
+ // write `data` to response
+ res.Write(data)
+}
+
+func removeClient(res http.ResponseWriter, req *http.Request) {
+ query := req.URL.Query()
+ realmName := query.Get("realm")
+ clientName := query.Get("name")
+ role := query.Get("role")
+
+ var msg string = "Removed keycloak " + clientName + " from " + realmName + " realm"
+ remove(realmName, clientName)
+ removeSecret(namespace, role)
// create response binary data
data := []byte(msg) // slice of bytes
// write `data` to response
@@ -24,13 +48,14 @@
}
func main() {
- // create a new handler
- handler := HttpHandler{}
- // listen and serve
- http.ListenAndServe(":9000", handler)
+ createHandler := http.HandlerFunc(createClient)
+ http.Handle("/create", createHandler)
+ removeHandler := http.HandlerFunc(removeClient)
+ http.Handle("/remove", removeHandler)
+ http.ListenAndServe(":9000", nil)
}
-func createClient() (string, error) {
+func create(realmName, clientName, clientRoleName string) (string, error) {
client := gocloak.NewClient("http://keycloak.default:8080")
ctx := context.Background()
token, err := client.LoginAdmin(ctx, "admin", "admin", "master")
@@ -38,7 +63,6 @@
return "", err
}
- realmName := "hwrealm"
_, err = client.GetRealm(ctx, token.AccessToken, realmName)
if err != nil {
realmRepresentation := gocloak.RealmRepresentation{
@@ -59,14 +83,16 @@
}
newClient := gocloak.Client{
- ClientID: gocloak.StringP("hwclient"),
+ ClientID: gocloak.StringP(clientName),
Enabled: gocloak.BoolP(true),
DirectAccessGrantsEnabled: gocloak.BoolP(true),
BearerOnly: gocloak.BoolP(false),
PublicClient: gocloak.BoolP(false),
ServiceAccountsEnabled: gocloak.BoolP(true),
ClientAuthenticatorType: gocloak.StringP("client-secret"),
- DefaultClientScopes: &[]string{ "email" },
+ DefaultClientScopes: &[]string{"email"},
+ Attributes: &map[string]string{"use.refresh.tokens": "true",
+ "client_credentials.use_refresh_token": "true"},
}
clientId, err := client.CreateClient(ctx, token.AccessToken, realmName, newClient)
if err != nil {
@@ -76,9 +102,9 @@
}
newClientRole := gocloak.Role{
- Name: gocloak.StringP("hwclientrole"),
+ Name: gocloak.StringP(clientRoleName),
}
- clientRoleName, err := client.CreateClientRole(ctx, token.AccessToken, realmName, clientId, newClientRole)
+ clientRoleName, err = client.CreateClientRole(ctx, token.AccessToken, realmName, clientId, newClientRole)
if err != nil {
return "", err
} else {
@@ -123,7 +149,7 @@
"jsonType.label": "String",
"multivalued": "true",
"userinfo.token.claim": "true",
- "usermodel.clientRoleMapping.clientId": "hwclient",
+ "usermodel.clientRoleMapping.clientId": clientName,
},
}
_, err = client.CreateClientProtocolMapper(ctx, token.AccessToken, realmName, clientId, clientroleMapper)
@@ -148,3 +174,79 @@
return *cred.Value, nil
}
+
+func connectToK8s() *kubernetes.Clientset {
+ config, err := rest.InClusterConfig()
+ if err != nil {
+ fmt.Println("failed to create K8s config")
+ }
+
+ clientset, err := kubernetes.NewForConfig(config)
+ if err != nil {
+ fmt.Println("Failed to create K8s clientset")
+ }
+
+ return clientset
+}
+
+func createSecret(clientSecret, clientName, realmName, role, namespace string) {
+ secretName := role +"-secret"
+ clientset := connectToK8s()
+ secrets := clientset.CoreV1().Secrets(namespace)
+ secret := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: secretName,
+ Namespace: namespace,
+ Labels: map[string]string{
+ "app" : secretName,
+ },
+ },
+ Type: "Opaque",
+ StringData: map[string]string{"client_secret": clientSecret, "client_id": clientName, "realm": realmName},
+ }
+
+ _, err := secrets.Create(context.TODO(), secret, metav1.CreateOptions{})
+ if err != nil {
+ fmt.Println("Failed to create K8s secret.", err)
+ }
+
+ fmt.Println("Created K8s secret successfully")
+}
+
+func remove(realmName, clientName string) {
+ adminClient := gocloak.NewClient("http://192.168.49.2:31560")
+ ctx := context.Background()
+ token, err := adminClient.LoginAdmin(ctx, "admin", "admin", "master")
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ clients, err := adminClient.GetClients(ctx, token.AccessToken, realmName,
+ gocloak.GetClientsParams{
+ ClientID: gocloak.StringP(clientName),
+ },
+ )
+ if err != nil {
+ panic("List clients failed:" + err.Error())
+ }
+ for _, client := range clients {
+ err = adminClient.DeleteClient(ctx, token.AccessToken, realmName, *client.ID)
+ if err != nil {
+ fmt.Println(err)
+ } else {
+ fmt.Println("Deleted client ", clientName)
+ }
+ }
+}
+
+func removeSecret(namespace, role string) {
+ clientset := connectToK8s()
+ secretName := role +"-secret"
+ secrets := clientset.CoreV1().Secrets(namespace)
+ err := secrets.Delete(context.TODO(), secretName, metav1.DeleteOptions{})
+ if err != nil {
+ fmt.Println(err)
+ } else {
+ fmt.Println("Deleted Secret", secretName)
+ }
+}