Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not generate proxy env secret for non private clusters. #463

Merged
merged 6 commits into from
Feb 14, 2024
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Do not generate proxy env secret for non private clusters.

## [2.20.0] - 2024-02-12

### Changed
Expand Down
57 changes: 6 additions & 51 deletions service/controller/resource/clusterconfigmap/desired.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/giantswarm/cluster-apps-operator/v2/service/controller/key"
infra "github.com/giantswarm/cluster-apps-operator/v2/service/internal/infrastructure"
"github.com/giantswarm/cluster-apps-operator/v2/service/internal/podcidr"
"github.com/giantswarm/cluster-apps-operator/v2/service/internal/privatecluster"
)

func (r *Resource) GetDesiredState(ctx context.Context, obj interface{}) ([]*corev1.ConfigMap, error) {
Expand Down Expand Up @@ -109,66 +110,20 @@ func (r *Resource) GetDesiredState(ctx context.Context, obj interface{}) ([]*cor
// gcpProject is only used on gcp.
gcpProject = ""
gcpProjectFound bool
// privateCluster is used only on aws in case the cluster vpc mode is private
privateCluster bool
)
privateCluster, err := privatecluster.IsPrivateCluster(ctx, r.logger, r.k8sClient.CtrlClient(), cr)
if err != nil {
return nil, microerror.Mask(err)
}

{
infrastructureRef := cr.Spec.InfrastructureRef
if infrastructureRef != nil {
switch infrastructureRef.Kind {
case infra.AzureClusterKind, infra.AzureManagedClusterKind:
provider = infra.AzureClusterKindProvider

capzCluster := &unstructured.Unstructured{}
capzCluster.SetGroupVersionKind(schema.GroupVersionKind{
Group: infrastructureRef.GroupVersionKind().Group,
Kind: infrastructureRef.Kind,
Version: infrastructureRef.GroupVersionKind().Version,
})
err = r.k8sClient.CtrlClient().Get(ctx, client.ObjectKey{
Namespace: cr.Namespace,
Name: infrastructureRef.Name,
}, capzCluster)
if err != nil {
return nil, microerror.Mask(err)
}

// TODO: We need to enable this for CAPZ clusters but we first need to understand the implication of this change to the Cilium CNI and the cluster as a whole
// blocks := azureCluster.Spec.NetworkSpec.Vnet.CIDRBlocks
// if len(blocks) > 0 {
// clusterCIDR = blocks[0]
// }

apiServerLbType, apiServerLbFound, err := unstructured.NestedString(capzCluster.Object, []string{"spec", "networkSpec", "apiServerLB", "type"}...)
if err != nil || !apiServerLbFound {
return nil, microerror.Mask(fieldNotFoundOnInfrastructureTypeError)
}

privateCluster = apiServerLbType == "Internal"

case infra.AWSClusterKind, infra.AWSManagedClusterKind:
provider = infra.AWSClusterKindProvider

awsCluster := &unstructured.Unstructured{}
awsCluster.SetGroupVersionKind(schema.GroupVersionKind{
Group: infrastructureRef.GroupVersionKind().Group,
Kind: infrastructureRef.Kind,
Version: infrastructureRef.GroupVersionKind().Version,
})
err = r.k8sClient.CtrlClient().Get(ctx, client.ObjectKey{
Namespace: cr.Namespace,
Name: infrastructureRef.Name,
}, awsCluster)
if err != nil {
return nil, microerror.Mask(err)
}

annotationValue, annotationFound, err := unstructured.NestedString(awsCluster.Object, []string{"metadata", "annotations", annotation.AWSVPCMode}...)
if err != nil || !annotationFound {
return nil, microerror.Mask(fieldNotFoundOnInfrastructureTypeError)
}

privateCluster = annotationValue == annotation.AWSVPCModePrivate
case infra.VCDClusterKind:
provider = infra.VCDClusterKindProvider
privateCluster = !reflect.ValueOf(r.proxy).IsZero()
whites11 marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
10 changes: 9 additions & 1 deletion service/controller/resource/clustersecret/desired.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/giantswarm/cluster-apps-operator/v2/pkg/project"
"github.com/giantswarm/cluster-apps-operator/v2/service/controller/key"
infra "github.com/giantswarm/cluster-apps-operator/v2/service/internal/infrastructure"
"github.com/giantswarm/cluster-apps-operator/v2/service/internal/privatecluster"
)

const (
Expand Down Expand Up @@ -53,6 +54,10 @@ func (r *Resource) GetDesiredState(ctx context.Context, obj interface{}) ([]*cor
}

values := map[string]interface{}{}
privateCluster, err := privatecluster.IsPrivateCluster(ctx, r.logger, r.k8sClient.CtrlClient(), cr)
if err != nil {
return nil, microerror.Mask(err)
}

{
infrastructureRef := cr.Spec.InfrastructureRef
Expand All @@ -69,6 +74,9 @@ func (r *Resource) GetDesiredState(ctx context.Context, obj interface{}) ([]*cor
if err != nil {
return nil, microerror.Mask(err)
}

// CAPV all clusters are private if the MC is private.
privateCluster = !reflect.ValueOf(r.proxy).IsZero()
}
}
}
Expand All @@ -81,7 +89,7 @@ func (r *Resource) GetDesiredState(ctx context.Context, obj interface{}) ([]*cor
},
}

if !reflect.ValueOf(r.proxy).IsZero() {
if privateCluster && !reflect.ValueOf(r.proxy).IsZero() {
whites11 marked this conversation as resolved.
Show resolved Hide resolved
r.logger.Debugf(ctx, "proxy secrets for cluster '%s/%s' : %v", cr.GetNamespace(), key.ClusterID(&cr), r.proxy)

noProxy := noProxy(cr, r.proxy.NoProxy)
Expand Down
14 changes: 14 additions & 0 deletions service/internal/privatecluster/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package privatecluster

import (
"github.com/giantswarm/microerror"
)

var fieldNotFoundOnInfrastructureTypeError = &microerror.Error{
Kind: "fieldNotFoundOnInfrastructureType",
}

// IsFieldNotFoundOnInfrastructureType asserts fieldNotFoundOnInfrastructureTypeError.
func IsFieldNotFoundOnInfrastructureType(err error) bool {
return microerror.Cause(err) == fieldNotFoundOnInfrastructureTypeError
}
79 changes: 79 additions & 0 deletions service/internal/privatecluster/privatecluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package privatecluster

import (
"context"

"github.com/giantswarm/k8smetadata/pkg/annotation"
"github.com/giantswarm/microerror"
"github.com/giantswarm/micrologger"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
capi "sigs.k8s.io/cluster-api/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"

infra "github.com/giantswarm/cluster-apps-operator/v2/service/internal/infrastructure"
)

// IsPrivateCluster returns true if the cluster is a private cluster (i.e. it has no direct internet access).
// -In CAPZ and CAPA, we respect WC attributes. A non-private WC can exist in a private MC
// - In CAPV and CAPVCD, we respect MC attributes. If MC is private, all WCs are private.
// - In CAPG, we don’t have private concept.
func IsPrivateCluster(ctx context.Context, logger micrologger.Logger, ctrlclient client.Client, cr capi.Cluster) (bool, error) {
var privateCluster bool
var err error

infrastructureRef := cr.Spec.InfrastructureRef
if infrastructureRef != nil {
switch infrastructureRef.Kind {
case infra.AzureClusterKind, infra.AzureManagedClusterKind:
capzCluster := &unstructured.Unstructured{}
capzCluster.SetGroupVersionKind(schema.GroupVersionKind{
Group: infrastructureRef.GroupVersionKind().Group,
Kind: infrastructureRef.Kind,
Version: infrastructureRef.GroupVersionKind().Version,
})
err = ctrlclient.Get(ctx, client.ObjectKey{
Namespace: cr.Namespace,
Name: infrastructureRef.Name,
}, capzCluster)
if err != nil {
return false, microerror.Mask(err)
}

apiServerLbType, apiServerLbFound, err := unstructured.NestedString(capzCluster.Object, []string{"spec", "networkSpec", "apiServerLB", "type"}...)
if err != nil || !apiServerLbFound {
return false, microerror.Mask(fieldNotFoundOnInfrastructureTypeError)
}

privateCluster = apiServerLbType == "Internal"
case infra.AWSClusterKind, infra.AWSManagedClusterKind:
awsCluster := &unstructured.Unstructured{}
awsCluster.SetGroupVersionKind(schema.GroupVersionKind{
Group: infrastructureRef.GroupVersionKind().Group,
Kind: infrastructureRef.Kind,
Version: infrastructureRef.GroupVersionKind().Version,
})
err = ctrlclient.Get(ctx, client.ObjectKey{
Namespace: cr.Namespace,
Name: infrastructureRef.Name,
}, awsCluster)
if err != nil {
return false, microerror.Mask(err)
}

annotationValue, annotationFound, err := unstructured.NestedString(awsCluster.Object, []string{"metadata", "annotations", annotation.AWSVPCMode}...)
if err != nil || !annotationFound {
return false, microerror.Mask(fieldNotFoundOnInfrastructureTypeError)
}

privateCluster = annotationValue == annotation.AWSVPCModePrivate
case infra.GCPClusterKind, infra.GCPManagedClusterKind:
// We don't support private clusters on GCP yet.
privateCluster = false
default:
logger.Debugf(ctx, "privatecluster.IsPrivateCluster in not implemented for infrastructure kind %q", infrastructureRef.Kind)
}
}

return privateCluster, nil
}
Loading
Loading