Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Backport of Net 6289 improve consul api gateway annotations into release/1.3.x #3479

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
7513ab5
backport of commit 06486579fb4082a8203a3877e690a2dcaffa2e44
nathancoleman Nov 3, 2023
9a2893f
backport of commit d19290d5640881801e65e4a474e8737851fda3fc
nathancoleman Nov 3, 2023
59e27b7
backport of commit c2bed3ecd57459fc6cef5abe36663196a24f6e97
nathancoleman Nov 3, 2023
b9073dc
backport of commit 98b2dd973cf3268668bd919cbbf31cc8d6b3ef40
nathancoleman Nov 3, 2023
feacdd7
backport of commit 529f2011a3b979a0d9af86fb424e25465894dc2e
nathancoleman Nov 3, 2023
7ac2a37
backport of commit 27a0f8b3773b7d3ba79d813355162f81525165b2
nathancoleman Nov 3, 2023
14175ce
backport of commit 13dea3a90cdeb5a0bd2f2f40b570690e9e32f188
sarahalsmiller Jan 5, 2024
ac0c59c
backport of commit 4130d8ddab0d8eaaf15d1a027dca320a763a13c4
sarahalsmiller Jan 8, 2024
70c3f30
backport of commit b8b567f73b3c676f18647dd8b929a2412e57ccb7
sarahalsmiller Jan 8, 2024
fea3c34
backport of commit 5842d3eced83fb53bf7ab861b5076d4fbb6be3b8
sarahalsmiller Jan 8, 2024
aae2cc6
backport of commit 79211272a5fb8b7fdda2e0a373b0743bdb1cfc17
sarahalsmiller Jan 8, 2024
0c022a7
backport of commit 2c0babc11b51b51fb53a458991ae19c7b7814d58
sarahalsmiller Jan 8, 2024
507e133
backport of commit 376879602c44b145b125a5045f53569dd2e53ec1
sarahalsmiller Jan 8, 2024
84d7b0b
backport of commit 67bef5a859301fe987f06e65666eabff60e64a5d
sarahalsmiller Jan 8, 2024
8908390
backport of commit 650f49c5556003800ca3b61fd27862ca69d7a9e0
sarahalsmiller Jan 16, 2024
c62ae2f
Merge branch 'release/1.3.x' into backport/NET-6289-Improve-Consul-AP…
sarahalsmiller Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/3437.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug-fix
api-gateways: API Gateway pods now include `gateway-kind` and `gateway-consul-service-name` annotations consistent with other Consul gateway types.
```
61 changes: 46 additions & 15 deletions cli/cmd/proxy/list/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ import (
"strings"
"sync"

"github.com/hashicorp/consul-k8s/cli/common"
"github.com/hashicorp/consul-k8s/cli/common/flag"
"github.com/hashicorp/consul-k8s/cli/common/terminal"
"github.com/posener/complete"
helmCLI "helm.sh/helm/v3/pkg/cli"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/validation"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"

"github.com/hashicorp/consul-k8s/cli/common"
"github.com/hashicorp/consul-k8s/cli/common/flag"
"github.com/hashicorp/consul-k8s/cli/common/terminal"
)

const (
Expand Down Expand Up @@ -211,21 +212,51 @@ func (c *ListCommand) fetchPods() ([]v1.Pod, error) {

// Fetch all pods in the namespace with labels matching the gateway component names.
gatewaypods, err := c.kubernetes.CoreV1().Pods(c.namespace()).List(c.Ctx, metav1.ListOptions{
LabelSelector: "component in (ingress-gateway, mesh-gateway, terminating-gateway), chart=consul-helm",
LabelSelector: "component in (api-gateway, ingress-gateway, mesh-gateway, terminating-gateway), chart=consul-helm",
})
if err != nil {
return nil, err
}
pods = append(pods, gatewaypods.Items...)

// Fetch all pods in the namespace with a label indicating they are an API gateway.
// Fetch API Gateway pods with deprecated label and append if they aren't already in the list
// TODO this block can be deleted if and when we decide we are ok with no longer listing pods of people using previous API Gateway
// versions.
apigatewaypods, err := c.kubernetes.CoreV1().Pods(c.namespace()).List(c.Ctx, metav1.ListOptions{
LabelSelector: "api-gateway.consul.hashicorp.com/managed=true",
})

namespacedName := func(pod v1.Pod) string {
return pod.Namespace + pod.Name
}
if err != nil {
return nil, err
}
pods = append(pods, apigatewaypods.Items...)
if len(apigatewaypods.Items) > 0 {
//Deduplicated pod list
seenPods := map[string]struct{}{}
for _, pod := range apigatewaypods.Items {
if _, ok := seenPods[namespacedName(pod)]; ok {
continue
}
found := false
for _, gatewayPod := range gatewaypods.Items {
//note that we already have this pod in the list so we can exit early.
seenPods[namespacedName(gatewayPod)] = struct{}{}

if (namespacedName(gatewayPod)) == namespacedName(pod) {
found = true
break
}
}
//pod isn't in the list already, we can add it.
if !found {
pods = append(pods, pod)
}

}
}
//---

// Fetch all pods in the namespace with a label indicating they are a service networked by Consul.
sidecarpods, err := c.kubernetes.CoreV1().Pods(c.namespace()).List(c.Ctx, metav1.ListOptions{
Expand Down Expand Up @@ -268,22 +299,22 @@ func (c *ListCommand) output(pods []v1.Pod) {

// Get the type for ingress, mesh, and terminating gateways.
switch pod.Labels["component"] {
case "api-gateway":
proxyType = "API Gateway"
case "ingress-gateway":
proxyType = "Ingress Gateway"
case "mesh-gateway":
proxyType = "Mesh Gateway"
case "terminating-gateway":
proxyType = "Terminating Gateway"
}

// Determine if the pod is an API Gateway.
if pod.Labels["api-gateway.consul.hashicorp.com/managed"] == "true" {
proxyType = "API Gateway"
}

// Fallback to "Sidecar" as a default
if proxyType == "" {
default:
// Fallback to "Sidecar" as a default
proxyType = "Sidecar"

// Determine if deprecated API Gateway pod.
if pod.Labels["api-gateway.consul.hashicorp.com/managed"] == "true" {
proxyType = "API Gateway"
}
}

if c.flagAllNamespaces {
Expand Down
44 changes: 43 additions & 1 deletion cli/cmd/proxy/list/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,33 @@ func TestListCommandOutput(t *testing.T) {
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "depricated-api-gateway",
Namespace: "consul",
Labels: map[string]string{
"api-gateway.consul.hashicorp.com/managed": "true",
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "api-gateway",
Namespace: "consul",
Labels: map[string]string{
"component": "api-gateway",
"chart": "consul-helm",
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "both-labels-api-gateway",
Namespace: "consul",
Labels: map[string]string{
"api-gateway.consul.hashicorp.com/managed": "true",
"component": "api-gateway",
"chart": "consul-helm",
},
},
},
Expand Down Expand Up @@ -321,7 +342,7 @@ func TestListCommandOutput(t *testing.T) {

func TestListCommandOutputInJsonFormat(t *testing.T) {
// These regular expressions must be present in the output.
expected := ".*Name.*mesh-gateway.*\n.*Namespace.*consul.*\n.*Type.*Mesh Gateway.*\n.*\n.*\n.*Name.*terminating-gateway.*\n.*Namespace.*consul.*\n.*Type.*Terminating Gateway.*\n.*\n.*\n.*Name.*ingress-gateway.*\n.*Namespace.*default.*\n.*Type.*Ingress Gateway.*\n.*\n.*\n.*Name.*api-gateway.*\n.*Namespace.*consul.*\n.*Type.*API Gateway.*\n.*\n.*\n.*Name.*pod1.*\n.*Namespace.*default.*\n.*Type.*Sidecar.*"
expected := ".*Name.*api-gateway.*\n.*Namespace.*consul.*\n.*Type.*API Gateway.*\n.*\n.*\n.*Name.*both-labels-api-gateway.*\n.*Namespace.*consul.*\n.*Type.*API Gateway.*\n.*\n.*\n.*Name.*mesh-gateway.*\n.*Namespace.*consul.*\n.*Type.*Mesh Gateway.*\n.*\n.*\n.*Name.*terminating-gateway.*\n.*Namespace.*consul.*\n.*Type.*Terminating Gateway.*\n.*\n.*\n.*Name.*ingress-gateway.*\n.*Namespace.*default.*\n.*Type.*Ingress Gateway.*\n.*\n.*\n.*Name.*deprecated-api-gateway.*\n.*Namespace.*consul.*\n.*Type.*API Gateway.*\n.*\n.*\n.*Name.*pod1.*\n.*Namespace.*default.*\n.*Type.*Sidecar.*"
notExpected := "default.*dont-fetch.*Sidecar"

pods := []v1.Pod{
Expand Down Expand Up @@ -359,6 +380,27 @@ func TestListCommandOutputInJsonFormat(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "api-gateway",
Namespace: "consul",
Labels: map[string]string{
"component": "api-gateway",
"chart": "consul-helm",
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "both-labels-api-gateway",
Namespace: "consul",
Labels: map[string]string{
"api-gateway.consul.hashicorp.com/managed": "true",
"component": "api-gateway",
"chart": "consul-helm",
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "deprecated-api-gateway",
Namespace: "consul",
Labels: map[string]string{
"api-gateway.consul.hashicorp.com/managed": "true",
},
Expand Down
2 changes: 2 additions & 0 deletions control-plane/api-gateway/common/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

const (
componentLabel = "component"
nameLabel = "gateway.consul.hashicorp.com/name"
namespaceLabel = "gateway.consul.hashicorp.com/namespace"
createdAtLabel = "gateway.consul.hashicorp.com/created"
Expand All @@ -21,6 +22,7 @@ const (
// LabelsForGateway formats the default labels that appear on objects managed by the controllers.
func LabelsForGateway(gateway *gwv1beta1.Gateway) map[string]string {
return map[string]string{
componentLabel: "api-gateway",
nameLabel: gateway.Name,
namespaceLabel: gateway.Namespace,
createdAtLabel: fmt.Sprintf("%d", gateway.CreationTimestamp.Unix()),
Expand Down
13 changes: 8 additions & 5 deletions control-plane/api-gateway/gatekeeper/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ package gatekeeper
import (
"context"

"github.com/hashicorp/consul-k8s/control-plane/api-gateway/common"
"github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1"
"k8s.io/apimachinery/pkg/types"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

"github.com/hashicorp/consul-k8s/control-plane/api-gateway/common"
"github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1"
"github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants"
)

const (
Expand Down Expand Up @@ -110,7 +111,9 @@ func (g *Gatekeeper) deployment(gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayC
ObjectMeta: metav1.ObjectMeta{
Labels: common.LabelsForGateway(&gateway),
Annotations: map[string]string{
"consul.hashicorp.com/connect-inject": "false",
constants.AnnotationInject: "false",
constants.AnnotationGatewayConsulServiceName: gateway.Name,
constants.AnnotationGatewayKind: "api-gateway",
},
},
Spec: corev1.PodSpec{
Expand Down
8 changes: 7 additions & 1 deletion control-plane/api-gateway/gatekeeper/gatekeeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/hashicorp/consul-k8s/control-plane/api-gateway/common"
"github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1"
"github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants"
)

var (
Expand All @@ -34,6 +35,7 @@ var (
name = "test"
namespace = "default"
labels = map[string]string{
"component": "api-gateway",
"gateway.consul.hashicorp.com/name": name,
"gateway.consul.hashicorp.com/namespace": namespace,
createdAtLabelKey: createdAtLabelValue,
Expand Down Expand Up @@ -1007,6 +1009,8 @@ func validateResourcesExist(t *testing.T, client client.Client, resources resour
require.NotNil(t, actual.Spec.Replicas)
require.EqualValues(t, *expected.Spec.Replicas, *actual.Spec.Replicas)
}
require.Equal(t, expected.Spec.Template.ObjectMeta.Annotations, actual.Spec.Template.ObjectMeta.Annotations)
require.Equal(t, expected.Spec.Template.ObjectMeta.Labels, actual.Spec.Template.Labels)

// Ensure there is a consul-dataplane container dropping ALL capabilities, adding
// back the NET_BIND_SERVICE capability, and establishing a read-only root filesystem
Expand Down Expand Up @@ -1189,7 +1193,9 @@ func configureDeployment(name, namespace string, labels map[string]string, repli
ObjectMeta: metav1.ObjectMeta{
Labels: labels,
Annotations: map[string]string{
"consul.hashicorp.com/connect-inject": "false",
constants.AnnotationInject: "false",
constants.AnnotationGatewayConsulServiceName: name,
constants.AnnotationGatewayKind: "api-gateway",
},
},
Spec: corev1.PodSpec{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ const (

// AnnotationGatewayKind is the key of the annotation that indicates pods
// that represent Consul Connect Gateways. This should be set to a
// value that is either "mesh", "ingress" or "terminating".
// value that is either "mesh-gateway", "ingress-gateway", "terminating-gateway",
// or "api-gateway".
AnnotationGatewayKind = "consul.hashicorp.com/gateway-kind"

// AnnotationGatewayConsulServiceName is the key of the annotation whose value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (
meshGateway = "mesh-gateway"
terminatingGateway = "terminating-gateway"
ingressGateway = "ingress-gateway"
apiGateway = "api-gateway"

envoyPrometheusBindAddr = "envoy_prometheus_bind_addr"
envoyTelemetryCollectorBindSocketDir = "envoy_telemetry_collector_bind_socket_dir"
Expand Down Expand Up @@ -801,9 +802,11 @@ func (r *Controller) createGatewayRegistrations(pod corev1.Pod, serviceEndpoints
"address": "0.0.0.0",
},
}

case apiGateway:
// Do nothing. This is only here so that API gateway pods have annotations
// consistent with other gateway types but don't return an error below.
default:
return nil, fmt.Errorf("%s must be one of %s, %s, or %s", constants.AnnotationGatewayKind, meshGateway, terminatingGateway, ingressGateway)
return nil, fmt.Errorf("%s must be one of %s, %s, %s, or %s", constants.AnnotationGatewayKind, meshGateway, terminatingGateway, ingressGateway, apiGateway)
}

if r.MetricsConfig.DefaultEnableMetrics && r.MetricsConfig.EnableGatewayMetrics {
Expand Down Expand Up @@ -1444,10 +1447,11 @@ func hasBeenInjected(pod corev1.Pod) bool {
return false
}

// isGateway checks the value of the gateway annotation and returns true if the Pod represents a Gateway.
// isGateway checks the value of the gateway annotation and returns true if the Pod
// represents a Gateway kind that should be acted upon by the endpoints controller.
func isGateway(pod corev1.Pod) bool {
anno, ok := pod.Annotations[constants.AnnotationGatewayKind]
return ok && anno != ""
return ok && anno != "" && anno != apiGateway
}

// isTelemetryCollector checks whether a pod is part of a deployment for a Consul Telemetry Collector. If so,
Expand Down