2022-12-08 13:05:19 -03:00

171 lines
4.6 KiB
Go

// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.
package proxy
import (
"bytes"
_ "embed"
"encoding/base64"
"fmt"
"text/template"
"github.com/gitpod-io/gitpod/installer/pkg/common"
ideProxyComponent "github.com/gitpod-io/gitpod/installer/pkg/components/ide-proxy"
minioComponent "github.com/gitpod-io/gitpod/installer/pkg/components/minio"
openvsxproxy "github.com/gitpod-io/gitpod/installer/pkg/components/openvsx-proxy"
"golang.org/x/crypto/bcrypt"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
)
//go:embed templates/configmap/vhost.docker-registry.tpl
var vhostDockerRegistry []byte
//go:embed templates/configmap/vhost.empty.tpl
var vhostEmptyTmpl []byte
//go:embed templates/configmap/vhost.minio.tpl
var vhostMinioTmpl []byte
//go:embed templates/configmap/vhost.open-vsx.tpl
var vhostOpenVSXTmpl []byte
//go:embed templates/configmap/vhost.ide-proxy.tpl
var ideProxyTmpl []byte
//go:embed templates/configmap/vhost.payment-endpoint.tpl
var vhostPaymentEndpointTmpl []byte
type commonTpl struct {
Domain string
ReverseProxy string
}
type dockerRegistryTpl struct {
Domain string
ReverseProxy string
Username string
Password string
}
type openVSXTpl struct {
Domain string
RepoURL string
}
func renderTemplate(tpl []byte, values interface{}) (*string, error) {
t, err := template.New("template").Parse(string(tpl))
if err != nil {
return nil, err
}
var parsed bytes.Buffer
err = t.Execute(&parsed, values)
if err != nil {
return nil, err
}
rendered := parsed.String()
return &rendered, nil
}
const kubeDomain = "svc.cluster.local"
func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
empty, err := renderTemplate(vhostEmptyTmpl, nil)
if err != nil {
return nil, err
}
openVSX, err := renderTemplate(vhostOpenVSXTmpl, openVSXTpl{
Domain: ctx.Config.Domain,
RepoURL: fmt.Sprintf("openvsx-proxy.%s.%s:%d", ctx.Namespace, kubeDomain, openvsxproxy.ServicePort),
})
if err != nil {
return nil, err
}
ideProxy, err := renderTemplate(ideProxyTmpl, commonTpl{
Domain: ctx.Config.Domain,
ReverseProxy: fmt.Sprintf("ide-proxy.%s.%s:%d", ctx.Namespace, kubeDomain, ideProxyComponent.ServicePort),
})
if err != nil {
return nil, err
}
paymentEndpoint, err := renderTemplate(vhostPaymentEndpointTmpl, commonTpl{
Domain: ctx.Config.Domain,
ReverseProxy: fmt.Sprintf("payment-endpoint.%s.%s:%d", ctx.Namespace, kubeDomain, 3002), // todo(sje): get port from (future) config
})
if err != nil {
return nil, err
}
data := map[string]string{
"vhost.empty": *empty,
"vhost.open-vsx": *openVSX,
"vhost.payment-endpoint": *paymentEndpoint,
"vhost.ide-proxy": *ideProxy,
}
if ctx.Config.ObjectStorage.CloudStorage == nil {
// Don't expose Minio if using cloud storage
minio, err := renderTemplate(vhostMinioTmpl, commonTpl{
Domain: ctx.Config.Domain,
ReverseProxy: fmt.Sprintf("minio.%s.%s:%d", ctx.Namespace, kubeDomain, minioComponent.ServiceConsolePort),
})
if err != nil {
return nil, err
}
data["vhost.minio"] = *minio
}
if pointer.BoolDeref(ctx.Config.ContainerRegistry.InCluster, false) {
username := ctx.Values.InternalRegistryUsername
if username == "" {
return nil, fmt.Errorf("unknown value: internal registry username")
}
password := ctx.Values.InternalRegistryPassword
if password == "" {
return nil, fmt.Errorf("unknown value: internal registry password")
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
dockerRegistry, err := renderTemplate(vhostDockerRegistry, dockerRegistryTpl{
Domain: ctx.Config.Domain,
ReverseProxy: fmt.Sprintf("https://%s.%s.%s", common.DockerRegistryName, ctx.Namespace, kubeDomain),
Username: username,
Password: base64.StdEncoding.EncodeToString(hashedPassword),
})
if err != nil {
return nil, err
}
data["vhost.docker-registry"] = *dockerRegistry
}
return []runtime.Object{
&corev1.ConfigMap{
TypeMeta: common.TypeMetaConfigmap,
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-config", Component),
Namespace: ctx.Namespace,
Labels: common.CustomizeLabel(ctx, Component, common.TypeMetaConfigmap),
Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaConfigmap),
},
Data: data,
},
}, nil
}