diff --git a/Makefile b/Makefile index 45032f5ce..2d1280edf 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ help: ## Display this help. .PHONY: manifests manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases + $(CONTROLLER_GEN) rbac:roleName=api7-ingress-manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. diff --git a/api/v1alpha1/consumer_types.go b/api/v1alpha1/consumer_types.go new file mode 100644 index 000000000..095ff8980 --- /dev/null +++ b/api/v1alpha1/consumer_types.go @@ -0,0 +1,57 @@ +package v1alpha1 + +import ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +type Consumer struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ConsumerSpec `json:"spec,omitempty"` + Status Status `json:"status,omitempty"` +} + +type ConsumerSpec struct { + GatewayRef GatewayRef `json:"gatewayRef,omitempty"` + Credentials []CredentialSpec `json:"credentials,omitempty"` +} + +type GatewayRef struct { + Name string `json:"name,omitempty"` + Kind string `json:"kind,omitempty"` + Group string `json:"group,omitempty"` + Namespace *string `json:"namespace,omitempty"` +} + +// +kubebuilder:validation:XValidation:rule="has(self.config) != has(self.secretRef)" +type CredentialSpec struct { + // +kubebuilder:validation:Enum=jwt-auth;basic-auth;key-auth;hmac-auth; + Type string `json:"type"` + Config apiextensionsv1.JSON `json:"config,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty"` + Name string `json:"name,omitempty"` +} + +type SecretReference struct { + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` +} + +type Status struct { + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true +type ConsumerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Consumer `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Consumer{}, &ConsumerList{}) +} diff --git a/api/v1alpha1/pluginconfig_types.go b/api/v1alpha1/pluginconfig_types.go index 67153f5bd..aaa225d45 100644 --- a/api/v1alpha1/pluginconfig_types.go +++ b/api/v1alpha1/pluginconfig_types.go @@ -8,11 +8,6 @@ import ( // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. -// PluginConfigSpec defines the desired state of PluginConfig -type PluginConfigSpec struct { - Plugins []Plugin `json:"plugins"` -} - // +kubebuilder:object:root=true // PluginConfig is the Schema for the PluginConfigs API @@ -23,6 +18,11 @@ type PluginConfig struct { Spec PluginConfigSpec `json:"spec,omitempty"` } +// PluginConfigSpec defines the desired state of PluginConfig +type PluginConfigSpec struct { + Plugins []Plugin `json:"plugins"` +} + // +kubebuilder:object:root=true // PluginConfigList contains a list of PluginConfig diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 0c2fe85f3..92f22606a 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -21,10 +21,114 @@ limitations under the License. package v1alpha1 import ( - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Consumer) DeepCopyInto(out *Consumer) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Consumer. +func (in *Consumer) DeepCopy() *Consumer { + if in == nil { + return nil + } + out := new(Consumer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Consumer) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConsumerList) DeepCopyInto(out *ConsumerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Consumer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsumerList. +func (in *ConsumerList) DeepCopy() *ConsumerList { + if in == nil { + return nil + } + out := new(ConsumerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ConsumerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConsumerSpec) DeepCopyInto(out *ConsumerSpec) { + *out = *in + in.GatewayRef.DeepCopyInto(&out.GatewayRef) + if in.Credentials != nil { + in, out := &in.Credentials, &out.Credentials + *out = make([]CredentialSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsumerSpec. +func (in *ConsumerSpec) DeepCopy() *ConsumerSpec { + if in == nil { + return nil + } + out := new(ConsumerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialSpec) DeepCopyInto(out *CredentialSpec) { + *out = *in + in.Config.DeepCopyInto(&out.Config) + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(SecretReference) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialSpec. +func (in *CredentialSpec) DeepCopy() *CredentialSpec { + if in == nil { + return nil + } + out := new(CredentialSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GatewayProxy) DeepCopyInto(out *GatewayProxy) { *out = *in @@ -111,7 +215,7 @@ func (in *GatewayProxySpec) DeepCopyInto(out *GatewayProxySpec) { } if in.PluginMetadata != nil { in, out := &in.PluginMetadata, &out.PluginMetadata - *out = make(map[string]v1.JSON, len(*in)) + *out = make(map[string]apiextensionsv1.JSON, len(*in)) for key, val := range *in { (*out)[key] = *val.DeepCopy() } @@ -128,6 +232,26 @@ func (in *GatewayProxySpec) DeepCopy() *GatewayProxySpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GatewayRef) DeepCopyInto(out *GatewayRef) { + *out = *in + if in.Namespace != nil { + in, out := &in.Namespace, &out.Namespace + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayRef. +func (in *GatewayRef) DeepCopy() *GatewayRef { + if in == nil { + return nil + } + out := new(GatewayRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Plugin) DeepCopyInto(out *Plugin) { *out = *in @@ -223,3 +347,40 @@ func (in *PluginConfigSpec) DeepCopy() *PluginConfigSpec { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretReference) DeepCopyInto(out *SecretReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretReference. +func (in *SecretReference) DeepCopy() *SecretReference { + if in == nil { + return nil + } + out := new(SecretReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Status) DeepCopyInto(out *Status) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. +func (in *Status) DeepCopy() *Status { + if in == nil { + return nil + } + out := new(Status) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/gateway.apisix.io_consumers.yaml b/config/crd/bases/gateway.apisix.io_consumers.yaml new file mode 100644 index 000000000..06704b3b3 --- /dev/null +++ b/config/crd/bases/gateway.apisix.io_consumers.yaml @@ -0,0 +1,157 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: consumers.gateway.apisix.io +spec: + group: gateway.apisix.io + names: + kind: Consumer + listKind: ConsumerList + plural: consumers + singular: consumer + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + credentials: + items: + properties: + config: + x-kubernetes-preserve-unknown-fields: true + name: + type: string + secretRef: + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: + enum: + - jwt-auth + - basic-auth + - key-auth + - hmac-auth + type: string + required: + - type + type: object + x-kubernetes-validations: + - rule: has(self.config) != has(self.secretRef) + type: array + gatewayRef: + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + type: object + status: + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/rbac/gatewayproxy_editor_role.yaml b/config/rbac/gatewayproxy_editor_role.yaml index e214d969d..78fd4e4b3 100644 --- a/config/rbac/gatewayproxy_editor_role.yaml +++ b/config/rbac/gatewayproxy_editor_role.yaml @@ -12,7 +12,7 @@ metadata: name: gatewayproxy-editor-role rules: - apiGroups: - - gateway.apisix.io.github.com + - gateway.apisix.io resources: - gatewayproxies verbs: @@ -24,7 +24,7 @@ rules: - update - watch - apiGroups: - - gateway.apisix.io.github.com + - gateway.apisix.io resources: - gatewayproxies/status verbs: diff --git a/config/rbac/gatewayproxy_viewer_role.yaml b/config/rbac/gatewayproxy_viewer_role.yaml index 7def52762..19972e8c4 100644 --- a/config/rbac/gatewayproxy_viewer_role.yaml +++ b/config/rbac/gatewayproxy_viewer_role.yaml @@ -12,7 +12,7 @@ metadata: name: gatewayproxy-viewer-role rules: - apiGroups: - - gateway.apisix.io.github.com + - gateway.apisix.io resources: - gatewayproxies verbs: @@ -20,7 +20,7 @@ rules: - list - watch - apiGroups: - - gateway.apisix.io.github.com + - gateway.apisix.io resources: - gatewayproxies/status verbs: diff --git a/config/rbac/guestbook_editor_role.yaml b/config/rbac/guestbook_editor_role.yaml deleted file mode 100644 index 8b5e94117..000000000 --- a/config/rbac/guestbook_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit guestbooks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: api7-ingress - app.kubernetes.io/managed-by: kustomize - name: guestbook-editor-role -rules: -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks/status - verbs: - - get diff --git a/config/rbac/guestbook_viewer_role.yaml b/config/rbac/guestbook_viewer_role.yaml deleted file mode 100644 index 91c76d723..000000000 --- a/config/rbac/guestbook_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view guestbooks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: api7-ingress - app.kubernetes.io/managed-by: kustomize - name: guestbook-viewer-role -rules: -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks - verbs: - - get - - list - - watch -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks/status - verbs: - - get diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index bb145874c..5619aa009 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -18,10 +18,3 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by -# default, aiding admins in cluster management. Those roles are -# not used by the Project itself. You can comment the following lines -# if you do not want those helpers be installed with your Project. -- guestbook_editor_role.yaml -- guestbook_viewer_role.yaml - diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index d18ea6240..3cad6be02 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: manager-role + name: api7-ingress-manager-role rules: - apiGroups: - "" @@ -55,6 +55,21 @@ rules: - get - list - watch +- apiGroups: + - gateway.apisix.io + resources: + - consumers + verbs: + - get + - list + - watch +- apiGroups: + - gateway.apisix.io + resources: + - consumers/status + verbs: + - get + - update - apiGroups: - gateway.apisix.io resources: diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index 55820434d..778f0d2dd 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -8,7 +8,7 @@ metadata: roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: manager-role + name: api7-ingress-manager-role subjects: - kind: ServiceAccount name: controller-manager diff --git a/internal/controller/consumer_controller.go b/internal/controller/consumer_controller.go new file mode 100644 index 000000000..c372e967b --- /dev/null +++ b/internal/controller/consumer_controller.go @@ -0,0 +1,50 @@ +package controller + +import ( + "context" + + "github.com/api7/api7-ingress-controller/api/v1alpha1" + "github.com/api7/api7-ingress-controller/internal/provider" + "github.com/go-logr/logr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// ConsumerReconciler reconciles a Gateway object. +type ConsumerReconciler struct { //nolint:revive + client.Client + Scheme *runtime.Scheme + Log logr.Logger + + Provider provider.Provider +} + +// SetupWithManager sets up the controller with the Manager. +func (r *ConsumerReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&v1alpha1.Consumer{}). + Complete(r) +} + +func (r *ConsumerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + consumer := new(v1alpha1.Consumer) + if err := r.Get(ctx, req.NamespacedName, consumer); err != nil { + if client.IgnoreNotFound(err) == nil { + consumer.Namespace = req.Namespace + consumer.Name = req.Name + + consumer.TypeMeta = metav1.TypeMeta{ + Kind: "Consumer", + APIVersion: v1alpha1.GroupVersion.String(), + } + + if err := r.Provider.Delete(ctx, consumer); err != nil { + return ctrl.Result{}, err + } + } + return ctrl.Result{}, err + } + return ctrl.Result{}, nil +} diff --git a/internal/controller/gateway_controller.go b/internal/controller/gateway_controller.go index e71e56e0c..47e42fa3c 100644 --- a/internal/controller/gateway_controller.go +++ b/internal/controller/gateway_controller.go @@ -24,9 +24,6 @@ import ( gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" ) -// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways,verbs=get;list;watch;update -// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways/status,verbs=get;update - // GatewayReconciler reconciles a Gateway object. type GatewayReconciler struct { //nolint:revive client.Client diff --git a/internal/controller/httproute_controller.go b/internal/controller/httproute_controller.go index 77e7251e8..afe21a884 100644 --- a/internal/controller/httproute_controller.go +++ b/internal/controller/httproute_controller.go @@ -25,9 +25,6 @@ import ( "github.com/api7/api7-ingress-controller/internal/provider" ) -// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch -// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes/status,verbs=get;update - // HTTPRouteReconciler reconciles a GatewayClass object. type HTTPRouteReconciler struct { //nolint:revive client.Client diff --git a/internal/manager/controllers.go b/internal/manager/controllers.go index 5c17c5848..e2846da09 100644 --- a/internal/manager/controllers.go +++ b/internal/manager/controllers.go @@ -11,14 +11,27 @@ import ( "github.com/api7/api7-ingress-controller/internal/provider" ) +// K8s // +kubebuilder:rbac:groups="",resources=events,verbs=create;patch // +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups="discovery.k8s.io",resources=endpointslices,verbs=get;list;watch // +kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch // +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch // +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch + +// CustomResourceDefinition // +kubebuilder:rbac:groups=gateway.apisix.io,resources=pluginconfigs,verbs=get;list;watch // +kubebuilder:rbac:groups=gateway.apisix.io,resources=gatewayproxies,verbs=get;list;watch +// +kubebuilder:rbac:groups=gateway.apisix.io,resources=consumers,verbs=get;list;watch +// +kubebuilder:rbac:groups=gateway.apisix.io,resources=consumers/status,verbs=get;update + +// GatewayAPI +// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gatewayclasses,verbs=get;list;watch;update +// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gatewayclasses/status,verbs=get;update +// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways,verbs=get;list;watch;update +// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways/status,verbs=get;update +// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch +// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes/status,verbs=get;update type Controller interface { SetupWithManager(mgr manager.Manager) error @@ -46,5 +59,11 @@ func setupControllers(ctx context.Context, mgr manager.Manager, pro provider.Pro Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("HTTPRoute"), Provider: pro, }, + &controller.ConsumerReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("Consumer"), + Provider: pro, + }, }, nil } diff --git a/test/e2e/framework/dashboard.go b/test/e2e/framework/dashboard.go index b255cfe43..395d30592 100644 --- a/test/e2e/framework/dashboard.go +++ b/test/e2e/framework/dashboard.go @@ -235,6 +235,10 @@ dashboard_service: # port: # number: 7943 tls: [] +api_usage: + service: + ingress: + enabled: false `) if err != nil { panic(err) diff --git a/test/e2e/framework/manifests/ingress.yaml b/test/e2e/framework/manifests/ingress.yaml index 6be443c0c..b57c988cc 100644 --- a/test/e2e/framework/manifests/ingress.yaml +++ b/test/e2e/framework/manifests/ingress.yaml @@ -52,56 +52,6 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: api7-ingress - name: api7-ingress-guestbook-editor-role -rules: -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: api7-ingress - name: api7-ingress-guestbook-viewer-role -rules: -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks - verbs: - - get - - list - - watch -- apiGroups: - - gateway.apisix.io.github.com - resources: - - guestbooks/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole metadata: name: api7-ingress-manager-role rules: @@ -115,7 +65,7 @@ rules: - apiGroups: - "" resources: - - services + - namespaces verbs: - get - list @@ -131,7 +81,7 @@ rules: - apiGroups: - "" resources: - - namespaces + - services verbs: - get - list @@ -159,12 +109,34 @@ rules: - apiGroups: - gateway.apisix.io resources: - - pluginconfigs + - consumers + verbs: + - get + - list + - watch +- apiGroups: + - gateway.apisix.io + resources: + - consumers/status + verbs: + - get + - update +- apiGroups: + - gateway.apisix.io + resources: - gatewayproxies verbs: - get - list - watch +- apiGroups: + - gateway.apisix.io + resources: + - pluginconfigs + verbs: + - get + - list + - watch - apiGroups: - gateway.networking.k8s.io resources: