Skip to content
Open
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
10 changes: 10 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth"

cmacmev1 "github.com/cert-manager/cert-manager/pkg/apis/acme/v1"
cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
envoygatewayv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1"
multiclusterproviders "go.miloapis.com/milo/pkg/multicluster-runtime"
milomulticluster "go.miloapis.com/milo/pkg/multicluster-runtime/milo"
Expand Down Expand Up @@ -65,6 +66,7 @@ func init() {
utilruntime.Must(envoygatewayv1alpha1.AddToScheme(scheme))
utilruntime.Must(networkingv1alpha1.AddToScheme(scheme))
utilruntime.Must(cmacmev1.AddToScheme(scheme))
utilruntime.Must(cmv1.AddToScheme(scheme))
utilruntime.Must(dnsv1alpha1.AddToScheme(scheme))
// +kubebuilder:scaffold:scheme
}
Expand Down Expand Up @@ -121,6 +123,8 @@ func main() {
// TODO(jreese) validate the config

cfg := ctrl.GetConfigOrDie()
cfg.QPS = 50
cfg.Burst = 100

deploymentCluster, err := cluster.New(cfg, func(o *cluster.Options) {
o.Scheme = scheme
Expand Down Expand Up @@ -187,6 +191,8 @@ func main() {
setupLog.Error(err, "unable to load control plane kubeconfig")
os.Exit(1)
}
downstreamRestConfig.QPS = 50
downstreamRestConfig.Burst = 100

downstreamCluster, err := cluster.New(downstreamRestConfig, func(o *cluster.Options) {
o.Scheme = scheme
Expand Down Expand Up @@ -439,11 +445,15 @@ func initializeClusterDiscovery(
if err != nil {
return nil, nil, fmt.Errorf("unable to get discovery rest config: %w", err)
}
discoveryRestConfig.QPS = 50
discoveryRestConfig.Burst = 100

projectRestConfig, err := serverConfig.Discovery.ProjectRestConfig()
if err != nil {
return nil, nil, fmt.Errorf("unable to get project rest config: %w", err)
}
projectRestConfig.QPS = 50
projectRestConfig.Burst = 100

discoveryManager, err := manager.New(discoveryRestConfig, manager.Options{
Client: client.Options{
Expand Down
4 changes: 4 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ rules:
resources:
- certificates
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- coordination.k8s.io
Expand Down
4 changes: 4 additions & 0 deletions config/rbac_downstream/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,12 @@ rules:
resources:
- certificates
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- gateway.envoyproxy.io
Expand Down
26 changes: 15 additions & 11 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,17 +486,6 @@ type GatewayConfig struct {
// issuer name, the operator will use the value as is.
ClusterIssuerMap map[string]string `json:"clusterIssuerMap,omitempty"`

// PerGatewayCertificateIssuer will result in the operator to expect a
// cert-manager Issuer to exist with the same name as the gateway. Any value
// provided for the "gateway.networking.datumapis.com/certificate-issuer"
// option will be replaced with the gateway's name. The Issuer resources will
// be managed by Kyverno policies, and not by this operator.
//
// TODO(jreese) Remove this once we've either implemented DNS validation,
// found a path to attach cert-manager generated routes to the gateway they're
// needed for, or implement our own ACME integration.
PerGatewayCertificateIssuer bool `json:"perGatewayCertificateIssuer,omitempty"`

// ListenerTLSOptions specifies the TLS options to program on generated
// TLS listeners.
// +default={"gateway.networking.datumapis.com/certificate-issuer": "auto"}
Expand Down Expand Up @@ -559,6 +548,15 @@ type GatewayConfig struct {
// Defaults to false.
EnableDNSIntegration bool `json:"enableDNSIntegration,omitempty"`

// DefaultListenerTLSSecretName, if provided, is the name of a
// pre-provisioned TLS certificate secret to use for the default HTTPS
// listener (named "default-https"). When set, this listener references
// the shared secret instead of requesting an individual certificate
// via cert-manager.
//
// The secret must exist in every downstream gateway namespace.
DefaultListenerTLSSecretName string `json:"defaultListenerTLSSecretName,omitempty"`

// MaxConcurrentReconciles is the maximum number of concurrent gateway
// reconciliations. Higher values allow the controller to process gateways
// across multiple projects in parallel.
Expand All @@ -567,6 +565,12 @@ type GatewayConfig struct {
MaxConcurrentReconciles int `json:"maxConcurrentReconciles,omitempty"`
}

// HasDefaultListenerTLSSecret returns true when a shared TLS certificate
// secret has been configured for default HTTPS listeners.
func (c *GatewayConfig) HasDefaultListenerTLSSecret() bool {
return c.DefaultListenerTLSSecretName != ""
}

// ShouldDeleteErroredChallenges returns whether the operator should automatically
// delete errored ACME challenges. Defaults to true if not explicitly set.
func (c *GatewayConfig) ShouldDeleteErroredChallenges() bool {
Expand Down
11 changes: 1 addition & 10 deletions internal/controller/challenge_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,16 @@ func (r *ChallengeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
}

// isGatewayRelatedIssuer checks if the given issuer reference is for a Gateway-managed
// certificate issuer. This includes:
// - ClusterIssuers that are mapped in the ClusterIssuerMap configuration
// - Issuers (namespace-scoped) when PerGatewayCertificateIssuer mode is enabled
// certificate issuer (ClusterIssuers that are mapped in the ClusterIssuerMap configuration).
func (r *ChallengeReconciler) isGatewayRelatedIssuer(ref cmmeta.ObjectReference) bool {
// Check if ClusterIssuer is in the configured map
if ref.Kind == "ClusterIssuer" || ref.Kind == "" {
// Default kind is ClusterIssuer for cert-manager
for _, mappedIssuer := range r.Config.Gateway.ClusterIssuerMap {
if mappedIssuer == ref.Name {
return true
}
}
}

// In per-gateway mode, any namespace-scoped Issuer is gateway-related
if r.Config.Gateway.PerGatewayCertificateIssuer && ref.Kind == "Issuer" {
return true
}

return false
}

Expand Down
26 changes: 5 additions & 21 deletions internal/controller/challenge_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func TestChallengeReconciler(t *testing.T) {
expectDeleted: true,
},
{
name: "errored challenge with Issuer in per-gateway mode is deleted",
name: "errored challenge with namespace-scoped Issuer is not deleted",
challenge: &cmacmev1.Challenge{
ObjectMeta: metav1.ObjectMeta{
Namespace: upstreamNamespace.Name,
Expand All @@ -95,11 +95,9 @@ func TestChallengeReconciler(t *testing.T) {
},
},
config: config.NetworkServicesOperator{
Gateway: config.GatewayConfig{
PerGatewayCertificateIssuer: true,
},
Gateway: config.GatewayConfig{},
},
expectDeleted: true,
expectDeleted: false,
},
{
name: "errored challenge with non-gateway ClusterIssuer is not deleted",
Expand Down Expand Up @@ -258,7 +256,6 @@ func TestChallengeReconciler(t *testing.T) {
},
config: config.NetworkServicesOperator{
Gateway: config.GatewayConfig{
PerGatewayCertificateIssuer: false,
ClusterIssuerMap: map[string]string{
"letsencrypt": "letsencrypt-prod",
},
Expand Down Expand Up @@ -368,25 +365,12 @@ func TestIsGatewayRelatedIssuer(t *testing.T) {
expected: true,
},
{
name: "Issuer in per-gateway mode returns true",
ref: cmmeta.ObjectReference{
Kind: "Issuer",
Name: "gateway-issuer",
},
config: config.GatewayConfig{
PerGatewayCertificateIssuer: true,
},
expected: true,
},
{
name: "Issuer not in per-gateway mode returns false",
name: "namespace-scoped Issuer returns false",
ref: cmmeta.ObjectReference{
Kind: "Issuer",
Name: "gateway-issuer",
},
config: config.GatewayConfig{
PerGatewayCertificateIssuer: false,
},
config: config.GatewayConfig{},
expected: false,
},
{
Expand Down
Loading
Loading