Skip to content

Commit

Permalink
BYOK installer for plural console
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljguarino committed Nov 5, 2023
1 parent 2147209 commit 82f4d0f
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 3 deletions.
23 changes: 23 additions & 0 deletions cmd/plural/cd.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/AlecAivazis/survey/v2"
gqlclient "github.com/pluralsh/console-client-go"
"github.com/pluralsh/plural/pkg/cd"
"github.com/pluralsh/plural/pkg/config"
"github.com/pluralsh/plural/pkg/console"
"github.com/pluralsh/plural/pkg/utils"
"github.com/pluralsh/polly/containers"
Expand Down Expand Up @@ -74,6 +75,11 @@ func (p *Plural) cdCommands() []cli.Command {
cli.StringFlag{Name: "token", Usage: "console token", Required: true},
},
},
{
Name: "control-plane",
Action: p.handleInstallControlPlane,
Usage: "sets up the plural console in an existing k8s cluster",
},
{
Name: "uninstall",
Action: p.handleUninstallOperator,
Expand Down Expand Up @@ -1000,6 +1006,23 @@ func (p *Plural) handleCreateCluster(c *cli.Context) error {
return nil
}

func (p *Plural) handleInstallControlPlane(c *cli.Context) error {
conf := config.Read()
vals, err := cd.CreateControlPlane(conf)
if err != nil {
return err
}

utils.Highlight("writing values.secret.yaml, you should keep this in a secure location for future helm installs")
if err := os.WriteFile("values.secret.yaml", []byte(vals), 0644); err != nil {
return err
}

fmt.Println("After confirming everything looks correct in values.secret.yaml, run the following command to install:")
utils.Highlight("helm upgrade --install --create-namespace -f values.secret.yaml console -n plrl-console")
return nil
}

func (p *Plural) handleCreateProvider(existingProviders []string) (*gqlclient.CreateClusterProvider, error) {
provider := ""
var resp struct {
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/norwoodj/helm-docs v1.11.2
github.com/olekukonko/tablewriter v0.0.5
github.com/osteele/liquid v1.3.2
github.com/packethost/packngo v0.29.0
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/pluralsh/cluster-api-migration v0.2.15
github.com/pluralsh/console-client-go v0.0.31
github.com/pluralsh/gqlclient v1.10.0
github.com/pluralsh/gqlclient v1.11.0
github.com/pluralsh/plural-operator v0.5.5
github.com/pluralsh/polly v0.1.1
github.com/pluralsh/terraform-delinker v0.0.1
Expand Down Expand Up @@ -220,6 +221,7 @@ require (
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect
github.com/onsi/gomega v1.27.6 // indirect
github.com/orcaman/concurrent-map v1.0.0 // indirect
github.com/osteele/tuesday v1.0.3 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
Expand Down
8 changes: 6 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,10 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/osteele/liquid v1.3.2 h1:G+MvVYt1HX2xuv99JgdrhV7zRVdlvFnNi8M5rN8gQmI=
github.com/osteele/liquid v1.3.2/go.mod h1:VmzQQHa5v4E0GvGzqccfAfLgMwRk2V+s1QbxYx9dGak=
github.com/osteele/tuesday v1.0.3 h1:SrCmo6sWwSgnvs1bivmXLvD7Ko9+aJvvkmDjB5G4FTU=
github.com/osteele/tuesday v1.0.3/go.mod h1:pREKpE+L03UFuR+hiznj3q7j3qB1rUZ4XfKejwWFF2M=
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
Expand Down Expand Up @@ -1423,8 +1427,8 @@ github.com/pluralsh/console-client-go v0.0.31 h1:M8NPmVmuL4sH8/gC+WlgbXmxOp/y3pX
github.com/pluralsh/console-client-go v0.0.31/go.mod h1:kZjk0pXAWnvyj+miXveCho4kKQaX1Tm3CGAM+iwurWU=
github.com/pluralsh/controller-reconcile-helper v0.0.4 h1:1o+7qYSyoeqKFjx+WgQTxDz4Q2VMpzprJIIKShxqG0E=
github.com/pluralsh/controller-reconcile-helper v0.0.4/go.mod h1:AfY0gtteD6veBjmB6jiRx/aR4yevEf6K0M13/pGan/s=
github.com/pluralsh/gqlclient v1.10.0 h1:ccYB+A0JbPYkEeVzdfajd29l65N6x/buSKPMMxM8OIA=
github.com/pluralsh/gqlclient v1.10.0/go.mod h1:qSXKUlio1F2DRPy8el4oFYsmpKbkUYspgPB87T4it5I=
github.com/pluralsh/gqlclient v1.11.0 h1:FfXW7FiEJLHOfTAa7NxDb8jb3aMZNIpCAcG+bg8uHYA=
github.com/pluralsh/gqlclient v1.11.0/go.mod h1:qSXKUlio1F2DRPy8el4oFYsmpKbkUYspgPB87T4it5I=
github.com/pluralsh/helm-docs v1.11.3-0.20230914191425-6d14ebab8817 h1:J7SGxH6nJGdRoNtqdzhyr2VMpbl4asolul7xqqW++EA=
github.com/pluralsh/helm-docs v1.11.3-0.20230914191425-6d14ebab8817/go.mod h1:rLqec59NO7YF57Rq9VlubQHMp7wcRTJhzpkcgs4lOG4=
github.com/pluralsh/oauth v0.9.2 h1:tM9hBK4tCnJUeCOgX0ctxBBCS3hiCDPoxkJLODtedmQ=
Expand Down
1 change: 1 addition & 0 deletions pkg/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type Client interface {
GetPackageInstallations(repoId string) (charts []*ChartInstallation, tfs []*TerraformInstallation, err error)
CreateCrd(repo string, chart string, file string) error
CreateDomain(name string) error
CreateInstallation(id string) (string, error)
GetInstallation(name string) (*Installation, error)
GetInstallationById(id string) (*Installation, error)
GetInstallations() ([]*Installation, error)
Expand Down
8 changes: 8 additions & 0 deletions pkg/api/installations.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ func (client *client) DeleteInstallation(id string) error {
return err
}

func (client *client) CreateInstallation(id string) (string, error) {
resp, err := client.pluralClient.CreateInstallation(client.ctx, id)
if err != nil {
return "", err
}
return resp.CreateInstallation.ID, err
}

func convertInstallation(installation *gqlclient.InstallationFragment) *Installation {
if installation == nil {
return nil
Expand Down
23 changes: 23 additions & 0 deletions pkg/bundle/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,29 @@ func ConfigureOidc(repo string, client api.Client, recipe *api.Recipe, ctx map[s
return api.GetErrorResponse(err, "OIDCProvider")
}

func SetupOIDC(repo string, client api.Client, redirectUris []string, authMethod string) error {
inst, err := client.GetInstallation(repo)
if err != nil {
return api.GetErrorResponse(err, "GetInstallation")
}

me, err := client.Me()
if err != nil {
return api.GetErrorResponse(err, "Me")
}

oidcSettings := &api.OidcProviderAttributes{
RedirectUris: redirectUris,
AuthMethod: authMethod,
Bindings: []api.Binding{
{UserId: me.Id},
},
}
mergeOidcAttributes(inst, oidcSettings)
err = client.OIDCProvider(inst.Id, oidcSettings)
return api.GetErrorResponse(err, "OIDCProvider")
}

func mergeOidcAttributes(inst *api.Installation, attributes *api.OidcProviderAttributes) {
if inst.OIDCProvider == nil {
return
Expand Down
140 changes: 140 additions & 0 deletions pkg/cd/control_plane_install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package cd

import (
"bytes"
"fmt"
"io"
"net/http"

"github.com/AlecAivazis/survey/v2"
"github.com/osteele/liquid"
"github.com/pluralsh/plural/pkg/api"
"github.com/pluralsh/plural/pkg/bundle"
"github.com/pluralsh/plural/pkg/config"
"github.com/pluralsh/plural/pkg/crypto"
"github.com/pluralsh/plural/pkg/utils"
)

var (
liquidEngine = liquid.NewEngine()
)

const (
templateUrl = "https://raw.githubusercontent.com/pluralsh/console/cd-scaffolding/charts/console/values.yaml.liquid"
)

func CreateControlPlane(conf config.Config) (string, error) {
client := api.FromConfig(&conf)
me, err := client.Me()
if err != nil {
return "", fmt.Errorf("you must run `plural login` before installing")
}

azureSurvey := []*survey.Question{
{
Name: "console",
Prompt: &survey.Input{Message: "Enter a dns name for your installation of the console (eg console.your.domain):"},
},
{
Name: "kubeProxy",
Prompt: &survey.Input{Message: "Enter a dns name for the kube proxy (eg kas.your.domain), this is used for dashboarding functionality:"},
},
{
Name: "clusterName",
Prompt: &survey.Input{Message: "Enter a name for this cluster:"},
},
{
Name: "postgresDsn",
Prompt: &survey.Input{Message: "Enter a postgres connection string for the underlying database (should be postgres://<user>:<password>@<host>:5432/<database>):"},
},
}
var resp struct {
Console string
KubeProxy string
ClusterName string
PostgresDsn string
}
if err := survey.Ask(azureSurvey, &resp); err != nil {
return "", err
}

randoms := map[string]string{}
for _, key := range []string{"jwt", "erlang", "adminPassword", "kasApi", "kasPrivateApi", "kasRedis"} {
rand, err := crypto.RandStr(32)
if err != nil {
return "", err
}
randoms[key] = rand
}

configuration := map[string]string{
"consoleDns": resp.Console,
"kasDns": resp.KubeProxy,
"aesKey": utils.GenAESKey(),
"adminName": me.Email,
"adminEmail": me.Email,
"clusterName": resp.ClusterName,
"pluralToken": conf.Token,
"postgresUrl": resp.PostgresDsn,
}
for k, v := range randoms {
configuration[k] = v
}

clientId, clientSecret, err := ensureInstalledAndOidc(client, resp.Console)
if err != nil {
return "", err
}
configuration["pluralClientId"] = clientId
configuration["pluralClientSecret"] = clientSecret

tpl, err := fetchTemplate()
if err != nil {
return "", err
}

bindings := map[string]interface{}{
"configuration": configuration,
}

res, err := liquidEngine.ParseAndRender(tpl, bindings)
return string(res), err
}

func fetchTemplate() (res []byte, err error) {
resp, err := http.Get(templateUrl)
if err != nil {
return
}
defer resp.Body.Close()
var out bytes.Buffer
_, err = io.Copy(&out, resp.Body)
return out.Bytes(), err
}

func ensureInstalledAndOidc(client api.Client, dns string) (clientId string, clientSecret string, err error) {
inst, err := client.GetInstallation("console")
if err != nil || inst == nil {
repo, err := client.GetRepository("console")
if err != nil {
return "", "", err
}
_, err = client.CreateInstallation(repo.Id)
if err != nil {
return "", "", err
}
}

redirectUris := []string{fmt.Sprintf("https://%s/oauth/callback", dns)}
err = bundle.SetupOIDC("console", client, redirectUris, "POST")
if err != nil {
return
}

inst, err = client.GetInstallation("console")
if err != nil {
return
}

return inst.OIDCProvider.ClientId, inst.OIDCProvider.ClientSecret, nil
}

0 comments on commit 82f4d0f

Please sign in to comment.