Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ For convenience, the `make toolcheck` script checks if you have the necessary de

### Provisioning Custom Keycloak and Policy Data

To provision a custom Keycloak setup, create a yaml following the format of [the sample Keycloak config](service/cmd/keycloak_data.yaml). You can create different realms with separate users, clients, roles, and groups. Run the provisioning with `go run ./service provision keycloak-from-config -f <path-to-your-yaml-file>`.
To provision a custom Keycloak setup, create a yaml following the format of [the sample Keycloak config](service/cmd/keycloak_data.yaml). You can create different realms with separate users, clients, roles, and groups. Run the provisioning with `go run ./service provision keycloak -f <path-to-your-yaml-file>`.

### Develop a new service

Expand Down
149 changes: 106 additions & 43 deletions service/cmd/provisionKeycloak.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,133 @@ package cmd

import (
"context"
"encoding/json"
"fmt"
"io"
"log/slog"
"os"

"github.com/opentdf/platform/lib/fixtures"
"github.com/opentdf/platform/service/internal/config"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)

const (
provKcEndpointFlag = "endpoint"
provKcUsernameFlag = "username"
provKcPasswordFlag = "password"
provKcRealmFlag = "realm"
provKcFilenameFlag = "file"
provKcInsecure = "insecure"
)

var (
provisionKeycloakCmd = &cobra.Command{
Use: "keycloak",
Short: "Run local provision of keycloak data",
Long: `
** Local Development and Testing Only **
This command will create the following Keyclaok resource:
- Realm
- Roles
- Client
- Users

This command is intended for local development and testing purposes only.
`,
RunE: func(cmd *cobra.Command, _ []string) error {
kcEndpoint, _ := cmd.Flags().GetString(provKcEndpointFlag)
realmName, _ := cmd.Flags().GetString(provKcRealmFlag)
kcUsername, _ := cmd.Flags().GetString(provKcUsernameFlag)
kcPassword, _ := cmd.Flags().GetString(provKcPasswordFlag)
configFile, _ := cmd.Flags().GetString(configFileFlag)
configKey, _ := cmd.Flags().GetString(configKeyFlag)
insecure, _ := cmd.Flags().GetBool(provKcInsecure)

config, err := config.LoadConfig(configKey, configFile)
if err != nil {
return err
}

kcConnectParams := fixtures.KeycloakConnectParams{
BasePath: kcEndpoint,
Username: kcUsername,
Password: kcPassword,
Realm: realmName,
Audience: config.Server.Auth.Audience,
AllowInsecureTLS: insecure,
}

return fixtures.SetupKeycloak(context.Background(), kcConnectParams)
},
}
provKeycloakFilename = "./service/cmd/keycloak_data.yaml"
keycloakData fixtures.KeycloakData
)

var provisionKeycloakCmd = &cobra.Command{
Use: "keycloak",
Short: "Run local provision of keycloak data",
Long: `
** Local Development and Testing Only **
This command will create the following Keyclaok resource:
- Realm
- Roles
- Client
- Users

This command is intended for local development and testing purposes only.
`,
RunE: func(cmd *cobra.Command, _ []string) error {
kcEndpoint, _ := cmd.Flags().GetString(provKcEndpointFlag)
kcUsername, _ := cmd.Flags().GetString(provKcUsernameFlag)
kcPassword, _ := cmd.Flags().GetString(provKcPasswordFlag)
keycloakFilename, _ := cmd.Flags().GetString(provKcFilenameFlag)

LoadKeycloakData(keycloakFilename)
ctx := context.Background()

kcParams := fixtures.KeycloakConnectParams{
BasePath: kcEndpoint,
Username: kcUsername,
Password: kcPassword,
Realm: "",
AllowInsecureTLS: true,
}

err := fixtures.SetupCustomKeycloak(ctx, kcParams, keycloakData)
if err != nil {
return err
}

return nil
},
}

var provisionKeycloakFromConfigCmd = &cobra.Command{
Use: "keycloak-from-config",
RunE: func(_ *cobra.Command, _ []string) error {
slog.Info("Command keycloak-from-config has been deprecated. Please use command 'keycloak' instead.")
return nil
},
}

func convert(i interface{}) interface{} {
switch x := i.(type) {
case map[interface{}]interface{}:
m2 := map[string]interface{}{}
for k, v := range x {
m2[k.(string)] = convert(v) //nolint:forcetypeassert // allow type assert
}
return m2
case []interface{}:
for i, v := range x {
x[i] = convert(v)
}
}
return i
}

func LoadKeycloakData(file string) {
yamlData := make(map[interface{}]interface{})

f, err := os.Open(file)
if err != nil {
panic(fmt.Errorf("error when opening YAML file: %s", err.Error()))
}

fileData, err := io.ReadAll(f)
if err != nil {
panic(fmt.Errorf("error reading YAML file: %s", err.Error()))
}

err = yaml.Unmarshal(fileData, &yamlData)
if err != nil {
panic(fmt.Errorf("error unmarshaling yaml file %s", err.Error()))
}

cleanedYaml := convert(yamlData)

kcData, err := json.Marshal(cleanedYaml)
if err != nil {
panic(fmt.Errorf("error converting yaml to json: %s", err.Error()))
}

if err := json.Unmarshal(kcData, &keycloakData); err != nil {
slog.Error("could not unmarshal json into data object", slog.String("error", err.Error()))
panic(err)
}
}

func init() {
provisionKeycloakCmd.Flags().StringP(provKcEndpointFlag, "e", "http://localhost:8888/auth", "Keycloak endpoint")
provisionKeycloakCmd.Flags().StringP(provKcUsernameFlag, "u", "admin", "Keycloak username")
provisionKeycloakCmd.Flags().StringP(provKcPasswordFlag, "p", "changeme", "Keycloak password")
provisionKeycloakCmd.Flags().StringP(provKcRealmFlag, "r", "opentdf", "OpenTDF Keycloak Realm name")
provisionKeycloakCmd.Flags().BoolP(provKcInsecure, "", false, "Ignore tls verification when connecting to keycloak. --insecure to disable.")
provisionKeycloakCmd.Flags().StringP(provKcFilenameFlag, "f", provKeycloakFilename, "Keycloak config file")

provisionCmd.AddCommand(provisionKeycloakCmd)

rootCmd.AddCommand(provisionKeycloakCmd)
// Deprecated command
provisionCmd.AddCommand(provisionKeycloakFromConfigCmd)
}
124 changes: 0 additions & 124 deletions service/cmd/provisionKeycloakFromConfig.go

This file was deleted.