diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 56f4acd7..9859f470 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -23,14 +23,14 @@ jobs: steps: - name: Log in to the container registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ secrets.DOCKER_REGISTRY_USER }} password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: google-github-actions/auth@v1 with: @@ -39,10 +39,11 @@ jobs: - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v0 - - name: Set up Go 1.20 - uses: actions/setup-go@v4 + - name: Set up Go 1.21 + uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: '1.21' + cache: false - name: Lint uses: golangci/golangci-lint-action@v3 @@ -64,7 +65,7 @@ jobs: make - name: Push Docker image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: . push: true @@ -89,12 +90,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: Set up Go 1.20 - uses: actions/setup-go@v4 + - name: Set up Go 1.21 + uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: '1.21' + cache: false - name: Run tests run: | diff --git a/Makefile b/Makefile index bea541ed..20b41be2 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GITVERSION := $(shell git describe --long --all) BUILDDATE := $(shell date -Iseconds) VERSION := $(or ${VERSION},$(shell git describe --tags --exact-match 2> /dev/null || git symbolic-ref -q --short HEAD || git rev-parse --short HEAD)) -CONTROLLER_TOOLS_VERSION ?= v0.11.3 +CONTROLLER_TOOLS_VERSION ?= v0.13.0 LOCALBIN ?= $(shell pwd)/bin CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen ENVTEST ?= $(LOCALBIN)/setup-envtest diff --git a/api/v1/clusterwidenetworkpolicy_types.go b/api/v1/clusterwidenetworkpolicy_types.go index 421855da..8864db65 100644 --- a/api/v1/clusterwidenetworkpolicy_types.go +++ b/api/v1/clusterwidenetworkpolicy_types.go @@ -27,6 +27,8 @@ const ( // +kubebuilder:object:root=true // +kubebuilder:resource:shortName=cwnp // +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.state" +// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.message" type ClusterwideNetworkPolicy struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -67,12 +69,26 @@ type PolicySpec struct { type FQDNState map[string][]IPSet +// PolicyDeploymentState describes the state of a CWNP deployment +type PolicyDeploymentState string + +const ( + // PolicyDeploymentStateDeployed the CWNP was deployed to a native nftable rule + PolicyDeploymentStateDeployed = PolicyDeploymentState("deployed") + // PolicyDeploymentStateIgnored the CWNP was not deployed to a native nftable rule because it is outside of allowed networks + PolicyDeploymentStateIgnored = PolicyDeploymentState("ignored") +) + // PolicyStatus defines the observed state for CWNP resource type PolicyStatus struct { // FQDNState stores mapping from FQDN rules to nftables sets used for a firewall rule. // Key is either MatchName or MatchPattern // +optional FQDNState FQDNState `json:"fqdn_state,omitempty"` + // State of the CWNP, can be either deployed or ignored + State PolicyDeploymentState `json:"state,omitempty"` + // Message describes why the state changed + Message string `json:"message,omitempty"` } // IngressRule describes a particular set of traffic that is allowed to the cluster. diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 72826954..c9863969 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Code generated by controller-gen. DO NOT EDIT. @@ -128,7 +127,8 @@ func (in FQDNState) DeepCopyInto(out *FQDNState) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]IPSet, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) @@ -239,7 +239,8 @@ func (in *PolicyStatus) DeepCopyInto(out *PolicyStatus) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]IPSet, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) diff --git a/config/crd/bases/metal-stack.io_clusterwidenetworkpolicies.yaml b/config/crd/bases/metal-stack.io_clusterwidenetworkpolicies.yaml index b7717485..6ce83c93 100644 --- a/config/crd/bases/metal-stack.io_clusterwidenetworkpolicies.yaml +++ b/config/crd/bases/metal-stack.io_clusterwidenetworkpolicies.yaml @@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.13.0 name: clusterwidenetworkpolicies.metal-stack.io spec: group: metal-stack.io @@ -17,7 +16,14 @@ spec: singular: clusterwidenetworkpolicy scope: Namespaced versions: - - name: v1 + - additionalPrinterColumns: + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .status.message + name: Message + type: string + name: v1 schema: openAPIV3Schema: description: ClusterwideNetworkPolicy contains the desired state for a cluster @@ -252,6 +258,12 @@ spec: description: FQDNState stores mapping from FQDN rules to nftables sets used for a firewall rule. Key is either MatchName or MatchPattern type: object + message: + description: Message describes why the state changed + type: string + state: + description: State of the CWNP, can be either deployed or ignored + type: string type: object type: object served: true diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 65ea3869..6a195b51 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -2,7 +2,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: manager-role rules: - apiGroups: diff --git a/controllers/clusterwidenetworkpolicy_controller.go b/controllers/clusterwidenetworkpolicy_controller.go index 4987d18a..b26bc738 100644 --- a/controllers/clusterwidenetworkpolicy_controller.go +++ b/controllers/clusterwidenetworkpolicy_controller.go @@ -5,13 +5,17 @@ import ( "fmt" "time" - "github.com/metal-stack/firewall-controller/pkg/dns" - "github.com/metal-stack/firewall-controller/pkg/nftables" + "go4.org/netipx" + + "github.com/metal-stack/firewall-controller/v2/pkg/dns" + "github.com/metal-stack/firewall-controller/v2/pkg/helper" + "github.com/metal-stack/firewall-controller/v2/pkg/nftables" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -21,7 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) // ClusterwideNetworkPolicyReconciler reconciles a ClusterwideNetworkPolicy object @@ -33,7 +37,8 @@ type ClusterwideNetworkPolicyReconciler struct { FirewallName string SeedNamespace string - Log logr.Logger + Log logr.Logger + Recorder record.EventRecorder Interval time.Duration DnsProxy *dns.DNSProxy @@ -91,7 +96,14 @@ func (r *ClusterwideNetworkPolicyReconciler) Reconcile(ctx context.Context, _ ct if err := r.ShootClient.List(ctx, &services); err != nil { return ctrl.Result{}, err } - nftablesFirewall := nftables.NewFirewall(f, &cwnps, &services, r.DnsProxy, r.Log) + + validCwnps, err := r.allowedCWNPs(ctx, cwnps.Items, f.Spec.AllowedNetworks) + if err != nil { + return ctrl.Result{}, err + } + cwnps.Items = validCwnps + + nftablesFirewall := nftables.NewFirewall(f, &cwnps, &services, r.DnsProxy, r.Log, r.Recorder) if err := r.manageDNSProxy(ctx, f, cwnps, nftablesFirewall); err != nil { return ctrl.Result{}, err } @@ -103,8 +115,8 @@ func (r *ClusterwideNetworkPolicyReconciler) Reconcile(ctx context.Context, _ ct if updated { for _, i := range cwnps.Items { o := i - if err := r.ShootClient.Status().Update(ctx, &o); err != nil { - return ctrl.Result{}, fmt.Errorf("failed to updated CWNP status: %w", err) + if err := r.updateCWNPState(ctx, o, firewallv1.PolicyDeploymentStateDeployed, ""); err != nil { + return ctrl.Result{}, err } } } @@ -181,3 +193,82 @@ func (r *ClusterwideNetworkPolicyReconciler) getReconciliationTicker(scheduleCha } } } + +func (r *ClusterwideNetworkPolicyReconciler) allowedCWNPs(ctx context.Context, cwnps []firewallv1.ClusterwideNetworkPolicy, allowedNetworks firewallv2.AllowedNetworks) ([]firewallv1.ClusterwideNetworkPolicy, error) { + if len(allowedNetworks.Egress) == 0 && len(allowedNetworks.Ingress) == 0 { + return cwnps, nil + } + + validCWNPs := make([]firewallv1.ClusterwideNetworkPolicy, 0, len(cwnps)) + + egressSet, err := helper.BuildNetworksIPSet(allowedNetworks.Egress) + if err != nil { + return nil, err + } + + ingressSet, err := helper.BuildNetworksIPSet(allowedNetworks.Ingress) + if err != nil { + return nil, err + } + + for _, cwnp := range cwnps { + cwnp := cwnp + oke, err := r.validateCWNPEgressTargetPrefix(cwnp, egressSet) + if err != nil { + return nil, err + } + oki, err := r.validateCWNPIngressTargetPrefix(cwnp, ingressSet) + if err != nil { + return nil, err + } + + if !oki || !oke { + // at least one of ingress and/or egress is not in the allowed network set + if err := r.updateCWNPState(ctx, cwnp, firewallv1.PolicyDeploymentStateIgnored, "ingress/egress does not match allowed networks"); err != nil { + return nil, err + } + continue + } + + validCWNPs = append(validCWNPs, cwnp) + } + + return validCWNPs, nil +} + +func (r *ClusterwideNetworkPolicyReconciler) updateCWNPState(ctx context.Context, cwnp firewallv1.ClusterwideNetworkPolicy, state firewallv1.PolicyDeploymentState, msg string) error { + // do nothing if message and state already have the desired values + if cwnp.Status.Message == msg && cwnp.Status.State == state { + return nil + } + + cwnp.Status.Message = msg + cwnp.Status.State = state + + if err := r.ShootClient.Status().Update(ctx, &cwnp); err != nil { + return fmt.Errorf("failed to update status of CWNP %q to %q: %w", cwnp.Name, state, err) + } + return nil +} + +func (r *ClusterwideNetworkPolicyReconciler) validateCWNPEgressTargetPrefix(cwnp firewallv1.ClusterwideNetworkPolicy, ipSet *netipx.IPSet) (bool, error) { + for _, egress := range cwnp.Spec.Egress { + for _, to := range egress.To { + if ok, err := helper.ValidateCIDR(&cwnp, to.CIDR, ipSet, r.Recorder); !ok { + return false, err + } + } + } + return true, nil +} + +func (r *ClusterwideNetworkPolicyReconciler) validateCWNPIngressTargetPrefix(cwnp firewallv1.ClusterwideNetworkPolicy, ipSet *netipx.IPSet) (bool, error) { + for _, ingress := range cwnp.Spec.Ingress { + for _, from := range ingress.From { + if ok, err := helper.ValidateCIDR(&cwnp, from.CIDR, ipSet, r.Recorder); !ok { + return false, err + } + } + } + return true, nil +} diff --git a/controllers/clusterwidenetworkpolicy_validation_controller.go b/controllers/clusterwidenetworkpolicy_validation_controller.go index 1d69ac61..1fb7cd2a 100644 --- a/controllers/clusterwidenetworkpolicy_validation_controller.go +++ b/controllers/clusterwidenetworkpolicy_validation_controller.go @@ -11,7 +11,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) // ClusterwideNetworkPolicyValidationReconciler validates a ClusterwideNetworkPolicy object diff --git a/controllers/droptailer_controller.go b/controllers/droptailer_controller.go index 023ca4d7..400140c6 100644 --- a/controllers/droptailer_controller.go +++ b/controllers/droptailer_controller.go @@ -15,12 +15,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" "github.com/go-logr/logr" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" - "github.com/metal-stack/gardener-extension-provider-metal/pkg/secret" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" "github.com/txn2/txeh" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -141,11 +141,17 @@ func (r *DroptailerReconciler) Reconcile(ctx context.Context, req ctrl.Request) return ctrl.Result{}, nil } - secret, err := getLatestSecret(ctx, r.ShootClient, firewallv1.ClusterwideNetworkPolicyNamespace, secretName) - if err != nil { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: firewallv1.ClusterwideNetworkPolicyNamespace, + }, + } + if err := r.ShootClient.Get(ctx, client.ObjectKeyFromObject(secret), secret); err != nil { return ctrl.Result{}, err } - err = r.writeSecret(secret) + + err := r.writeSecret(secret) if err != nil { return ctrl.Result{}, err } @@ -222,15 +228,3 @@ func (r *DroptailerReconciler) writeSecret(secret *corev1.Secret) error { } return nil } - -func getLatestSecret(ctx context.Context, c client.Client, namespace string, name string) (*corev1.Secret, error) { - secretList := &corev1.SecretList{} - if err := c.List(ctx, secretList, client.InNamespace(namespace), client.MatchingLabels{ - "name": name, - "managed-by": "secrets-manager", - }); err != nil { - return nil, err - } - - return secret.GetLatestIssuedSecret(secretList.Items) -} diff --git a/controllers/firewall_controller.go b/controllers/firewall_controller.go index 6d46effa..deaf365d 100644 --- a/controllers/firewall_controller.go +++ b/controllers/firewall_controller.go @@ -25,10 +25,10 @@ import ( firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" "github.com/metal-stack/firewall-controller-manager/api/v2/helper" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" - "github.com/metal-stack/firewall-controller/pkg/network" - "github.com/metal-stack/firewall-controller/pkg/nftables" - "github.com/metal-stack/firewall-controller/pkg/updater" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" + "github.com/metal-stack/firewall-controller/v2/pkg/network" + "github.com/metal-stack/firewall-controller/v2/pkg/nftables" + "github.com/metal-stack/firewall-controller/v2/pkg/updater" ) // FirewallReconciler reconciles a Firewall object @@ -47,6 +47,8 @@ type FirewallReconciler struct { Namespace string recordFirewallEvent func(f *firewallv2.Firewall, eventtype, reason, message string) + + SeedUpdatedFunc func() } const ( @@ -84,7 +86,8 @@ func (r *FirewallReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c if apierrors.IsNotFound(err) { r.Log.Info("flushing k8s firewall rules") - defaultFw := nftables.NewDefaultFirewall() + defaultFw := nftables.NewFirewall(&firewallv2.Firewall{}, &firewallv1.ClusterwideNetworkPolicyList{}, &corev1.ServiceList{}, nil, logr.Discard(), r.Recorder) + flushErr := defaultFw.Flush() if flushErr != nil { r.Log.Error(flushErr, "error flushing k8s firewall rules") @@ -139,9 +142,13 @@ func (r *FirewallReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c r.recordFirewallEvent(f, corev1.EventTypeNormal, "Reconciled", "nftables rules and statistics successfully") - r.Log.Info("successfully reconciled firewall") + r.SeedUpdatedFunc() + + r.Log.Info("successfully reconciled firewall, requeueing in 3 minutes") - return ctrl.Result{}, nil + return ctrl.Result{ + RequeueAfter: 3 * time.Minute, + }, nil } type firewallService struct { diff --git a/controllers/firewall_controller_test.go b/controllers/firewall_controller_test.go index 772ff91d..15fc7367 100644 --- a/controllers/firewall_controller_test.go +++ b/controllers/firewall_controller_test.go @@ -6,7 +6,7 @@ import ( "reflect" "testing" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" corev1 "k8s.io/api/core/v1" networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/controllers/firewall_monitor_controller.go b/controllers/firewall_monitor_controller.go index d823ef7e..e2546afa 100644 --- a/controllers/firewall_monitor_controller.go +++ b/controllers/firewall_monitor_controller.go @@ -7,13 +7,14 @@ import ( "github.com/go-logr/logr" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" - "github.com/metal-stack/firewall-controller/pkg/collector" - "github.com/metal-stack/firewall-controller/pkg/suricata" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" + "github.com/metal-stack/firewall-controller/v2/pkg/collector" + "github.com/metal-stack/firewall-controller/v2/pkg/suricata" "github.com/metal-stack/v" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/record" + "k8s.io/client-go/util/retry" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" @@ -32,6 +33,12 @@ type FirewallMonitorReconciler struct { IDSEnabled bool Interval time.Duration + + seedUpdated metav1.Time +} + +func (r *FirewallMonitorReconciler) SeedUpdated() { + r.seedUpdated = metav1.NewTime(time.Now()) } // SetupWithManager configures this controller to watch for the CRDs in a specific namespace @@ -55,41 +62,13 @@ func (r *FirewallMonitorReconciler) SetupWithManager(mgr ctrl.Manager) error { // Reconcile updates the firewall monitor. func (r *FirewallMonitorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - mon := &firewallv2.FirewallMonitor{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.FirewallName, - Namespace: firewallv1.ClusterwideNetworkPolicyNamespace, - }, - } - - if err := r.ShootClient.Get(ctx, client.ObjectKeyFromObject(mon), mon); err != nil { - if apierrors.IsNotFound(err) { - r.Log.Info("resource no longer exists") - return ctrl.Result{}, nil - } - - return ctrl.Result{}, fmt.Errorf("error retrieving resource: %w", err) - } - - if !mon.GetDeletionTimestamp().IsZero() { - return ctrl.Result{}, nil - } - c := collector.NewNFTablesCollector(&r.Log) ruleStats := c.CollectRuleStats() - if mon.ControllerStatus == nil { - mon.ControllerStatus = &firewallv2.ControllerStatus{} - } - - mon.ControllerStatus.FirewallStats = &firewallv2.FirewallStats{ - RuleStats: ruleStats, - } deviceStats, err := c.CollectDeviceStats() if err != nil { return ctrl.Result{}, err } - mon.ControllerStatus.FirewallStats.DeviceStats = deviceStats idsStats := firewallv2.IDSStatsByDevice{} if r.IDSEnabled { @@ -106,17 +85,61 @@ func (r *FirewallMonitorReconciler) Reconcile(ctx context.Context, req ctrl.Requ } } } - mon.ControllerStatus.FirewallStats.IDSStats = idsStats - mon.ControllerStatus.ControllerVersion = v.Version - mon.ControllerStatus.Updated.Time = time.Now() + err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + mon := &firewallv2.FirewallMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.FirewallName, + Namespace: firewallv1.ClusterwideNetworkPolicyNamespace, + }, + } + + if err := r.ShootClient.Get(ctx, client.ObjectKeyFromObject(mon), mon); err != nil { + if apierrors.IsNotFound(err) { + r.Log.Info("resource no longer exists") + return nil + } + + return fmt.Errorf("error retrieving resource: %w", err) + } + + if !mon.GetDeletionTimestamp().IsZero() { + return nil + } + + now := time.Now() + + mon.ControllerStatus = &firewallv2.ControllerStatus{ + Message: fmt.Sprintf("updated firewall monitor resource at %s", now.String()), + FirewallStats: &firewallv2.FirewallStats{ + RuleStats: ruleStats, + DeviceStats: deviceStats, + IDSStats: idsStats, + }, + ControllerVersion: v.Version, + NftablesExporterVersion: "", // TODO + Updated: metav1.NewTime(now), + Distance: 0, + DistanceSupported: false, + } - if err := r.ShootClient.Update(ctx, mon); err != nil { + if !r.seedUpdated.IsZero() { + mon.ControllerStatus.SeedUpdated = r.seedUpdated + } + + err := r.ShootClient.Update(ctx, mon) + if err != nil { + return err + } + + r.Log.Info(fmt.Sprintf("firewall monitor successfully updated, requeuing in %s", r.Interval.String()), "name", mon.Name, "namespace", mon.Namespace) + + return nil + }) + if err != nil { return ctrl.Result{}, fmt.Errorf("unable to update firewall monitor status, err: %w", err) } - r.Log.Info(fmt.Sprintf("firewall monitor successfully updated, requeuing in %s", r.Interval.String()), "name", mon.Name, "namespace", mon.Namespace) - return ctrl.Result{ // TODO: the interval can change over the lifetime of a firewall resource // in case the interval has changed nothing happens at the moment diff --git a/go.mod b/go.mod index 3cf545bd..c9ba840f 100644 --- a/go.mod +++ b/go.mod @@ -1,31 +1,29 @@ -module github.com/metal-stack/firewall-controller +module github.com/metal-stack/firewall-controller/v2 -go 1.20 +go 1.21 require ( github.com/coreos/go-systemd/v22 v22.5.0 - github.com/fatih/color v1.15.0 - github.com/go-logr/logr v1.2.4 - github.com/go-logr/zapr v1.2.3 + github.com/fatih/color v1.16.0 + github.com/go-logr/logr v1.4.1 github.com/golang/mock v1.6.0 - github.com/google/go-cmp v0.5.9 - github.com/google/nftables v0.1.0 + github.com/google/go-cmp v0.6.0 + github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c github.com/ks2211/go-suricata v0.0.0-20200823200910-986ce1470707 - github.com/metal-stack/firewall-controller-manager v0.2.2 - github.com/metal-stack/gardener-extension-provider-metal v0.20.3 - github.com/metal-stack/metal-go v0.22.6 - github.com/metal-stack/metal-lib v0.11.10 - github.com/metal-stack/metal-networker v0.33.0 + github.com/metal-stack/firewall-controller-manager v0.3.2 + github.com/metal-stack/metal-go v0.26.2 + github.com/metal-stack/metal-lib v0.14.3 + github.com/metal-stack/metal-networker v0.41.0 github.com/metal-stack/v v1.0.3 - github.com/miekg/dns v1.1.53 - github.com/txn2/txeh v1.3.0 + github.com/miekg/dns v1.1.58 + github.com/txn2/txeh v1.5.5 github.com/vishvananda/netlink v1.2.1-beta.2 - go.uber.org/zap v1.24.0 + go4.org/netipx v0.0.0-20231129151722-fdeea329fbba k8s.io/api v0.26.3 k8s.io/apiextensions-apiserver v0.26.3 - k8s.io/apimachinery v0.26.3 + k8s.io/apimachinery v0.28.2 k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible - k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 sigs.k8s.io/controller-runtime v0.14.6 ) @@ -34,74 +32,74 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.10.2 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.1 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.4 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/spec v0.20.9 // indirect - github.com/go-openapi/strfmt v0.21.7 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-openapi/validate v0.22.1 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/go-openapi/analysis v0.22.2 // indirect + github.com/go-openapi/errors v0.21.0 // indirect + github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/loads v0.21.5 // indirect + github.com/go-openapi/spec v0.20.14 // indirect + github.com/go-openapi/strfmt v0.22.0 // indirect + github.com/go-openapi/swag v0.22.8 // indirect + github.com/go-openapi/validate v0.22.6 // indirect + github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.6.9 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.5.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/josharian/native v1.0.0 // indirect + github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mdlayher/netlink v1.7.0 // indirect - github.com/mdlayher/socket v0.4.0 // indirect - github.com/metal-stack/metal-hammer v0.11.2 // indirect + github.com/mdlayher/netlink v1.7.2 // indirect + github.com/mdlayher/socket v0.5.0 // indirect + github.com/metal-stack/metal-hammer v0.12.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_golang v1.15.1 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/vishvananda/netns v0.0.4 // indirect - go.mongodb.org/mongo-driver v1.11.7 // indirect - go.uber.org/atomic v1.11.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.11.0 // indirect - golang.org/x/oauth2 v0.9.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.7.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + go.mongodb.org/mongo-driver v1.13.1 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.17.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/component-base v0.26.3 // indirect - k8s.io/klog/v2 v2.90.1 // indirect - k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) -replace k8s.io/client-go => k8s.io/client-go v0.26.3 +replace ( + k8s.io/client-go => k8s.io/client-go v0.26.3 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f +) diff --git a/go.sum b/go.sum index d91e1795..69b28cd3 100644 --- a/go.sum +++ b/go.sum @@ -2,20 +2,15 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= @@ -27,107 +22,61 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= -github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.1 h1:S+9bSbua1z3FgCnV0KKOSSZ3mDthb5NyEPL5gEpCvyk= +github.com/emicklei/go-restful/v3 v3.11.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= -github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= -github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= -github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= -github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= +github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= +github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY= +github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0= +github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8= +github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do= +github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= +github.com/go-openapi/strfmt v0.22.0 h1:Ew9PnEYc246TwrEspvBdDHS4BVKXy/AOVsfqGDgAcaI= +github.com/go-openapi/strfmt v0.22.0/go.mod h1:HzJ9kokGIju3/K6ap8jL+OlGAbjpSv27135Yr9OivU4= +github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw= +github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= +github.com/go-openapi/validate v0.22.6 h1:+NhuwcEYpWdO5Nm4bmvhGLW0rt1Fcc532Mu3wpypXfo= +github.com/go-openapi/validate v0.22.6/go.mod h1:eaddXSqKeTg5XpSmj1dYyFTK/95n/XHwcOY+BMxKMyM= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ= +github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= +github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -137,7 +86,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= @@ -156,6 +104,8 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -163,96 +113,85 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/nftables v0.1.0 h1:T6lS4qudrMufcNIZ8wSRrL+iuwhsKxpN+zFLxhUWOqk= -github.com/google/nftables v0.1.0/go.mod h1:b97ulCCFipUC+kSin+zygkvUVpx0vyIAwxXFdY3PlNc= +github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c h1:06RMfw+TMMHtRuUOroMeatRCCgSMWXCJQeABvHU69YQ= +github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c/go.mod h1:BVIYo3cdnT4qSylnYqcd5YtmXhr51cJPGtnLBe/uLBU= github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk= -github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk= +github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/jszwec/csvutil v1.8.0 h1:G7vS2LGdpZZDH1HmHeNbxOaJ/ZnJlpwGFvOkTkJzzNk= +github.com/jszwec/csvutil v1.8.0/go.mod h1:/E4ONrmGkwmWsk9ae9jpXnv9QT8pLHEPcCirMFhxG9I= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ks2211/go-suricata v0.0.0-20200823200910-986ce1470707 h1:kQ1CJobf2nLiSO9zznMneZ0t87TCcU8sTAG7JWjiRcg= github.com/ks2211/go-suricata v0.0.0-20200823200910-986ce1470707/go.mod h1:9r65g0Y5T/WyFMctCe9YqJocU+uCkNXNm414lfMOflY= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mdlayher/netlink v1.7.0 h1:ZNGI4V7i1fJ94DPYtWhI/R85i/Q7ZxnuhUJQcJMoodI= -github.com/mdlayher/netlink v1.7.0/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ= -github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw= -github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc= -github.com/metal-stack/firewall-controller-manager v0.2.2 h1:PM60rnyIb38EVnm4MEm8y2AGeiqwopf8h707qaTJsso= -github.com/metal-stack/firewall-controller-manager v0.2.2/go.mod h1:f4c+yYBQLuNpS5cyGXBj7c0b5TeR770LaElgPgA6DTw= -github.com/metal-stack/gardener-extension-provider-metal v0.20.3 h1:hhNLjACU2vYbZJFx7XuFXEAZXgXKElq6Bb5FFFUJEiQ= -github.com/metal-stack/gardener-extension-provider-metal v0.20.3/go.mod h1:r0SgbEF3au3pJCMmriA3PNaawUd9h3v8msrMt43rGxI= -github.com/metal-stack/metal-go v0.22.6 h1:nWjk2VH1B1CWGoupYGxxceblWszTjpD08729riaRyUE= -github.com/metal-stack/metal-go v0.22.6/go.mod h1:n0KALbtB6JGAICDmgSU5B/jekEFODuqcluTHEAXMPng= -github.com/metal-stack/metal-hammer v0.11.2 h1:CUzrz+RCKlbhdKKSI5ow8UhgURmcT3Z7Zly113BTm98= -github.com/metal-stack/metal-hammer v0.11.2/go.mod h1:OyrsyH6aZ6p1DWv6k2CFEJGybg4A0oBjH0yQQmSBfcQ= -github.com/metal-stack/metal-lib v0.11.10 h1:8Dgz4aPJHJvv1gSrxWsm3r9TlR3BdPPlt7xl3p5C8tI= -github.com/metal-stack/metal-lib v0.11.10/go.mod h1:f0HJJdwR6KaAyOWPUCvq6jqQDMxu+aNGtON1UU5Chdo= -github.com/metal-stack/metal-networker v0.33.0 h1:DZf79nBS4CAL0QQnTq1jTucbL/Cj1qfj+jfFpmU8+Ws= -github.com/metal-stack/metal-networker v0.33.0/go.mod h1:lVpSIE7E0iYgyTAavjcrLrUYB5IaFrtthhKzKn5fcH4= +github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= +github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= +github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= +github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= +github.com/metal-stack/firewall-controller-manager v0.3.2 h1:SXamSfDzEZgXGLf4EAobVnBDtTq/QauXcggiifA5gHg= +github.com/metal-stack/firewall-controller-manager v0.3.2/go.mod h1:KjLZv/BatucZM9DQtBLN04wBGjvxEJRV1C+xDkCWwIE= +github.com/metal-stack/metal-go v0.26.2 h1:KZRV1wtCsj0dMo4GpW2+XemmAkPZAYFjbGe7QhhcH1k= +github.com/metal-stack/metal-go v0.26.2/go.mod h1:olJ3Az7RBh39Q5WFCJOQBd7cJi0xgGYwMTEIFvkDQQY= +github.com/metal-stack/metal-hammer v0.12.0 h1:t6t73RGmDU1IFkHC7dJxu7xDIZZvwmqmu9/0xZVF/L0= +github.com/metal-stack/metal-hammer v0.12.0/go.mod h1:MeY/EDYqyFUTk24vEQuaUrfRJf20lIisbqXj28+Bxmc= +github.com/metal-stack/metal-lib v0.14.3 h1:oHtOnGsQC/ySLXzj14mfy7/8bwmCPfD5SD6U4yh8BHU= +github.com/metal-stack/metal-lib v0.14.3/go.mod h1:2wKxFXSCpA1Dr+Rq0ddpQCPKPGMWJp4cpIaVTM4lDi0= +github.com/metal-stack/metal-networker v0.41.0 h1:eefp8nzhF6eBDoGjFR8m+chkGUO5QFuyxffsgQT808c= +github.com/metal-stack/metal-networker v0.41.0/go.mod h1:jdHKFIbPBNHnvies0Tb8DlnPfbKV/HuikxPZH3kC6uA= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= +github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -261,25 +200,24 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.28.1 h1:MijcGUbfYuznzK/5R4CPNoUP/9Xvuo20sXfEm6XxoTA= +github.com/onsi/gomega v1.28.1/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= @@ -288,204 +226,178 @@ github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= +github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= +github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/txn2/txeh v1.3.0 h1:vnbv63htVMZCaQgLqVBxKvj2+HHHFUzNW7I183zjg3E= -github.com/txn2/txeh v1.3.0/go.mod h1:O7M6gUTPeMF+vsa4c4Ipx3JDkOYrruB1Wry8QRsMcw8= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/txn2/txeh v1.5.5 h1:UN4e/lCK5HGw/gGAi2GCVrNKg0GTCUWs7gs5riaZlz4= +github.com/txn2/txeh v1.5.5/go.mod h1:qYzGG9kCzeVEI12geK4IlanHWY8X4uy/I3NcW7mk8g4= github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs= github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs= -go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= +go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= +go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= -golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= -gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -510,27 +422,22 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -539,18 +446,18 @@ k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU= k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE= k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE= k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ= -k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k= -k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s= k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ= k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g= k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c h1:EFfsozyzZ/pggw5qNx7ftTVZdp7WZl+3ih89GEjYEK8= -k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY= -k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/main.go b/main.go index 7755c06e..33214ba7 100644 --- a/main.go +++ b/main.go @@ -4,36 +4,30 @@ import ( "context" "flag" "fmt" + "log/slog" "os" "time" "github.com/metal-stack/v" "github.com/go-logr/logr" - "github.com/go-logr/zapr" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" corev1 "k8s.io/api/core/v1" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/yaml" - "k8s.io/client-go/discovery" clientgoscheme "k8s.io/client-go/kubernetes/scheme" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" controllerclient "sigs.k8s.io/controller-runtime/pkg/client" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" "github.com/metal-stack/firewall-controller-manager/api/v2/helper" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" - "github.com/metal-stack/firewall-controller/controllers" - "github.com/metal-stack/firewall-controller/pkg/updater" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" + "github.com/metal-stack/firewall-controller/v2/controllers" + "github.com/metal-stack/firewall-controller/v2/pkg/sysctl" + "github.com/metal-stack/firewall-controller/v2/pkg/updater" // +kubebuilder:scaffold:imports ) @@ -93,104 +87,84 @@ func main() { return } - l, err := newZapLogger(logLevel) - if err != nil { - setupLog.Error(err, "unable to parse log level") - os.Exit(1) - } - ctrl.SetLogger(zapr.NewLogger(l.Desugar())) + jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{}) + l := slog.New(jsonHandler) - l.Infow("using kubeconfig path", "path", kubeconfigPath) + ctrl.SetLogger(logr.FromSlogHandler(jsonHandler)) + + l.Info("using kubeconfig path", "path", kubeconfigPath) var ( ctx = ctrl.SetupSignalHandler() seedConfig = ctrl.GetConfigOrDie() ) + // FIXME validation and controller start should be refactored into own func which returns error + // instead Fatalw or Error and panic here. + var err error if firewallName == "" { firewallName, err = os.Hostname() if err != nil { - l.Fatalw("unable to default firewall name flag to hostname", "error", err) + l.Error("unable to default firewall name flag to hostname", "error", err) + panic(err) } } if kubeconfigPath == "" { - l.Fatalw("kubeconfig path is empty, aborting") + l.Error("kubeconfig path is empty, aborting") + panic(err) } seedClient, err := controllerclient.New(seedConfig, controllerclient.Options{ Scheme: scheme, }) if err != nil { - l.Fatalw("unable to create seed client", "error", err) + l.Error("unable to create seed client", "error", err) + panic(err) } rawKubeconfig, err := os.ReadFile(kubeconfigPath) if err != nil { - l.Fatalw("unable to read kubeconfig", "path", kubeconfigPath, "error", err) + l.Error("unable to read kubeconfig", "path", kubeconfigPath, "error", err) + panic(err) } seedNamespace, err := getSeedNamespace(rawKubeconfig) if err != nil { - l.Fatalw("unable to find seed namespace from kubeconfig", "error", err) - } - - err = isFirewallV2GVKPresent(seedConfig) // only works for shoots, not for seeds because extension-provider deploys crds immediately into seeds - if err != nil { - l.Info(err.Error()) - - err = controllerMigration(ctx, setupLog, seedClient, firewallName, seedNamespace) - if err != nil { - l.Fatalw("unable to migrate firewall-controller", "error", err) - } - - l.Info("controller migrated, restarting controller") - os.Exit(0) - - return + l.Error("unable to find seed namespace from kubeconfig", "error", err) + panic(err) } fw, err := findResponsibleFirewall(ctx, seedClient, firewallName, seedNamespace) if err != nil { - l.Errorw("unable to find firewall resource to be responsible for", "error", err) - - if kubeconfigPath == seedKubeconfigPath { - os.Exit(1) - } - - l.Info("controller is potentially still running with shoot kubeconfig, attempting migration") - - err = controllerMigration(ctx, setupLog, seedClient, firewallName, seedNamespace) - if err != nil { - l.Fatalw("unable to migrate firewall-controller", "error", err) - } - - l.Info("controller migrated, restarting controller") - os.Exit(0) - - return + l.Error("unable to find firewall resource to be responsible for", "error", err) + panic(err) } - l.Infow("found firewall resource to be responsible for", "firewall-name", firewallName, "namespace", seedNamespace) + l.Info("found firewall resource to be responsible for", "firewall-name", firewallName, "namespace", seedNamespace) shootAccessHelper := helper.NewShootAccessHelper(seedClient, fw.Status.ShootAccess) if err != nil { - l.Fatalw("unable to construct shoot access helper", "error", err) + l.Error("unable to construct shoot access helper", "error", err) + panic(err) } accessTokenUpdater, err := helper.NewShootAccessTokenUpdater(shootAccessHelper, "/etc/firewall-controller") if err != nil { - l.Fatalw("unable to create shoot access token updater", "error", err) + l.Error("unable to create shoot access token updater", "error", err) + panic(err) } err = accessTokenUpdater.UpdateContinuously(ctrl.Log.WithName("token-updater"), ctx) if err != nil { - l.Fatalw("unable to start token updater", "error", err) + l.Error("unable to start token updater", "error", err) + panic(err) } shootConfig, err := shootAccessHelper.RESTConfig(ctx) if err != nil { - l.Fatalw("unable to create shoot config", "error", err) + l.Error("unable to create shoot config", "error", err) + panic(err) } seedMgr, err := ctrl.NewManager(seedConfig, ctrl.Options{ @@ -204,7 +178,8 @@ func main() { LeaderElection: false, // leader election does not make sense for this controller, it's always single managed by systemd }) if err != nil { - l.Fatalw("unable to create seed manager", "error", err) + l.Error("unable to create seed manager", "error", err) + panic(err) } shootMgr, err := ctrl.NewManager(shootConfig, ctrl.Options{ @@ -213,29 +188,42 @@ func main() { LeaderElection: false, }) if err != nil { - l.Fatalw("unable to create shoot manager", "error", err) + l.Error("unable to create shoot manager", "error", err) + panic(err) } - shootClient, err := client.New(shootConfig, client.Options{Scheme: scheme}) + shootClient, err := controllerclient.New(shootConfig, controllerclient.Options{Scheme: scheme}) if err != nil { - l.Fatalw("unable to create shoot client", "error", err) + l.Error("unable to create shoot client", "error", err) + panic(err) } updater := updater.New(ctrl.Log.WithName("updater"), shootMgr.GetEventRecorderFor("FirewallController")) + fwmReconciler := &controllers.FirewallMonitorReconciler{ + ShootClient: shootMgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("FirewallMonitorReconciler"), + Recorder: shootMgr.GetEventRecorderFor("FirewallMonitorController"), + IDSEnabled: enableIDS, + FirewallName: firewallName, + Namespace: firewallv2.FirewallShootNamespace, + } + // Firewall Reconciler if err = (&controllers.FirewallReconciler{ - SeedClient: seedMgr.GetClient(), - ShootClient: shootClient, - Log: ctrl.Log.WithName("controllers").WithName("Firewall"), - Scheme: scheme, - Namespace: seedNamespace, - FirewallName: firewallName, - Recorder: shootMgr.GetEventRecorderFor("FirewallController"), - Updater: updater, - TokenUpdater: accessTokenUpdater, + SeedClient: seedMgr.GetClient(), + ShootClient: shootClient, + Log: ctrl.Log.WithName("controllers").WithName("Firewall"), + Scheme: scheme, + Namespace: seedNamespace, + FirewallName: firewallName, + Recorder: shootMgr.GetEventRecorderFor("FirewallController"), + Updater: updater, + SeedUpdatedFunc: fwmReconciler.SeedUpdated, + TokenUpdater: accessTokenUpdater, }).SetupWithManager(seedMgr); err != nil { - l.Fatalw("unable to create firewall controller", "error", err) + l.Error("unable to create firewall controller", "error", err) + panic(err) } // Droptailer Reconciler @@ -244,7 +232,8 @@ func main() { Log: ctrl.Log.WithName("controllers").WithName("Droptailer"), HostsFile: hostsFile, }).SetupWithManager(shootMgr); err != nil { - l.Fatalw("unable to create droptailer controller", "error", err) + l.Error("unable to create droptailer controller", "error", err) + panic(err) } // ClusterwideNetworkPolicy Reconciler @@ -252,10 +241,12 @@ func main() { SeedClient: seedMgr.GetClient(), ShootClient: shootMgr.GetClient(), Log: ctrl.Log.WithName("controllers").WithName("ClusterwideNetworkPolicy"), + Recorder: shootMgr.GetEventRecorderFor("FirewallController"), FirewallName: firewallName, SeedNamespace: seedNamespace, }).SetupWithManager(shootMgr); err != nil { - l.Fatalw("unable to create clusterwidenetworkpolicy controller", "error", err) + l.Error("unable to create clusterwidenetworkpolicy controller", "error", err) + panic(err) } if err = (&controllers.ClusterwideNetworkPolicyValidationReconciler{ @@ -263,18 +254,14 @@ func main() { Log: ctrl.Log.WithName("controllers").WithName("ClusterwideNetworkPolicyValidation"), Recorder: shootMgr.GetEventRecorderFor("FirewallController"), }).SetupWithManager(shootMgr); err != nil { - l.Fatalw("unable to create clusterwidenetworkpolicyvalidation controller", "error", err) + l.Error("unable to create clusterwidenetworkpolicyvalidation controller", "error", err) + panic(err) } - if err = (&controllers.FirewallMonitorReconciler{ - ShootClient: shootMgr.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("FirewallMonitorReconciler"), - Recorder: shootMgr.GetEventRecorderFor("FirewallMonitorController"), - IDSEnabled: enableIDS, - FirewallName: firewallName, - Namespace: firewallv2.FirewallShootNamespace, - }).SetupWithManager(shootMgr); err != nil { - l.Fatalw("unable to create firewall monitor controller", "error", err) + // FirewallMonitorReconciler + if err = (fwmReconciler).SetupWithManager(shootMgr); err != nil { + l.Error("unable to create firewall monitor controller", "error", err) + panic(err) } // +kubebuilder:scaffold:builder @@ -288,66 +275,32 @@ func main() { defer cancel() err = updater.Run(updaterCtx, fw) if err != nil { - l.Fatalw("unable to update firewall components", "error", err) + l.Error("unable to update firewall components", "error", err) + panic(err) } go func() { - l.Infow("starting shoot controller", "version", v.V) + l.Info("starting shoot controller", "version", v.V) if err := shootMgr.Start(ctx); err != nil { - l.Fatalw("problem running shoot controller", "error", err) + l.Error("problem running shoot controller", "error", err) + panic(err) } }() - if err := seedMgr.Start(ctx); err != nil { - l.Errorw("problem running seed controller", "error", err) - panic(err) - } -} - -func newZapLogger(levelString string) (*zap.SugaredLogger, error) { - level, err := zap.ParseAtomicLevel(levelString) - if err != nil { - return nil, fmt.Errorf("unable to parse log level: %w", err) - } - - cfg := zap.NewProductionConfig() - cfg.Level = level - cfg.EncoderConfig.TimeKey = "timestamp" - cfg.EncoderConfig.EncodeTime = zapcore.RFC3339TimeEncoder - - l, err := cfg.Build() + err = sysctl.Tune(l) if err != nil { - return nil, fmt.Errorf("can't initialize zap logger: %w", err) + l.Error("unable to tune kernel", "error", err) } - return l.Sugar(), nil -} - -func isFirewallV2GVKPresent(config *rest.Config) error { - discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(config) - - resources, err := discoveryClient.ServerResourcesForGroupVersion(firewallv2.GroupVersion.String()) - if err != nil { - return err - } - - found := false - for _, r := range resources.APIResources { - if r.Kind == "Firewall" { - found = true - break - } - } - if found { - return nil + if err := seedMgr.Start(ctx); err != nil { + l.Error("problem running seed controller", "error", err) + panic(err) } - - return fmt.Errorf("client cannot find firewall v2 resource on server side, assuming that this firewall was provisioned with shoot client in the past") } -func findResponsibleFirewall(ctx context.Context, seed client.Client, firewallName, seedNamespace string) (*firewallv2.Firewall, error) { +func findResponsibleFirewall(ctx context.Context, seed controllerclient.Client, firewallName, seedNamespace string) (*firewallv2.Firewall, error) { fwList := &firewallv2.FirewallList{} - err := seed.List(ctx, fwList, &client.ListOptions{ + err := seed.List(ctx, fwList, &controllerclient.ListOptions{ Namespace: seedNamespace, }) if err != nil { @@ -384,54 +337,3 @@ func getSeedNamespace(rawKubeconfig []byte) (string, error) { return "", fmt.Errorf("unable to figure out seed namespace from kubeconfig") } - -func controllerMigration(ctx context.Context, log logr.Logger, c client.Client, firewallName, seedNamespace string) error { - // changing from existing shoot kubeconfig from deployments before firewall-controller-manager - // to seed kubeconfig by trying to use an offered migration secret in the shoot's firewall namespace. - - migrationSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: firewallv2.FirewallControllerMigrationSecretName, - Namespace: firewallv2.FirewallShootNamespace, - }, - } - err := c.Get(ctx, client.ObjectKeyFromObject(migrationSecret), migrationSecret) - if err != nil { - return fmt.Errorf("no migration secret found, cannot run with shoot client: %w", err) - } - - log.Info("found migration secret, attempting to exchange kubeconfig from original provisioning process") - - kubeconfig := migrationSecret.Data["kubeconfig"] - - seedConfig, err := clientcmd.RESTConfigFromKubeConfig(kubeconfig) - if err != nil { - return fmt.Errorf("unable to create rest config from migration secret: %w", err) - } - - seed, err := client.New(seedConfig, client.Options{ - Scheme: scheme, - }) - if err != nil { - return fmt.Errorf("unable to create seed client from migration secret: %w", err) - } - - err = isFirewallV2GVKPresent(seedConfig) - if err != nil { - return fmt.Errorf("in client created from migration secret, firewall v2 is still not present: %w", err) - } - - _, err = findResponsibleFirewall(ctx, seed, firewallName, seedNamespace) - if err != nil { - return fmt.Errorf("in client created from migration secret, firewall no responsible firewall was found: %w", err) - } - - log.Info("possible to start up with client from migration secret, exchanging original kubeconfig") - - err = os.WriteFile(seedKubeconfigPath, kubeconfig, 0600) - if err != nil { - return fmt.Errorf("unable to write kubeconfig to destination: %w", err) - } - - return nil // not reachable, but satisfies the compiler -} diff --git a/pkg/dns/dnscache.go b/pkg/dns/dnscache.go index 7a793691..3c5dbfc8 100644 --- a/pkg/dns/dnscache.go +++ b/pkg/dns/dnscache.go @@ -18,7 +18,7 @@ import ( dnsgo "github.com/miekg/dns" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) type IPVersion string diff --git a/pkg/dns/dnscache_test.go b/pkg/dns/dnscache_test.go index a1e77f78..ade37e6c 100644 --- a/pkg/dns/dnscache_test.go +++ b/pkg/dns/dnscache_test.go @@ -5,7 +5,7 @@ import ( "github.com/go-logr/logr" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) func Test_GetSetsForFQDN(t *testing.T) { diff --git a/pkg/dns/dnsproxy.go b/pkg/dns/dnsproxy.go index 096d24bf..d5056de2 100644 --- a/pkg/dns/dnsproxy.go +++ b/pkg/dns/dnsproxy.go @@ -3,16 +3,17 @@ package dns import ( "context" "fmt" - "github.com/metal-stack/metal-networker/pkg/netconf" "net" "strconv" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + "github.com/metal-stack/metal-networker/pkg/netconf" + + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" "github.com/go-logr/logr" dnsgo "github.com/miekg/dns" - "github.com/metal-stack/firewall-controller/pkg/network" + "github.com/metal-stack/firewall-controller/v2/pkg/network" ) const ( diff --git a/pkg/helper/helper.go b/pkg/helper/helper.go new file mode 100644 index 00000000..90e774c6 --- /dev/null +++ b/pkg/helper/helper.go @@ -0,0 +1,70 @@ +package helper + +import ( + "fmt" + "net/netip" + + "go4.org/netipx" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/record" +) + +const ( + forbiddenCIDR = "ForbiddenCIDR" +) + +// Create an IPSet from a given list of strings describing networks. +func BuildNetworksIPSet(networks []string) (*netipx.IPSet, error) { + var externalBuilder netipx.IPSetBuilder + + for _, externalNetwork := range networks { + parsedExternal, err := netip.ParsePrefix(externalNetwork) + if err != nil { + return nil, fmt.Errorf("failed to parse prefix: %w", err) + } + externalBuilder.AddPrefix(parsedExternal) + } + externalSet, err := externalBuilder.IPSet() + if err != nil { + return nil, fmt.Errorf("failed to create ipset: %w", err) + } + return externalSet, nil +} + +func NetworkSetAsString(externalSet *netipx.IPSet) string { + var allowedNetworksStr string + if externalSet != nil { + for i, r := range externalSet.Ranges() { + if i > 0 { + allowedNetworksStr += "," + } + if p, ok := r.Prefix(); ok { + allowedNetworksStr += p.String() + } else { + allowedNetworksStr += r.String() + } + } + } + return allowedNetworksStr +} + +func ValidateCIDR(o runtime.Object, cidr string, ipset *netipx.IPSet, rec record.EventRecorder) (bool, error) { + parsedTo, err := netip.ParsePrefix(cidr) + if err != nil { + return false, fmt.Errorf("failed to parse to address: %w", err) + } + if !ipset.ContainsPrefix(parsedTo) { + allowedNetworksStr := NetworkSetAsString(ipset) + if rec != nil { + rec.Eventf( + o, + corev1.EventTypeWarning, + forbiddenCIDR, + "address:%q is outside of the allowed network range:%q, ignoring", + parsedTo.String(), allowedNetworksStr) + } + return false, nil + } + return true, nil +} diff --git a/pkg/helper/helper_test.go b/pkg/helper/helper_test.go new file mode 100644 index 00000000..f94befa4 --- /dev/null +++ b/pkg/helper/helper_test.go @@ -0,0 +1,232 @@ +package helper + +import ( + "net/netip" + "testing" + + "go4.org/netipx" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func helpMustParseIPSet(ips []string) *netipx.IPSet { + res, _ := BuildNetworksIPSet(ips) + return res +} + +func TestBuildNetworksIPSet(t *testing.T) { + type args struct { + networks []string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "legal values", + args: args{ + networks: []string{ + "192.168.0.0/16", + "1.2.3.4/24", + }, + }, + wantErr: false, + }, + { + name: "overlapping values", + args: args{ + networks: []string{ + "192.168.0.0/16", + "192.168.1.0/8", + }, + }, + wantErr: false, + }, + { + name: "illegal IP", + args: args{ + networks: []string{ + "292.168.0.0/16", + "192.168.1.0/8", + }, + }, + wantErr: true, + }, + { + name: "illegal mask", + args: args{ + networks: []string{ + "192.168.0.0/33", + "192.168.1.0/8", + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := BuildNetworksIPSet(tt.args.networks) + if (err != nil) != tt.wantErr { + t.Errorf("BuildNetworksIPSet() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != nil { + for _, n := range tt.args.networks { + p, _ := netip.ParsePrefix(n) + if !got.ContainsPrefix(p) { + t.Errorf("BuildNetworksIPSet() = does not contain %v", p) + } + } + } + }) + } +} + +func TestNetworkSetAsString(t *testing.T) { + type args struct { + externalSet *netipx.IPSet + } + tests := []struct { + name string + args args + want string + }{ + { + name: "list of overlapping ranges", + args: args{ + externalSet: helpMustParseIPSet([]string{"192.168.0.1/8", "192.168.1.1/16"}), + }, + want: "192.0.0.0/8", + }, + { + name: "list of non overlapping ranges", + args: args{ + externalSet: helpMustParseIPSet([]string{"192.168.1.1/24", "192.168.2.1/24"}), + }, + want: "192.168.1.0-192.168.2.255", + }, + { + name: "list of ranges", + args: args{ + externalSet: helpMustParseIPSet([]string{"192.168.1.1/24", "193.168.2.1/24"}), + }, + want: "192.168.1.0/24,193.168.2.0/24", + }, + { + name: "list of ranges with single IP-cidr", + args: args{ + externalSet: helpMustParseIPSet([]string{"192.168.1.1/24", "193.168.2.1/24", "1.2.3.4/32"}), + }, + want: "1.2.3.4/32,192.168.1.0/24,193.168.2.0/24", + }, + { + name: "empty input", + args: args{ + externalSet: nil, + }, + want: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NetworkSetAsString(tt.args.externalSet); got != tt.want { + t.Errorf("NetworkSetAsString() = %v, want %v", got, tt.want) + } + }) + } +} + +type mockRecorder struct { + evType string + evReason string + tpreason string + ok bool + invoke bool +} + +func (mr *mockRecorder) Event(object runtime.Object, eventtype, reason, message string) { + mr.invoke = true + mr.tpreason = eventtype + "," + reason + mr.ok = eventtype == mr.evType && reason == mr.evReason +} +func (mr *mockRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { + mr.invoke = true + mr.tpreason = eventtype + "," + reason + mr.ok = eventtype == mr.evType && reason == mr.evReason +} +func (mr *mockRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { + mr.invoke = true + mr.tpreason = eventtype + "," + reason + mr.ok = eventtype == mr.evType && reason == mr.evReason +} + +func TestValidateCIDR(t *testing.T) { + type args struct { + o runtime.Object + cidr string + ipset *netipx.IPSet + } + tests := []struct { + name string + args args + want bool + wantRecordEvent bool + wantErr bool + }{ + { + name: "cidr in ipset", + args: args{ + o: nil, + cidr: "192.168.0.6/24", + ipset: helpMustParseIPSet([]string{"192.168.0.0/16"}), + }, + want: true, + wantRecordEvent: false, + wantErr: false, + }, + { + name: "cidr not in ipset", + args: args{ + o: nil, + cidr: "193.168.0.6/24", + ipset: helpMustParseIPSet([]string{"192.168.0.0/16"}), + }, + want: false, + wantRecordEvent: true, + wantErr: false, + }, + { + name: "illegal cidr value", + args: args{ + o: nil, + cidr: "293.168.0.6/24", + ipset: helpMustParseIPSet([]string{"192.168.0.0/16"}), + }, + want: false, + wantRecordEvent: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rec := mockRecorder{evType: corev1.EventTypeWarning, evReason: forbiddenCIDR} + + got, err := ValidateCIDR(tt.args.o, tt.args.cidr, tt.args.ipset, &rec) + if (err != nil) != tt.wantErr { + t.Errorf("ValidateCIDR() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("ValidateCIDR() = %v, want %v", got, tt.want) + } + if tt.wantRecordEvent != rec.invoke { + t.Errorf("ValidateCIDR() log event = %v, wanted log event %v", rec.invoke, tt.wantRecordEvent) + } + if tt.wantRecordEvent && !rec.ok { + t.Errorf("ValidateCIDR() did log wrong type/reason %q", rec.tpreason) + } + + }) + } +} diff --git a/pkg/network/network.go b/pkg/network/network.go index a5bd5306..68691ce4 100644 --- a/pkg/network/network.go +++ b/pkg/network/network.go @@ -2,11 +2,10 @@ package network import ( "fmt" + "log/slog" "os" "path/filepath" - "go.uber.org/zap" - firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" "github.com/metal-stack/metal-go/api/models" "github.com/metal-stack/metal-networker/pkg/netconf" @@ -17,18 +16,16 @@ const ( frrConfig = "/etc/frr/frr.conf" ) -var logger *zap.SugaredLogger +var logger *slog.Logger func init() { - l, err := zap.NewProduction() - if err != nil { - panic(err) - } + jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{}) + l := slog.New(jsonHandler) - logger = l.Sugar() + logger = l.WithGroup("networker") } -func GetLogger() *zap.SugaredLogger { +func GetLogger() *slog.Logger { return logger } diff --git a/pkg/nftables/firewall.go b/pkg/nftables/firewall.go index 28066b0d..19e4ac83 100644 --- a/pkg/nftables/firewall.go +++ b/pkg/nftables/firewall.go @@ -8,20 +8,21 @@ import ( "os/exec" "path/filepath" - "github.com/metal-stack/firewall-controller/pkg/dns" + "github.com/metal-stack/firewall-controller/v2/pkg/dns" - "github.com/metal-stack/firewall-controller/pkg/network" + "github.com/metal-stack/firewall-controller/v2/pkg/network" "github.com/go-logr/logr" "github.com/vishvananda/netlink" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/tools/record" mn "github.com/metal-stack/metal-lib/pkg/net" "github.com/metal-stack/metal-networker/pkg/netconf" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) const ( @@ -45,6 +46,8 @@ type FQDNCache interface { type Firewall struct { log logr.Logger + recorder record.EventRecorder + firewall *firewallv2.Firewall clusterwideNetworkPolicies *firewallv1.ClusterwideNetworkPolicyList services *corev1.ServiceList @@ -67,11 +70,6 @@ type forwardingRules struct { Egress nftablesRules } -// NewDefaultFirewall creates a new default nftables firewall. -func NewDefaultFirewall() *Firewall { - return NewFirewall(&firewallv2.Firewall{}, &firewallv1.ClusterwideNetworkPolicyList{}, &corev1.ServiceList{}, nil, logr.Discard()) -} - // NewFirewall creates a new nftables firewall object based on k8s entities func NewFirewall( firewall *firewallv2.Firewall, @@ -79,6 +77,7 @@ func NewFirewall( svcs *corev1.ServiceList, cache FQDNCache, log logr.Logger, + recorder record.EventRecorder, ) *Firewall { networkMap := networkMap{} var primaryPrivateNet *firewallv2.FirewallNetwork @@ -103,6 +102,7 @@ func NewFirewall( cache: cache, enableDNS: len(cwnps.GetFQDNs()) > 0, log: log, + recorder: recorder, } } @@ -181,7 +181,7 @@ func (f *Firewall) ReconcileNetconfTables() error { if err != nil { return fmt.Errorf("failed to init networker configurator: %w", err) } - configurator.ConfigureNftables() + configurator.ConfigureNftables(netconf.ForwardPolicyAccept) return nil } diff --git a/pkg/nftables/mocks/mock_fqdncache.go b/pkg/nftables/mocks/mock_fqdncache.go index e7812461..568cf1fc 100644 --- a/pkg/nftables/mocks/mock_fqdncache.go +++ b/pkg/nftables/mocks/mock_fqdncache.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/metal-stack/firewall-controller/pkg/nftables (interfaces: FQDNCache) +// Source: github.com/metal-stack/firewall-controller/v2/pkg/nftables (interfaces: FQDNCache) // Package mocks is a generated GoMock package. package mocks @@ -8,8 +8,8 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - v1 "github.com/metal-stack/firewall-controller/api/v1" - dns "github.com/metal-stack/firewall-controller/pkg/dns" + v1 "github.com/metal-stack/firewall-controller/v2/api/v1" + dns "github.com/metal-stack/firewall-controller/v2/pkg/dns" ) // MockFQDNCache is a mock of FQDNCache interface. diff --git a/pkg/nftables/networkpolicy.go b/pkg/nftables/networkpolicy.go index 1567867c..f6dfc3df 100644 --- a/pkg/nftables/networkpolicy.go +++ b/pkg/nftables/networkpolicy.go @@ -6,7 +6,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) type ruleBase struct { @@ -82,7 +82,7 @@ func clusterwideNetworkPolicyEgressRules( ruleBases = append(ruleBases, ruleBase{base: rb}) } else if len(e.ToFQDNs) > 0 && cache.IsInitialized() { // Generate allow rules based on DNS selectors - rbs, u := clusterwideNetworkPolicyEgressToFQDNRules(cache, np.Status.FQDNState, e) + rbs, u := clusterwideNetworkPolicyEgressToFQDNRules(cache, e) np.Status.FQDNState = u ruleBases = append(ruleBases, rbs...) } @@ -112,12 +112,9 @@ func clusterwideNetworkPolicyEgressToRules(e firewallv1.EgressRule) (allow, exce func clusterwideNetworkPolicyEgressToFQDNRules( cache FQDNCache, - fqdnState firewallv1.FQDNState, e firewallv1.EgressRule, ) (rules []ruleBase, updatedState firewallv1.FQDNState) { - if fqdnState == nil { - fqdnState = firewallv1.FQDNState{} - } + fqdnState := firewallv1.FQDNState{} for _, fqdn := range e.ToFQDNs { fqdnName := fqdn.MatchName diff --git a/pkg/nftables/networkpolicy_test.go b/pkg/nftables/networkpolicy_test.go index 4f9dd851..e4815671 100644 --- a/pkg/nftables/networkpolicy_test.go +++ b/pkg/nftables/networkpolicy_test.go @@ -10,8 +10,8 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/pointer" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" - "github.com/metal-stack/firewall-controller/pkg/nftables/mocks" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" + "github.com/metal-stack/firewall-controller/v2/pkg/nftables/mocks" ) func port(p int) *intstr.IntOrString { diff --git a/pkg/nftables/ratelimit_test.go b/pkg/nftables/ratelimit_test.go index 66c64b7d..c7125cbc 100644 --- a/pkg/nftables/ratelimit_test.go +++ b/pkg/nftables/ratelimit_test.go @@ -8,7 +8,7 @@ import ( mn "github.com/metal-stack/metal-lib/pkg/net" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) func TestRateLimitRules(t *testing.T) { @@ -81,7 +81,7 @@ func TestRateLimitRules(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - f := NewFirewall(&firewallv2.Firewall{Spec: tt.input.Spec, Status: tt.input.Status}, &firewallv1.ClusterwideNetworkPolicyList{}, nil, nil, logr.Discard()) + f := NewFirewall(&firewallv2.Firewall{Spec: tt.input.Spec, Status: tt.input.Status}, &firewallv1.ClusterwideNetworkPolicyList{}, nil, nil, logr.Discard(), nil) got := rateLimitRules(f) if !cmp.Equal(got, tt.want) { t.Errorf("rateLimitRules() diff: %v", cmp.Diff(got, tt.want)) diff --git a/pkg/nftables/rendering.go b/pkg/nftables/rendering.go index 7c824221..c169508b 100644 --- a/pkg/nftables/rendering.go +++ b/pkg/nftables/rendering.go @@ -8,7 +8,9 @@ import ( "strings" "text/template" - "github.com/metal-stack/firewall-controller/pkg/dns" + "github.com/metal-stack/firewall-controller/v2/pkg/dns" + "github.com/metal-stack/firewall-controller/v2/pkg/helper" + "go4.org/netipx" ) // firewallRenderingData holds the data available in the nftables template @@ -36,8 +38,18 @@ func newFirewallRenderingData(f *Firewall) (*firewallRenderingData, error) { f.clusterwideNetworkPolicies.Items[ind] = u } + var serviceAllowedSet *netipx.IPSet + if len(f.firewall.Spec.AllowedNetworks.Ingress) > 0 { + // the ips for services are only checked if the accesstype is forbidden + a, err := helper.BuildNetworksIPSet(f.firewall.Spec.AllowedNetworks.Ingress) + if err != nil { + return nil, err + } + serviceAllowedSet = a + } + for _, svc := range f.services.Items { - ingress = append(ingress, serviceRules(svc, f.logAcceptedConnections)...) + ingress = append(ingress, serviceRules(svc, serviceAllowedSet, f.logAcceptedConnections, f.recorder)...) } snatRules, err := snatRules(f) diff --git a/pkg/nftables/rendering_test.go b/pkg/nftables/rendering_test.go index 7c8f757c..b12107bc 100644 --- a/pkg/nftables/rendering_test.go +++ b/pkg/nftables/rendering_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" - "github.com/metal-stack/firewall-controller/pkg/dns" + "github.com/metal-stack/firewall-controller/v2/pkg/dns" ) func TestFirewallRenderingData_renderString(t *testing.T) { diff --git a/pkg/nftables/service.go b/pkg/nftables/service.go index 9ce978a9..c4c6dfb5 100644 --- a/pkg/nftables/service.go +++ b/pkg/nftables/service.go @@ -2,47 +2,28 @@ package nftables import ( "fmt" - "net" + "net/netip" "strings" + "github.com/metal-stack/firewall-controller/v2/pkg/helper" + "go4.org/netipx" corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/tools/record" ) -func isCIDR(cidr string) bool { - _, _, err := net.ParseCIDR(cidr) - return err != nil -} - -func isIP(ip string) bool { - i := net.ParseIP(ip) - return i != nil -} - // serviceRules generates nftables rules base on a k8s service definition -func serviceRules(svc corev1.Service, logAcceptedConnections bool) nftablesRules { +func serviceRules(svc corev1.Service, allowed *netipx.IPSet, logAcceptedConnections bool, recorder record.EventRecorder) nftablesRules { if svc.Spec.Type != corev1.ServiceTypeLoadBalancer && svc.Spec.Type != corev1.ServiceTypeNodePort { return nil } from := []string{} - for _, lbsr := range svc.Spec.LoadBalancerSourceRanges { - if !isCIDR(lbsr) && !isIP(lbsr) { - continue - } - } - from = append(from, svc.Spec.LoadBalancerSourceRanges...) to := []string{} if svc.Spec.Type == corev1.ServiceTypeLoadBalancer { - if svc.Spec.LoadBalancerIP != "" { - if isIP(svc.Spec.LoadBalancerIP) { - to = append(to, svc.Spec.LoadBalancerIP) - } - } + to = appendServiceIP(to, svc, allowed, svc.Spec.LoadBalancerIP, recorder) for _, e := range svc.Status.LoadBalancer.Ingress { - if isIP(e.IP) { - to = append(to, e.IP) - } + to = appendServiceIP(to, svc, allowed, e.IP, recorder) } } @@ -63,6 +44,7 @@ func serviceRules(svc corev1.Service, logAcceptedConnections bool) nftablesRules tcpPorts := []string{} udpPorts := []string{} for _, p := range svc.Spec.Ports { + p := p proto := proto(&p.Protocol) if proto == "tcp" { tcpPorts = append(tcpPorts, fmt.Sprint(p.Port)) @@ -80,3 +62,19 @@ func serviceRules(svc corev1.Service, logAcceptedConnections bool) nftablesRules } return uniqueSorted(rules) } + +func appendServiceIP(to []string, svc corev1.Service, allowed *netipx.IPSet, ip string, recorder record.EventRecorder) []string { + _, err := netip.ParseAddr(ip) + if err != nil { + return to + } + if allowed == nil { + return append(to, ip) + } + + // if there is an allowed-ipset restriction, we check if the given IP is contained in this set + if ok, _ := helper.ValidateCIDR(&svc, ip+"/32", allowed, recorder); ok { + to = append(to, ip) + } + return to +} diff --git a/pkg/nftables/service_test.go b/pkg/nftables/service_test.go index 589df273..9dcae4e5 100644 --- a/pkg/nftables/service_test.go +++ b/pkg/nftables/service_test.go @@ -4,10 +4,17 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/metal-stack/firewall-controller/v2/pkg/helper" + "go4.org/netipx" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func helpMustParseIPSet(ips []string) *netipx.IPSet { + res, _ := helper.BuildNetworksIPSet(ips) + return res +} + func TestServiceRules(t *testing.T) { type want struct { ingress nftablesRules @@ -15,9 +22,10 @@ func TestServiceRules(t *testing.T) { } tests := []struct { - name string - input corev1.Service - want want + name string + input corev1.Service + allowed *netipx.IPSet + want want }{ { name: "standard service type loadbalancer with restricted source IP range", @@ -89,15 +97,132 @@ func TestServiceRules(t *testing.T) { }, want: want{nil, nil}, }, + { + name: "standard service type loadbalancer with a non matching allowed IP set", + allowed: helpMustParseIPSet([]string{"182.0.0.0/8"}), + input: corev1.Service{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "test", + Name: "svc", + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{ + { + Port: 443, + TargetPort: *port(30443), + Protocol: corev1.ProtocolTCP, + }, + }, + LoadBalancerSourceRanges: []string{"185.0.0.0/16", "185.1.0.0/16"}, + }, + Status: corev1.ServiceStatus{ + LoadBalancer: corev1.LoadBalancerStatus{ + Ingress: []corev1.LoadBalancerIngress{ + { + IP: "185.0.0.1", + }, + }, + }, + }, + }, + want: want{ + ingress: nftablesRules{ + `ip saddr { 185.0.0.0/16, 185.1.0.0/16 } tcp dport { 443 } counter accept comment "accept traffic for k8s service test/svc"`, + }, + ingressAL: nftablesRules{ + `ip saddr { 185.0.0.0/16, 185.1.0.0/16 } tcp dport { 443 } log prefix "nftables-firewall-accepted: " limit rate 10/second`, + `ip saddr { 185.0.0.0/16, 185.1.0.0/16 } tcp dport { 443 } counter accept comment "accept traffic for k8s service test/svc"`, + }, + }, + }, + { + name: "standard service type loadbalancer with restricted source IP range, allow loadbalancer and status-ingress IP", + allowed: helpMustParseIPSet([]string{"185.0.1.0/30"}), + input: corev1.Service{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "test", + Name: "svc", + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{ + { + Port: 443, + TargetPort: *port(30443), + Protocol: corev1.ProtocolTCP, + }, + }, + LoadBalancerIP: "185.0.1.2", + }, + Status: corev1.ServiceStatus{ + LoadBalancer: corev1.LoadBalancerStatus{ + Ingress: []corev1.LoadBalancerIngress{ + { + IP: "185.0.1.1", + }, + }, + }, + }, + }, + want: want{ + ingress: nftablesRules{ + `ip daddr { 185.0.1.2, 185.0.1.1 } tcp dport { 443 } counter accept comment "accept traffic for k8s service test/svc"`, + }, + ingressAL: nftablesRules{ + `ip daddr { 185.0.1.2, 185.0.1.1 } tcp dport { 443 } log prefix "nftables-firewall-accepted: " limit rate 10/second`, + `ip daddr { 185.0.1.2, 185.0.1.1 } tcp dport { 443 } counter accept comment "accept traffic for k8s service test/svc"`, + }, + }, + }, + { + name: "standard service type loadbalancer with restricted source IP range, filter out loadbalancer-IP", + allowed: helpMustParseIPSet([]string{"185.0.1.0/31"}), + input: corev1.Service{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "test", + Name: "svc", + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{ + { + Port: 443, + TargetPort: *port(30443), + Protocol: corev1.ProtocolTCP, + }, + }, + LoadBalancerIP: "185.0.1.2", + }, + Status: corev1.ServiceStatus{ + LoadBalancer: corev1.LoadBalancerStatus{ + Ingress: []corev1.LoadBalancerIngress{ + { + IP: "185.0.1.1", + }, + }, + }, + }, + }, + want: want{ + ingress: nftablesRules{ + `ip daddr { 185.0.1.1 } tcp dport { 443 } counter accept comment "accept traffic for k8s service test/svc"`, + }, + ingressAL: nftablesRules{ + `ip daddr { 185.0.1.1 } tcp dport { 443 } log prefix "nftables-firewall-accepted: " limit rate 10/second`, + `ip daddr { 185.0.1.1 } tcp dport { 443 } counter accept comment "accept traffic for k8s service test/svc"`, + }, + }, + }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - ingress := serviceRules(tt.input, false) + ingress := serviceRules(tt.input, tt.allowed, false, nil) if !cmp.Equal(ingress, tt.want.ingress) { t.Errorf("serviceRules() diff: %v", cmp.Diff(ingress, tt.want.ingress)) } - ingressAL := serviceRules(tt.input, true) + ingressAL := serviceRules(tt.input, tt.allowed, true, nil) if !cmp.Equal(ingressAL, tt.want.ingressAL) { t.Errorf("serviceRules() diff: %v", cmp.Diff(ingressAL, tt.want.ingressAL)) } diff --git a/pkg/nftables/snat_test.go b/pkg/nftables/snat_test.go index f331e012..3f1a0eed 100644 --- a/pkg/nftables/snat_test.go +++ b/pkg/nftables/snat_test.go @@ -11,7 +11,7 @@ import ( networking "k8s.io/api/networking/v1" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" ) func TestSnatRules(t *testing.T) { @@ -198,7 +198,7 @@ func TestSnatRules(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - f := NewFirewall(&firewallv2.Firewall{Spec: tt.input.Spec, Status: tt.input.Status}, &tt.cwnps, nil, nil, logr.Discard()) + f := NewFirewall(&firewallv2.Firewall{Spec: tt.input.Spec, Status: tt.input.Status}, &tt.cwnps, nil, nil, logr.Discard(), nil) got, err := snatRules(f) if (err != nil) != tt.wantErr { t.Errorf("snatRules() error = %v, wantErr %v", err, tt.err) diff --git a/pkg/sysctl/sysctl.go b/pkg/sysctl/sysctl.go new file mode 100644 index 00000000..432ba323 --- /dev/null +++ b/pkg/sysctl/sysctl.go @@ -0,0 +1,94 @@ +package sysctl + +import ( + "fmt" + "log/slog" + "os" + "path" + "strconv" + "strings" +) + +const ( + // sysctlBase is the root directory for sysctl values in the proc filesystem + sysctlBase = "/proc/sys" + // nfConntrackMax defines how many connection track entries can be active at the same time + nfConntrackMax = Sysctl("/net/netfilter/nf_conntrack_max") + // nfConntrackMaxSetting defines the maximum settable + nfConntrackMaxSetting = 4194304 + + // moduleBase is the root directory for module specific settings + moduleBase = "/sys/module" + // nfConntrackHashSize defines the hashsize of the conntrack module + nfConntrackHashSize = Module("/nf_conntrack/parameters/hashsize") + // nfConntrackHashSizeSetting defines the maximum settable + nfConntrackHashSizeSetting = 4194304 +) + +type ( + Sysctl string + Module string +) + +func Tune(log *slog.Logger) error { + log.Info("set sysctl value", "key", nfConntrackMax, "value", nfConntrackMaxSetting) + err := Set(nfConntrackMax, nfConntrackMaxSetting) + if err != nil { + return fmt.Errorf("unable to set value of %q %w", nfConntrackMax, err) + } + + conntrackMax, err := Get(nfConntrackMax) + if err != nil { + return fmt.Errorf("unable to get value of %q %w", nfConntrackMax, err) + } + + log.Info("set module value", "key", nfConntrackHashSize, "value", nfConntrackHashSizeSetting) + err = SetModule(nfConntrackHashSize, nfConntrackHashSizeSetting) + if err != nil { + return fmt.Errorf("unable to set module parameter %w", err) + } + + hashSize, err := GetModule(nfConntrackHashSize) + if err != nil { + return fmt.Errorf("unable to get value of %q %w", nfConntrackMax, err) + } + + log.Info("sysctl and module parameters set", "conntrack max", conntrackMax, "hash size", hashSize) + return nil +} + +// Get returns the value for the specified sysctl setting +func Get(sysctl Sysctl) (int, error) { + data, err := os.ReadFile(path.Join(sysctlBase, string(sysctl))) + if err != nil { + return -1, err + } + val, err := strconv.Atoi(strings.Trim(string(data), " \n")) + if err != nil { + return -1, err + } + return val, nil +} + +// Set modifies the specified sysctl flag to the new value +func Set(sysctl Sysctl, newVal int) error { + return os.WriteFile(path.Join(sysctlBase, string(sysctl)), []byte(strconv.Itoa(newVal)), 0600) +} + +// GetModule returns the value for the specified Module setting +func GetModule(module Module) (int, error) { + data, err := os.ReadFile(path.Join(moduleBase, string(module))) + if err != nil { + return -1, err + } + val, err := strconv.Atoi(strings.Trim(string(data), " \n")) + if err != nil { + return -1, err + } + return val, nil +} + +// SetModule modifies the specified module flag to the new value +func SetModule(module Module, newVal int) error { + return os.WriteFile(path.Join(moduleBase, string(module)), []byte(strconv.Itoa(newVal)), 0600) +} diff --git a/pkg/updater/updater.go b/pkg/updater/updater.go index de2296b4..18c8da18 100644 --- a/pkg/updater/updater.go +++ b/pkg/updater/updater.go @@ -6,7 +6,7 @@ import ( "github.com/go-logr/logr" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/record" )