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
4 changes: 4 additions & 0 deletions golang/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,7 @@ test-cli:
.PHONY: coverage
coverage:
go tool cover -func ./merged.cov

.PHONY: fieldalign
fieldalign:
fieldalign -fix ./...
25 changes: 14 additions & 11 deletions golang/api/v1/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,20 @@ type ContainerConfig struct {
Networks []string `json:"networks"`
Ports []builder.PortBinding `json:"port" binding:"dive"`
PortRanges []builder.PortRangeBinding `json:"portRanges" binding:"dive"`
CustomHeaders []string `json:"customHeaders,omitempty"`
Mounts []string `json:"mount"`
IngressPort uint16 `json:"ingressPort"`
Replicas uint8 `json:"replicas"`
Shared bool `json:"shared"`
UseLoadBalancer bool `json:"useLoadBalancer"`
Expose bool `json:"expose"`
ProxyHeaders bool `json:"proxyHeaders"`
ExposeTLS bool `json:"exposeTls"`
IngressStripPath bool `json:"ingressPathStrip"`
TTY bool `json:"tty"`
// These are CORS headers, providing value will enable CORS and add these headers as extra
CorsHeaders []string `json:"corsHeaders,omitempty"`
// Not all headers are proxied downstream by default, this allows the listed headers to reach backends
ProxyHeaders []string `json:"proxyHeaders,omitempty"`
Mounts []string `json:"mount"`
IngressPort uint16 `json:"ingressPort"`
Replicas uint8 `json:"replicas"`
Shared bool `json:"shared"`
ProxyBuffering bool `json:"proxyBuffering"`
UseLoadBalancer bool `json:"useLoadBalancer"`
Expose bool `json:"expose"`
ExposeTLS bool `json:"exposeTls"`
IngressStripPath bool `json:"ingressPathStrip"`
TTY bool `json:"tty"`
}

type Metrics struct {
Expand Down
10 changes: 9 additions & 1 deletion golang/internal/mapper/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,15 @@ func mapCraneConfig(crane *agent.CraneContainerConfig, containerConfig *v1.Conta
containerConfig.DeploymentStrategy = strcase.ToCamel(crane.DeploymentStrategy.String())

if crane.ProxyHeaders != nil {
containerConfig.ProxyHeaders = *crane.ProxyHeaders
containerConfig.ProxyHeaders = crane.ProxyHeaders
}

if crane.CorsHeaders != nil {
containerConfig.CorsHeaders = crane.CorsHeaders
}

if crane.ProxyBuffering != nil {
containerConfig.ProxyBuffering = *crane.ProxyBuffering
}

if crane.UseLoadBalancer != nil {
Expand Down
6 changes: 2 additions & 4 deletions golang/internal/mapper/grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ func testExpectedCommon(req *agent.DeployWorkloadRequest) *v1.DeployImageRequest
RestartPolicy: container.RestartPolicyAlways,
Networks: []string{"n1", "n2"},
NetworkMode: "BRIDGE",
CustomHeaders: []string(nil),
Annotations: v1.Markers{
Deployment: map[string]string{"annot1": "value1"},
Service: map[string]string{"annot2": "value2"},
Expand All @@ -144,7 +143,7 @@ func testExpectedCommon(req *agent.DeployWorkloadRequest) *v1.DeployImageRequest
Limits: v1.Resources{CPU: "250m", Memory: "512Mi"},
Requests: v1.Resources{CPU: "100m", Memory: "64Mi"},
},
ProxyHeaders: true,
ProxyHeaders: []string{"ProxyHeader"},
UseLoadBalancer: true,
ExtraLBAnnotations: map[string]string{"annotation1": "value1"},
},
Expand Down Expand Up @@ -336,9 +335,8 @@ func testCraneConfig() *agent.CraneContainerConfig {
sProbe := "/test-startup"
port := int32(1234)
return &agent.CraneContainerConfig{
CustomHeaders: []string{"header1", "value1", "header2", "value2"},
ExtraLBAnnotations: map[string]string{"annotation1": "value1"},
ProxyHeaders: &b,
ProxyHeaders: []string{"ProxyHeader"},
UseLoadBalancer: &b,
Labels: &agent.Marker{
Deployment: map[string]string{"label1": "value1"},
Expand Down
20 changes: 20 additions & 0 deletions golang/pkg/crane/k8s/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ func (cm *configmap) deployConfigMapRuntime(runtimeType v1.RuntimeConfigType, na
return nil
}

func (cm *configmap) deployIngressProxyHeaders(namespace, containerName string, headers ...string) error {
client, err := getConfigMapClient(namespace, cm.appConfig)
if err != nil {
return err
}

headerMap := make(map[string]string)
for _, item := range headers {
headerMap[item] = ""
}

_, err = client.Apply(cm.ctx,
corev1.ConfigMap(containerName, namespace).
WithData(headerMap),
metaV1.ApplyOptions{FieldManager: cm.appConfig.FieldManagerName, Force: cm.appConfig.ForceOnConflicts},
)

return err
}

// delete related configmaps. note: configmaps being in use are unaffected by this
func (cm *configmap) deleteConfigMaps(namespace, name string) error {
client, err := getConfigMapClient(namespace, cm.appConfig)
Expand Down
40 changes: 25 additions & 15 deletions golang/pkg/crane/k8s/deploy_facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/rs/zerolog/log"
"k8s.io/apimachinery/pkg/api/errors"

v1 "github.com/dyrector-io/dyrectorio/golang/api/v1"
"github.com/dyrector-io/dyrectorio/golang/internal/dogger"
Expand All @@ -13,8 +14,6 @@ import (
"github.com/dyrector-io/dyrectorio/golang/internal/util"
builder "github.com/dyrector-io/dyrectorio/golang/pkg/builder/container"
"github.com/dyrector-io/dyrectorio/golang/pkg/crane/config"

"k8s.io/apimachinery/pkg/api/errors"
)

type DeployFacade struct {
Expand Down Expand Up @@ -213,28 +212,39 @@ func (d *DeployFacade) Deploy() error {
}

if d.params.ContainerConfig.Expose {
if len(d.params.ContainerConfig.ProxyHeaders) > 0 {
if err := d.configmap.deployIngressProxyHeaders(d.namespace.name,
d.params.ContainerConfig.Container,
d.params.ContainerConfig.ProxyHeaders...,
); err != nil {
log.Error().Err(err).Stack().Msg("Error with ingress proxy headers configmap")
}
}

if err := d.ingress.deployIngress(
&DeployIngressOptions{
namespace: d.namespace.name,
containerName: d.params.ContainerConfig.Container,
ingressName: d.params.ContainerConfig.IngressName,
ingressHost: d.params.ContainerConfig.IngressHost,
ingressPath: d.params.ContainerConfig.IngressPath,
stripPrefix: d.params.ContainerConfig.IngressStripPath,
uploadLimit: d.params.ContainerConfig.IngressUploadLimit,
customHeaders: d.params.ContainerConfig.CustomHeaders,
port: d.params.ContainerConfig.IngressPort,
portList: d.service.portsBound,
tls: d.params.ContainerConfig.ExposeTLS,
proxyHeaders: d.params.ContainerConfig.ProxyHeaders,
annotations: d.params.ContainerConfig.Annotations.Ingress,
labels: d.params.ContainerConfig.Labels.Ingress,
name: d.params.ContainerConfig.IngressName,
routing: routingOptions{
proxyBuffering: d.params.ContainerConfig.ProxyBuffering,
ingressHost: d.params.ContainerConfig.IngressHost,
ingressPath: d.params.ContainerConfig.IngressPath,
stripPrefix: d.params.ContainerConfig.IngressStripPath,
uploadLimit: d.params.ContainerConfig.IngressUploadLimit,
proxyHeaders: d.params.ContainerConfig.ProxyHeaders,
corsHeaders: d.params.ContainerConfig.CorsHeaders,
port: d.params.ContainerConfig.IngressPort,
portList: d.service.portsBound,
tls: d.params.ContainerConfig.ExposeTLS,
},
annotations: d.params.ContainerConfig.Annotations.Ingress,
labels: d.params.ContainerConfig.Labels.Ingress,
},
); err != nil {
log.Error().Err(err).Stack().Msg("Error with ingress")
}
}

return nil
}

Expand Down
71 changes: 35 additions & 36 deletions golang/pkg/crane/k8s/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
applymetav1 "k8s.io/client-go/applyconfigurations/meta/v1"
netv1 "k8s.io/client-go/applyconfigurations/networking/v1"
networking "k8s.io/client-go/kubernetes/typed/networking/v1"

"github.com/dyrector-io/dyrectorio/golang/internal/domain"
"github.com/dyrector-io/dyrectorio/golang/internal/util"
"github.com/dyrector-io/dyrectorio/golang/pkg/crane/config"

networking "k8s.io/client-go/kubernetes/typed/networking/v1"
)

// facade object for ingress management
Expand All @@ -28,21 +27,26 @@ type ingress struct {
status string
}

type routingOptions struct {
ingressHost string
ingressPath string
uploadLimit string
proxyHeaders []string
corsHeaders []string
portList []int32
port uint16
proxyBuffering bool
stripPrefix bool
tls bool
}

type DeployIngressOptions struct {
annotations map[string]string
labels map[string]string
containerName string
ingressName string
ingressHost string
ingressPath string
uploadLimit string
name string
namespace string
customHeaders []string
portList []int32
port uint16
stripPrefix bool
proxyHeaders bool
tls bool
routing routingOptions
}

func newIngress(ctx context.Context, client *Client) *ingress {
Expand All @@ -59,29 +63,31 @@ func (ing *ingress) deployIngress(options *DeployIngressOptions) error {
log.Error().Err(err).Stack().Msg("Error with ingress client")
}

if options.port == 0 && len(options.portList) == 0 {
routing := options.routing

if routing.port == 0 && len(routing.portList) == 0 {
return errors.New("empty ports, nothing to expose")
}

routedPort := options.port
routedPort := routing.port
if routedPort == 0 {
routedPort = uint16(options.portList[0]) //#nosec G115
routedPort = uint16(routing.portList[0]) //#nosec G115
}

ingressDomain := domain.GetHostRule(
&domain.HostRouting{
Subdomain: options.ingressName,
RootDomain: options.ingressHost,
Subdomain: options.name,
RootDomain: routing.ingressHost,
ContainerName: options.containerName,
Prefix: options.namespace,
DomainFallback: ing.appConfig.RootDomain,
})

ingressPath := "/"
if options.ingressPath != "" {
ingressPath = options.ingressPath
if routing.ingressPath != "" {
ingressPath = routing.ingressPath
// prefix stripping works in combination with annotations
if options.stripPrefix {
if routing.stripPrefix {
split := strings.Split(ingressPath, "/")

split = append(split, "?(.*)")
Expand All @@ -105,12 +111,12 @@ func (ing *ingress) deployIngress(options *DeployIngressOptions) error {
),
),
)))
tlsConf := getTLSConfig(ingressDomain, options.containerName, options.tls)
tlsConf := getTLSConfig(ingressDomain, options.containerName, options.routing.tls)
if tlsConf != nil {
spec.WithTLS(tlsConf)
}

annot := getIngressAnnotations(options)
annot := getIngressAnnotations(options.namespace, options.containerName, &options.routing)
maps.Copy(annot, options.annotations)

labels := map[string]string{}
Expand Down Expand Up @@ -153,9 +159,7 @@ func getTLSConfig(ingressPath, containerName string, enabled bool) *netv1.Ingres
return nil
}

func getIngressAnnotations(opts *DeployIngressOptions) map[string]string {
corsHeaders := []string{}

func getIngressAnnotations(namespace, name string, opts *routingOptions) map[string]string {
annotations := map[string]string{
"kubernetes.io/ingress.class": "nginx",
}
Expand All @@ -165,23 +169,18 @@ func getIngressAnnotations(opts *DeployIngressOptions) map[string]string {
annotations["cert-manager.io/cluster-issuer"] = "letsencrypt-prod"
}

// Add Custom Headers to the CORS Allow Header annotation if presents
if len(opts.customHeaders) > 0 {
corsHeaders = opts.customHeaders
if len(opts.corsHeaders) > 0 {
annotations["nginx.ingress.kubernetes.io/enable-cors"] = "true"
annotations["nginx.ingress.kubernetes.io/cors-allow-headers"] = strings.Join(opts.proxyHeaders, ", ")
}

if opts.proxyHeaders {
extraHeaders := []string{"X-Forwarded-For", "X-Forwarded-Host", "X-Forwarded-Server", "X-Real-IP", "X-Requested-With"}
corsHeaders = append(corsHeaders, extraHeaders...)

annotations["nginx.ingress.kubernetes.io/enable-cors"] = "true"
if opts.proxyBuffering {
annotations["nginx.ingress.kubernetes.io/proxy-buffering"] = "on"
annotations["nginx.ingress.kubernetes.io/proxy-buffer-size"] = "256k"
}

// Add header string to cors-allow-headers if presents any value
if len(corsHeaders) > 0 {
annotations["nginx.ingress.kubernetes.io/cors-allow-headers"] = strings.Join(corsHeaders, ", ")
if len(opts.proxyHeaders) > 0 {
annotations["nginx.ingress.kubernetes.io/proxy-set-headers"] = util.JoinV("/", namespace, name)
}

if opts.uploadLimit != "" {
Expand Down
1 change: 1 addition & 0 deletions golang/pkg/dagent/utils/dockerhelper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ func TestEventToMessageContainer(t *testing.T) {

assert.NoError(t, err)

// if this is failing locally, you have to log in to ghcr.io
containerID := *builder.GetContainerID()

event := events.Message{
Expand Down
Loading
Loading