Skip to content

Commit

Permalink
feat: deprecate --gateway-discovery-dns-strategy make resolution to…
Browse files Browse the repository at this point in the history
… always work
  • Loading branch information
programmer04 committed Jan 27, 2025
1 parent 1778b51 commit 4c88518
Show file tree
Hide file tree
Showing 29 changed files with 476 additions and 599 deletions.
1 change: 0 additions & 1 deletion docs/cli-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
| `--enable-reverse-sync` | `bool` | Send configuration to Kong even if the configuration checksum has not changed since previous update. | `false` |
| `--feature-gates` | `list of string=bool` | A set of comma separated key=value pairs that describe feature gates for alpha/beta/experimental features. See the Feature Gates documentation for information and available options: https://github.com/Kong/kubernetes-ingress-controller/blob/main/FEATURE_GATES.md. | |
| `--gateway-api-controller-name` | `string` | The controller name to match on Gateway API resources. | `konghq.com/kic-gateway-controller` |
| `--gateway-discovery-dns-strategy` | `dns-strategy` | DNS strategy to use when creating Gateway's Admin API addresses. One of: ip, service, pod. | `"ip"` |
| `--gateway-discovery-readiness-check-interval` | `duration` | Interval of readiness checks on gateway admin API clients for discovery. | `10s` |
| `--gateway-discovery-readiness-check-timeout` | `duration` | Timeout of readiness checks on gateway admin clients. | `5s` |
| `--gateway-to-reconcile` | `namespaced-name` | Gateway namespaced name in "namespace/name" format. Makes KIC reconcile only the specified Gateway. | |
Expand Down
14 changes: 8 additions & 6 deletions internal/adminapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ func (c *Client) PodReference() (k8stypes.NamespacedName, bool) {

type ClientFactory struct {
workspace string
httpClientOpts HTTPClientOpts
httpClientOpts ClientOpts
adminToken string
}

func NewClientFactoryForWorkspace(workspace string, httpClientOpts HTTPClientOpts, adminToken string) ClientFactory {
func NewClientFactoryForWorkspace(workspace string, httpClientOpts ClientOpts, adminToken string) ClientFactory {
return ClientFactory{
workspace: workspace,
httpClientOpts: httpClientOpts,
Expand All @@ -218,11 +218,13 @@ func NewClientFactoryForWorkspace(workspace string, httpClientOpts HTTPClientOpt
}

func (cf ClientFactory) CreateAdminAPIClient(ctx context.Context, discoveredAdminAPI DiscoveredAdminAPI) (*Client, error) {
httpclient, err := MakeHTTPClient(&cf.httpClientOpts, cf.adminToken)
if err != nil {
return nil, err
opts := cf.httpClientOpts
opts.ResolveTo = ResolveTo{
From: discoveredAdminAPI.Authority,
To: discoveredAdminAPI.ResolveTo,
}
cl, err := NewKongClientForWorkspace(ctx, discoveredAdminAPI.Address, cf.workspace, httpclient)

cl, err := NewKongClientForWorkspace(ctx, discoveredAdminAPI.Address, cf.workspace, opts, cf.adminToken)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/adminapi/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func TestClientFactory_CreateAdminAPIClientAttachesPodReference(t *testing.T) {
factory := adminapi.NewClientFactoryForWorkspace("workspace", adminapi.HTTPClientOpts{}, "")
factory := adminapi.NewClientFactoryForWorkspace("workspace", adminapi.ClientOpts{}, "")

adminAPIHandler := mocks.NewAdminAPIHandler(t)
adminAPIServer := httptest.NewServer(adminAPIHandler)
Expand Down
79 changes: 27 additions & 52 deletions internal/adminapi/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,37 @@ import (
k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/controller-runtime/pkg/client"

cfgtypes "github.com/kong/kubernetes-ingress-controller/v3/internal/manager/config/types"
)

// DiscoveredAdminAPI represents an Admin API discovered from a Kubernetes Service.
type DiscoveredAdminAPI struct {
// https://10-68-0-5.dataplane-admin-kong-rqwr9-sc49t.default.svc:8444
Address string
PodRef k8stypes.NamespacedName

// 10-68-0-5.dataplane-admin-kong-rqwr9-sc49t.default.svc:8444
Authority string

// 10.68.0.5:8444
ResolveTo string

PodRef k8stypes.NamespacedName
}

type Discoverer struct {
// portNames is the set of port names that Admin API Service ports will be
// matched against.
portNames sets.Set[string]

// dnsStrategy is the DNS strategy to use when resolving Admin API Service
// addresses.
dnsStrategy cfgtypes.DNSStrategy
}

func NewDiscoverer(
adminAPIPortNames sets.Set[string],
dnsStrategy cfgtypes.DNSStrategy,
) (*Discoverer, error) {
if adminAPIPortNames.Len() == 0 {
return nil, fmt.Errorf("no admin API port names provided")
}
if err := dnsStrategy.Validate(); err != nil {
return nil, fmt.Errorf("invalid dns strategy: %w", err)
}

return &Discoverer{
portNames: adminAPIPortNames,
dnsStrategy: dnsStrategy,
portNames: adminAPIPortNames,
}, nil
}

Expand Down Expand Up @@ -140,7 +137,7 @@ func (d *Discoverer) AdminAPIsFromEndpointSlice(
Namespace: endpoints.Namespace,
}

adminAPI, err := adminAPIFromEndpoint(e, p, svc, d.dnsStrategy, endpoints.AddressType)
adminAPI, err := adminAPIFromEndpoint(e, p, svc, endpoints.AddressType)
if err != nil {
return nil, err
}
Expand All @@ -154,9 +151,10 @@ func adminAPIFromEndpoint(
endpoint discoveryv1.Endpoint,
port discoveryv1.EndpointPort,
service k8stypes.NamespacedName,
dnsStrategy cfgtypes.DNSStrategy,
addressFamily discoveryv1.AddressType,
) (DiscoveredAdminAPI, error) {
// XXX: maybe I have to care about addressFamily?
_ = addressFamily
podNN := k8stypes.NamespacedName{
Name: endpoint.TargetRef.Name,
Namespace: endpoint.TargetRef.Namespace,
Expand All @@ -171,43 +169,20 @@ func adminAPIFromEndpoint(
// server will live in another Pod/elsewhere so allowing http would
// not be considered best practice.

switch dnsStrategy {
case cfgtypes.ServiceScopedPodDNSStrategy:
if service.Name == "" {
return DiscoveredAdminAPI{}, fmt.Errorf(
"service name is empty for an endpoint with TargetRef %s/%s",
endpoint.TargetRef.Namespace, endpoint.TargetRef.Name,
)
}

ipAddr := strings.ReplaceAll(eAddress, ".", "-")
address := fmt.Sprintf("%s.%s.%s.svc", ipAddr, service.Name, service.Namespace)

return DiscoveredAdminAPI{
Address: fmt.Sprintf("https://%s:%d", address, *port.Port),
PodRef: podNN,
}, nil

case cfgtypes.NamespaceScopedPodDNSStrategy:
ipAddr := strings.ReplaceAll(eAddress, ".", "-")
address := fmt.Sprintf("%s.%s.pod", ipAddr, service.Namespace)
if service.Name == "" {
return DiscoveredAdminAPI{}, fmt.Errorf(
"service name is empty for an endpoint with TargetRef %s/%s",
endpoint.TargetRef.Namespace, endpoint.TargetRef.Name,
)
}

return DiscoveredAdminAPI{
Address: fmt.Sprintf("https://%s:%d", address, *port.Port),
PodRef: podNN,
}, nil
ipAddr := strings.ReplaceAll(eAddress, ".", "-")
address := fmt.Sprintf("%s.%s.%s.svc", ipAddr, service.Name, service.Namespace)

case cfgtypes.IPDNSStrategy:
bounded := eAddress
if addressFamily == discoveryv1.AddressTypeIPv6 {
bounded = fmt.Sprintf("[%s]", bounded)
}
return DiscoveredAdminAPI{
Address: fmt.Sprintf("https://%s:%d", bounded, *port.Port),
PodRef: podNN,
}, nil

default:
return DiscoveredAdminAPI{}, fmt.Errorf("unknown dns strategy: %s", dnsStrategy)
}
return DiscoveredAdminAPI{
Address: fmt.Sprintf("https://%s:%d", address, *port.Port),
Authority: fmt.Sprintf("%s:%d", address, *port.Port),
ResolveTo: fmt.Sprintf("%s:%d", eAddress, *port.Port),
PodRef: podNN,
}, nil
}
Loading

0 comments on commit 4c88518

Please sign in to comment.