Skip to content

Commit 3080410

Browse files
authored
Merge pull request #532 from cnvergence/fix-host-aliases
Add option to configure host aliases for konnector
2 parents 454b88a + 3f2393b commit 3080410

8 files changed

Lines changed: 280 additions & 109 deletions

File tree

backend/http/handler.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"time"
2828

2929
"github.com/gorilla/mux"
30+
corev1 "k8s.io/api/core/v1"
3031
apierrors "k8s.io/apimachinery/pkg/api/errors"
3132
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3233
"k8s.io/apimachinery/pkg/runtime"
@@ -220,7 +221,7 @@ func (h *handler) handleKonnectorManifests(w http.ResponseWriter, r *http.Reques
220221
}
221222
konnectorImage := fmt.Sprintf("ghcr.io/kube-bind/konnector:%s", konnectorVersion)
222223

223-
manifests := kuberesources.NewKonnectorManifests(konnectorImage, nil)
224+
manifests := kuberesources.NewKonnectorManifests(konnectorImage, h.kubeManager.GetKonnectorHostAliases())
224225

225226
// Serialize each object to YAML and join with document separators
226227
s := runtime.NewScheme()
@@ -556,6 +557,9 @@ type applyBindingRequest struct {
556557
ConsumerKubeconfig string `json:"consumerKubeconfig"`
557558
// BindingName is the name for the binding (used for secret and bundle naming).
558559
BindingName string `json:"bindingName"`
560+
// HostAliases is an optional list of host alias entries for konnector pods,
561+
// in the format "IP:hostname1,hostname2". Overrides the server-configured defaults.
562+
HostAliases []string `json:"hostAliases,omitempty"`
559563
}
560564

561565
// handleApplyBinding receives a consumer kubeconfig and applies the konnector + binding
@@ -610,13 +614,26 @@ func (h *handler) handleApplyBinding(w http.ResponseWriter, r *http.Request) {
610614
}
611615
konnectorImage := fmt.Sprintf("ghcr.io/kube-bind/konnector:%s", konnectorVersion)
612616

617+
// Parse optional host alias overrides from request
618+
var overrideHostAliases []corev1.HostAlias
619+
for _, entry := range req.HostAliases {
620+
parts := strings.SplitN(entry, ":", 2)
621+
if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
622+
overrideHostAliases = append(overrideHostAliases, corev1.HostAlias{
623+
IP: parts[0],
624+
Hostnames: strings.Split(parts[1], ","),
625+
})
626+
}
627+
}
628+
613629
// Apply to consumer cluster
614630
result, err := h.kubeManager.ApplyToConsumer(
615631
r.Context(),
616632
consumerKubeconfigData,
617633
handleResult.Kubeconfig,
618634
req.BindingName,
619635
konnectorImage,
636+
overrideHostAliases,
620637
)
621638
if err != nil {
622639
logger.Error(err, "failed to apply binding to consumer cluster")

backend/kubernetes/manager.go

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ type Manager struct {
5858

5959
manager mcmanager.Manager
6060
embeddedOIDC bool
61+
62+
// konnectorHostAliases are default host aliases injected into konnector
63+
// pods deployed via the UI flow (configured via --konnector-host-alias flag).
64+
konnectorHostAliases []corev1.HostAlias
6165
}
6266

6367
func NewKubernetesManager(
@@ -69,6 +73,7 @@ func NewKubernetesManager(
6973
externalTLSServerName string,
7074
manager mcmanager.Manager,
7175
embeddedOIDC bool,
76+
konnectorHostAliases []corev1.HostAlias,
7277
) (*Manager, error) {
7378
m := &Manager{
7479
namespacePrefix: namespacePrefix,
@@ -79,8 +84,9 @@ func NewKubernetesManager(
7984
externalCA: externalCA,
8085
externalTLSServerName: externalTLSServerName,
8186

82-
manager: manager,
83-
embeddedOIDC: embeddedOIDC,
87+
manager: manager,
88+
embeddedOIDC: embeddedOIDC,
89+
konnectorHostAliases: konnectorHostAliases,
8490
}
8591

8692
if err := m.manager.GetFieldIndexer().IndexField(ctx, &corev1.Namespace{}, NamespacesByIdentity,
@@ -465,6 +471,7 @@ func (m *Manager) ApplyToConsumer(
465471
providerKubeconfigData []byte,
466472
bindingName string,
467473
konnectorImage string,
474+
overrideHostAliases []corev1.HostAlias,
468475
) (*ApplyToConsumerResult, error) {
469476
logger := klog.FromContext(ctx).WithValues("bindingName", bindingName)
470477

@@ -495,10 +502,17 @@ func (m *Manager) ApplyToConsumer(
495502
return nil, fmt.Errorf("failed to create kube-bind namespace: %w", err)
496503
}
497504

498-
// 2. Resolve host aliases from the provider kubeconfig so the konnector
499-
// can reach the provider API server (needed in Kind/Docker environments
500-
// where the hostname resolves to localhost on the host but not in pods).
501-
hostAliases := m.resolveProviderHostAliases(ctx, providerKubeconfigData)
505+
// 2. Build host aliases: start with request overrides (if any), fall back to
506+
// configured defaults, then merge any auto-resolved aliases from the provider kubeconfig.
507+
var hostAliases []corev1.HostAlias
508+
if len(overrideHostAliases) > 0 {
509+
hostAliases = append(hostAliases, overrideHostAliases...)
510+
} else {
511+
hostAliases = append(hostAliases, m.konnectorHostAliases...)
512+
}
513+
if resolved := m.resolveProviderHostAliases(ctx, providerKubeconfigData); len(resolved) > 0 {
514+
hostAliases = mergeHostAliases(hostAliases, resolved)
515+
}
502516

503517
// 3. Deploy konnector (idempotent)
504518
konnectorDeployed, err := m.ensureKonnector(ctx, consumerClient, konnectorImage, hostAliases)
@@ -633,18 +647,24 @@ func (m *Manager) resolveProviderHostAliases(ctx context.Context, providerKubeco
633647
// ensureKonnector deploys the konnector agent to the consumer cluster.
634648
// Returns true if the konnector was newly deployed, false if it already existed.
635649
func (m *Manager) ensureKonnector(ctx context.Context, c client.Client, konnectorImage string, hostAliases []corev1.HostAlias) (bool, error) {
650+
manifests := kuberesources.NewKonnectorManifests(konnectorImage, hostAliases)
651+
636652
// Check if konnector deployment already exists
637653
existing := &appsv1.Deployment{}
638654
err := c.Get(ctx, types.NamespacedName{Name: kuberesources.KonnectorDeploymentName, Namespace: kuberesources.KonnectorNamespace}, existing)
639655
if err == nil {
640-
return false, nil // already deployed
656+
// Update the deployment if host aliases changed
657+
existing.Spec.Template.Spec.HostAliases = hostAliases
658+
existing.Spec.Template.Spec.Containers[0].Image = konnectorImage
659+
if err := c.Update(ctx, existing); err != nil {
660+
return false, fmt.Errorf("failed to update konnector deployment: %w", err)
661+
}
662+
return false, nil
641663
}
642664
if !errors.IsNotFound(err) {
643665
return false, fmt.Errorf("failed to check for existing konnector: %w", err)
644666
}
645667

646-
manifests := kuberesources.NewKonnectorManifests(konnectorImage, hostAliases)
647-
648668
if err := c.Create(ctx, manifests.ServiceAccount); err != nil && !errors.IsAlreadyExists(err) {
649669
return false, fmt.Errorf("failed to create konnector service account: %w", err)
650670
}
@@ -698,3 +718,24 @@ func (m *Manager) SeedDefaultCluster(ctx context.Context) error {
698718
logger.Info("Default Cluster resource ensured")
699719
return nil
700720
}
721+
722+
// GetKonnectorHostAliases returns the configured default host aliases for konnector pods.
723+
func (m *Manager) GetKonnectorHostAliases() []corev1.HostAlias {
724+
return m.konnectorHostAliases
725+
}
726+
727+
// mergeHostAliases merges additional host aliases into existing ones,
728+
// skipping entries whose IP is already present.
729+
func mergeHostAliases(existing, additional []corev1.HostAlias) []corev1.HostAlias {
730+
seen := make(map[string]bool, len(existing))
731+
for _, ha := range existing {
732+
seen[ha.IP] = true
733+
}
734+
for _, ha := range additional {
735+
if !seen[ha.IP] {
736+
existing = append(existing, ha)
737+
seen[ha.IP] = true
738+
}
739+
}
740+
return existing
741+
}

backend/options/options.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ type ExtraOptions struct {
7979
// SchemaSyncInterval is how often the serviceexportrequest controller re-reconciles
8080
// to detect source schema changes when SchemaUpdatePolicy is Always.
8181
SchemaSyncInterval time.Duration
82+
83+
// KonnectorHostAlias is a list of host alias entries for konnector pods
84+
// deployed via the UI flow, in the format IP:hostname1,hostname2.
85+
KonnectorHostAlias []string
8286
}
8387

8488
type completedOptions struct {
@@ -195,6 +199,7 @@ func (options *Options) AddFlags(fs *pflag.FlagSet) {
195199

196200
fs.StringVar(&options.TestingAutoSelect, "testing-auto-select", options.TestingAutoSelect, "<resource>.<group> that is automatically selected on th bind screen for testing")
197201
fs.MarkHidden("testing-auto-select") //nolint:errcheck
202+
fs.StringSliceVar(&options.KonnectorHostAlias, "konnector-host-alias", options.KonnectorHostAlias, "Add host aliases to konnector pods deployed via the UI flow, in the format IP:hostname1,hostname2. Can be specified multiple times.")
198203
}
199204

200205
func (options *Options) Complete() (*CompletedOptions, error) {
@@ -323,5 +328,12 @@ func (options *CompletedOptions) Validate() error {
323328
return fmt.Errorf("--schema-sync-interval must be at least 10s, got %v", options.SchemaSyncInterval)
324329
}
325330

331+
for _, entry := range options.KonnectorHostAlias {
332+
parts := strings.SplitN(entry, ":", 2)
333+
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
334+
return fmt.Errorf("invalid --konnector-host-alias %q, expected format IP:hostname1,hostname2", entry)
335+
}
336+
}
337+
326338
return nil
327339
}

backend/server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import (
2222
"fmt"
2323
"net"
2424
nethttp "net/http"
25+
"strings"
2526
"sync"
2627

28+
corev1 "k8s.io/api/core/v1"
2729
"k8s.io/klog/v2"
2830
"k8s.io/utils/ptr"
2931
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -79,6 +81,18 @@ func NewServer(ctx context.Context, c *Config) (*Server, error) {
7981
Config: c,
8082
}
8183

84+
// Parse konnector host aliases from flag
85+
var konnectorHostAliases []corev1.HostAlias
86+
for _, entry := range c.Options.KonnectorHostAlias {
87+
parts := strings.SplitN(entry, ":", 2)
88+
if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
89+
konnectorHostAliases = append(konnectorHostAliases, corev1.HostAlias{
90+
IP: parts[0],
91+
Hostnames: strings.Split(parts[1], ","),
92+
})
93+
}
94+
}
95+
8296
var err error
8397
s.Kubernetes, err = kube.NewKubernetesManager(
8498
ctx,
@@ -90,6 +104,7 @@ func NewServer(ctx context.Context, c *Config) (*Server, error) {
90104
c.Options.TLSExternalServerName,
91105
s.Config.Manager,
92106
c.Options.OIDC.Type == string(kubebindv1alpha2.OIDCProviderTypeEmbedded),
107+
konnectorHostAliases,
93108
)
94109
if err != nil {
95110
return nil, fmt.Errorf("error setting up Kubernetes Manager: %w", err)

0 commit comments

Comments
 (0)