diff --git a/charts/consul/templates/connect-inject-clusterrole.yaml b/charts/consul/templates/connect-inject-clusterrole.yaml index 1dc6d2c34a..34c87f88c6 100644 --- a/charts/consul/templates/connect-inject-clusterrole.yaml +++ b/charts/consul/templates/connect-inject-clusterrole.yaml @@ -98,6 +98,7 @@ rules: resources: - gatewayclassconfigs - gatewayclasses + - meshconfigurations - grpcroutes - httproutes - meshgateways @@ -116,6 +117,7 @@ rules: resources: - gatewayclassconfigs/status - gatewayclasses/status + - meshconfigurations/status - grpcroutes/status - httproutes/status - meshgateways/status diff --git a/control-plane/api/common/common.go b/control-plane/api/common/common.go index 75343ae5f9..d810c06dcc 100644 --- a/control-plane/api/common/common.go +++ b/control-plane/api/common/common.go @@ -5,8 +5,9 @@ package common import ( - mapset "github.com/deckarep/golang-set" "time" + + mapset "github.com/deckarep/golang-set" ) const ( @@ -35,6 +36,7 @@ const ( MeshGateway string = "meshgateway" GatewayClass string = "gatewayclass" GatewayClassConfig string = "gatewayclassconfig" + MeshConfiguration string = "meshconfiguration" Global string = "global" Mesh string = "mesh" diff --git a/control-plane/api/mesh/v2beta1/mesh_configuration_types.go b/control-plane/api/mesh/v2beta1/mesh_configuration_types.go index 7ffba4f6d8..4bfa41b2bf 100644 --- a/control-plane/api/mesh/v2beta1/mesh_configuration_types.go +++ b/control-plane/api/mesh/v2beta1/mesh_configuration_types.go @@ -50,13 +50,13 @@ type MeshConfigurationList struct { Items []*MeshConfiguration `json:"items"` } -func (in *MeshConfiguration) ResourceID(namespace, partition string) *pbresource.ID { +func (in *MeshConfiguration) ResourceID(_, partition string) *pbresource.ID { return &pbresource.ID{ Name: in.Name, Type: pbmesh.MeshConfigurationType, Tenancy: &pbresource.Tenancy{ + // we don't pass a namespace here because MeshConfiguration is partition-scoped Partition: partition, - Namespace: namespace, // Because we are explicitly defining NS/partition, this will not default and must be explicit. // At a future point, this will move out of the Tenancy block. @@ -65,9 +65,9 @@ func (in *MeshConfiguration) ResourceID(namespace, partition string) *pbresource } } -func (in *MeshConfiguration) Resource(namespace, partition string) *pbresource.Resource { +func (in *MeshConfiguration) Resource(_, partition string) *pbresource.Resource { return &pbresource.Resource{ - Id: in.ResourceID(namespace, partition), + Id: in.ResourceID("", partition), Data: inject.ToProtoAny(&in.Spec), Metadata: meshConfigMeta(), } @@ -91,9 +91,9 @@ func (in *MeshConfiguration) Finalizers() []string { return in.ObjectMeta.Finalizers } -func (in *MeshConfiguration) MatchesConsul(candidate *pbresource.Resource, namespace, partition string) bool { +func (in *MeshConfiguration) MatchesConsul(candidate *pbresource.Resource, _, partition string) bool { return cmp.Equal( - in.Resource(namespace, partition), + in.Resource("", partition), candidate, protocmp.IgnoreFields(&pbresource.Resource{}, "status", "generation", "version"), protocmp.IgnoreFields(&pbresource.ID{}, "uid"), diff --git a/control-plane/config-entries/controllersv2/mesh_configuration_controller.go b/control-plane/config-entries/controllersv2/mesh_configuration_controller.go new file mode 100644 index 0000000000..d485ed3e89 --- /dev/null +++ b/control-plane/config-entries/controllersv2/mesh_configuration_controller.go @@ -0,0 +1,43 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package controllersv2 + +import ( + "context" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" +) + +// MeshConfigurationController reconciles a MeshConfiguration object. +type MeshConfigurationController struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + Controller *ConsulResourceController +} + +// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=meshconfiguration,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=meshconfiguration/status,verbs=get;update;patch + +func (r *MeshConfigurationController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + return r.Controller.ReconcileEntry(ctx, r, req, &meshv2beta1.MeshConfiguration{}) +} + +func (r *MeshConfigurationController) Logger(name types.NamespacedName) logr.Logger { + return r.Log.WithValues("request", name) +} + +func (r *MeshConfigurationController) UpdateStatus(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { + return r.Status().Update(ctx, obj, opts...) +} + +func (r *MeshConfigurationController) SetupWithManager(mgr ctrl.Manager) error { + return setupWithManager(mgr, &meshv2beta1.MeshConfiguration{}, r) +} diff --git a/control-plane/config/rbac/role.yaml b/control-plane/config/rbac/role.yaml index b0904211b6..652dcb8e1c 100644 --- a/control-plane/config/rbac/role.yaml +++ b/control-plane/config/rbac/role.yaml @@ -445,6 +445,26 @@ rules: - get - patch - update +- apiGroups: + - mesh.consul.hashicorp.com + resources: + - meshconfiguration + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - mesh.consul.hashicorp.com + resources: + - meshconfiguration/status + verbs: + - get + - patch + - update - apiGroups: - mesh.consul.hashicorp.com resources: diff --git a/control-plane/subcommand/inject-connect/v2controllers.go b/control-plane/subcommand/inject-connect/v2controllers.go index c9e77c66df..989fdf43e3 100644 --- a/control-plane/subcommand/inject-connect/v2controllers.go +++ b/control-plane/subcommand/inject-connect/v2controllers.go @@ -5,6 +5,7 @@ package connectinject import ( "context" + "github.com/hashicorp/consul-k8s/control-plane/gateways" "github.com/hashicorp/consul-server-connection-manager/discovery" ctrl "sigs.k8s.io/controller-runtime" @@ -132,6 +133,7 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage ConsulServerConnMgr: watcher, ConsulTenancyConfig: consulTenancyConfig, } + if err := (&controllersv2.TrafficPermissionsController{ Controller: consulResourceController, Client: mgr.GetClient(), @@ -141,6 +143,7 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage setupLog.Error(err, "unable to create controller", "controller", common.TrafficPermissions) return err } + if err := (&controllersv2.GRPCRouteController{ Controller: consulResourceController, Client: mgr.GetClient(), @@ -150,6 +153,7 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage setupLog.Error(err, "unable to create controller", "controller", common.GRPCRoute) return err } + if err := (&controllersv2.HTTPRouteController{ Controller: consulResourceController, Client: mgr.GetClient(), @@ -159,6 +163,7 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage setupLog.Error(err, "unable to create controller", "controller", common.HTTPRoute) return err } + if err := (&controllersv2.TCPRouteController{ Controller: consulResourceController, Client: mgr.GetClient(), @@ -168,6 +173,7 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage setupLog.Error(err, "unable to create controller", "controller", common.TCPRoute) return err } + if err := (&controllersv2.ProxyConfigurationController{ Controller: consulResourceController, Client: mgr.GetClient(), @@ -177,6 +183,17 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage setupLog.Error(err, "unable to create controller", "controller", common.ProxyConfiguration) return err } + + if err := (&controllersv2.MeshConfigurationController{ + Controller: consulResourceController, + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controller").WithName(common.MeshConfiguration), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", common.MeshConfiguration) + return err + } + if err := (&controllersv2.MeshGatewayController{ Controller: consulResourceController, Client: mgr.GetClient(), @@ -215,6 +232,7 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage setupLog.Error(err, "unable to create controller", "controller", common.GatewayClassConfig) return err } + if err := (&controllersv2.GatewayClassController{ Controller: consulResourceController, Client: mgr.GetClient(),