Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

There is also a helm sdk you can use:

HELM SDK

Code Block
languagepy
titleHelm Deploy
package main

import (
    "fmt"
    "os"
    "log"
    "k8s.io/cli-runtime/pkg/genericclioptions"
    "k8s.io/client-go/rest"
    "helm.sh/helm/v3/pkg/action"
    "helm.sh/helm/v3/pkg/chart/loader"
)

func main() {
    chartPath := "/tmp/wordpress-12.3.3.tgz"
    chart, err := loader.Load(chartPath)

    releaseName := "wordpress"
    releaseNamespace := "default"

    actionConfig, err := getActionConfig(releaseNamespace)
    if err != nil {
        panic(err)
    }

    listAction := action.NewList(actionConfig)
    releases, err := listAction.Run()
    if err != nil {
        log.Println(err)
    }
    for _, release := range releases {
        log.Println("Release: " + release.Name + " Status: " + release.Info.Status.String())
    }

    iCli := action.NewInstall(actionConfig)
    iCli.Namespace = releaseNamespace
    iCli.ReleaseName = releaseName
    rel, err := iCli.Run(chart, nil)
    if err != nil {

        fmt.Println(err)
    }
   fmt.Println("Successfully installed release: ", rel.Name)
}

func getActionConfig(namespace string) (*action.Configuration, error) {
        actionConfig := new(action.Configuration)
        // Create the rest config instance with ServiceAccount values loaded in them
        config, err := rest.InClusterConfig()
        if err != nil {
        // fallback to kubeconfig
        home, exists := os.LookupEnv("HOME")
        if !exists {
            home = "/root"
        }
        kubeconfigPath := filepath.Join(home, ".kube", "config")
         if envvar := os.Getenv("KUBECONFIG"); len(envvar) >0 {
            kubeconfigPath = envvar
         }
         if err := actionConfig.Init(kube.GetConfig(kubeconfigPath, "", namespace), namespace, os.Getenv("HELM_DRIVER"),
                   func(format string, v ...interface{}) {
                   fmt.Sprintf(format, v)
         }); err != nil {
             panic(err)
         }
        } else {
           // Create the ConfigFlags struct instance with initialized values from ServiceAccount
           var kubeConfig *genericclioptions.ConfigFlags
           kubeConfig = genericclioptions.NewConfigFlags(false)
           kubeConfig.APIServer = &config.Host
           kubeConfig.BearerToken = &config.BearerToken
           kubeConfig.CAFile = &config.CAFile
           kubeConfig.Namespace = &namespace
           if err := actionConfig.Init(kubeConfig, namespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
               fmt.Sprintf(format, v)
           }); err != nil {
               panic(err)
           }
        }
        return actionConfig, nil
}

...

The method getActionConfig works for both in-cluster deployments and from the localhost. It determines which one to use by calling the rest.InClusterConfig() function.

GO CLIENT SDK

Here are another couple of programs that demonstrate how to use the go client:

...

There is also support for istio in client go Istio client-go

ISTIO SDK

Code Block
languageyml
titleAuthorizationPolicy
package main

import (
    "context"
    "bytes"
    "fmt"
    "os"
    "log"
    "path/filepath"
    k8Yaml "k8s.io/apimachinery/pkg/util/yaml"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    clientcmd "k8s.io/client-go/tools/clientcmd"
    versioned "istio.io/client-go/pkg/clientset/versioned"
    v1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
    securityv1beta1 "istio.io/api/security/v1beta1"
    typev1beta1 "istio.io/api/type/v1beta1"
)

const (
        NAMESPACE = "default"
)

const authorizationPolicyManifest = `
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "pms-policy"
  namespace: default
spec:
  selector:
    matchLabels:
      apptype: nonrtric-pms
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/goclient"]
    to:
    - operation:
        methods: ["GET", "POST", "PUT", "DELETE"]
        paths: ["/a1-policy*"]
        hosts: ["a1-policy*"]
        ports: ["8080"]
    when:
    - key: request.auth.claims[role]
      values: ["pms_admin"]
`

func connectToK8s() *versioned.Clientset {
    home, exists := os.LookupEnv("HOME")
    if !exists {
        home = "/root"
    }

    configPath := filepath.Join(home, ".kube", "config")

    config, err := clientcmd.BuildConfigFromFlags("", configPath)
    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 createAuthorizationPolicy(clientset *versioned.Clientset) {
        authClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE)

        auth := &v1beta1.AuthorizationPolicy{}
        dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(authorizationPolicyManifest)), 1000)

        if err := dec.Decode(&auth); err != nil {
               fmt.Println(err)
        }

        result, err := authClient.Create(context.TODO(), auth, metav1.CreateOptions{})

        if err!=nil {
                panic(err.Error())
        }

        fmt.Printf("Create Authorization Policy %s \n", result.GetName())
}

func createAuthorizationPolicy2(clientset *versioned.Clientset) {
        authClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE)

        auth := &v1beta1.AuthorizationPolicy{
                ObjectMeta: metav1.ObjectMeta{
                        Name: "ics-policy",
                },
                Spec: securityv1beta1.AuthorizationPolicy {
                  Selector: &typev1beta1.WorkloadSelector{
                             MatchLabels: map[string]string{
                             "apptype" : "nonrtric-ics",
                           },
                  },
                  Action: securityv1beta1.AuthorizationPolicy_ALLOW,
                  Rules: []*securityv1beta1.Rule{{
                         From: []*securityv1beta1.Rule_From{{
                              Source: &securityv1beta1.Source{
                                Namespaces : []string{
                                        "default",
                                },
                              },
                         },},
                         To: []*securityv1beta1.Rule_To{{
                              Operation:  &securityv1beta1.Operation{
                                Methods : []string{
                                      "GET", "POST", "PUT", "DELETE",
                                },
                                Paths : []string{
                                      "/data-*",
                                },
                                Hosts : []string{
                                      "data-consumer*", "data-producer*",
                                },
                                Ports : []string{
                                      "8080",
                                },
                              },
                         },},
                  },},
              },
        }

        result, err := authClient.Create(context.TODO(), auth, metav1.CreateOptions{})

        if err!=nil {
                panic(err.Error())
        }

        fmt.Printf("Create Authorization Policy %s \n", result.GetName())
}

func main() {
    clientset := connectToK8s()
    createAuthorizationPolicy(clientset)
    createAuthorizationPolicy2(clientset)
}

...

keycloak aslo has a client called gocloak

GOCLOAK SDK

Code Block
languagepy
titlegocloak
package main

import (
        "github.com/Nerzal/gocloak/v10"
        "context"
        "fmt"
)

func main(){
 client := gocloak.NewClient("http://192.168.49.2:31560")
 ctx := context.Background()
 token, err := client.LoginAdmin(ctx, "admin", "admin", "master")
 if err != nil {
  fmt.Println(err)
  panic("Something wrong with the credentials or url")
 }

 realmRepresentation := gocloak.RealmRepresentation{
  ID: gocloak.StringP("testRealm"),
  Realm: gocloak.StringP("testRealm"),
  DisplayName: gocloak.StringP("testRealm"),
  Enabled:   gocloak.BoolP(true),
 }

 realm, err := client.CreateRealm(ctx, token.AccessToken, realmRepresentation)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to create realm :(")
 } else {
  fmt.Println("Created new realm", realm)
 }

 newClient := gocloak.Client{
  ClientID: gocloak.StringP("testClient"),
  Enabled:   gocloak.BoolP(true),
  DirectAccessGrantsEnabled: gocloak.BoolP(true),
  BearerOnly: gocloak.BoolP(false),
  PublicClient: gocloak.BoolP(true),
 }
 clientId, err := client.CreateClient(ctx, token.AccessToken, realm, newClient)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to create client :(")
 } else {
  fmt.Println("Created new client", clientId)
 }


 newUser := gocloak.User{
  FirstName: gocloak.StringP("Bob"),
  LastName:  gocloak.StringP("Uncle"),
  Email:     gocloak.StringP("something@really.wrong"),
  Enabled:   gocloak.BoolP(true),
  Username:  gocloak.StringP("testUser"),
 }

 userId, err := client.CreateUser(ctx, token.AccessToken, realm, newUser)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to create user :(")
 } else {
  fmt.Println("Created new user", userId)
}

 err = client.SetPassword(ctx, token.AccessToken, userId, realm, "secret", false)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to set password :(")
 } else {
  fmt.Println("Set password for user")
 }

 removeRoles := []gocloak.Role{}
 origRoles, err := client.GetRealmRoles(ctx, token.AccessToken, realm, gocloak.GetRoleParams{})
  if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to retreive roles :(")
 } else {
  fmt.Println("Retrieved roles")
 }
 for _, r := range origRoles {
   removeRoles = append(removeRoles, *r)
 }

 newRole := gocloak.Role{
  Name: gocloak.StringP("testRole"),
 }
 roleName, err := client.CreateRealmRole(ctx, token.AccessToken, realm, newRole)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to create role :(")
 } else {
  fmt.Println("Created new role", roleName)
 }

 role, err := client.GetRealmRole(ctx, token.AccessToken, realm, roleName)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to retrieve role :(")
 } else {
  fmt.Println("Retrieved role")
 }

 roles := []gocloak.Role{}
 roles = append(roles, *role)
 err = client.AddRealmRoleToUser(ctx, token.AccessToken, realm, userId, roles)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to add role to user :(")
 } else {
  fmt.Println("Role added to user")
 }

 err = client.DeleteRealmRoleFromUser(ctx, token.AccessToken, realm, userId, removeRoles)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to remove roles from user :(")
 } else {
  fmt.Println("Roles removed from user")
 }

 newMapper := gocloak.ProtocolMapperRepresentation{
   ID:             gocloak.StringP("testMapper"),
   Name:           gocloak.StringP("testMapper"),
   Protocol:       gocloak.StringP("openid-connect"),
   ProtocolMapper: gocloak.StringP("oidc-usermodel-realm-role-mapper"),
   Config: &map[string]string{
                                "access.token.claim":   "true",
                                "aggregate.attrs":      "",
                                "claim.name":           "role",
                                "id.token.claim":       "true",
                                "jsonType.label":       "String",
                                "multivalued":          "",
                                "userinfo.token.claim": "true",
                        },
  }
 _, err = client.CreateClientProtocolMapper(ctx, token.AccessToken, realm, clientId, newMapper)
 if err != nil {
  fmt.Println(err)
  panic("Oh no!, failed to add roleampper to client :(")
 } else {
  fmt.Println("Rolemapper added to client")
 }

}

...