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

Admin server backports [1.17] #9795

Merged
merged 4 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions changelog/v1.17.1/admin-server-updates.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
changelog:
- type: NON_USER_FACING
issueLink: https://github.com/solo-io/solo-projects/issues/6391
resolvesIssue: false
description: >-
Admin endpoint now returns snapshot resources in Kubernetes format (with apiVersion,
kind, metadata, spec), and returns all resources as a flat list.
- type: NON_USER_FACING
issueLink: https://github.com/solo-io/solo-projects/issues/6391
resolvesIssue: false
description: >-
Return Settings, GatewayParameters, and other resources from Admin input snapshot endpoint.
- type: NON_USER_FACING
issueLink: https://github.com/solo-io/solo-projects/issues/6391
resolvesIssue: false
description: >-
Allow the list of Kubernetes Gateway-related resource types returned by the Admin input snapshot endpoint
to be configured via the History object.
15 changes: 14 additions & 1 deletion projects/gateway2/api/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,26 @@ import (
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

const (
Group = "gateway.gloo.solo.io"
Version = "v1alpha1"

GatewayParametersKind = "GatewayParameters"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "gateway.gloo.solo.io", Version: "v1alpha1"}
GroupVersion = schema.GroupVersion{Group: Group, Version: Version}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme

GatewayParametersGVK = schema.GroupVersionKind{
Group: Group,
Version: Version,
Kind: GatewayParametersKind,
}
)
14 changes: 6 additions & 8 deletions projects/gateway2/controller/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ package controller
import (
"context"

"github.com/solo-io/gloo/projects/gloo/pkg/servers/iosnapshot"

ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
apiv1 "sigs.k8s.io/gateway-api/apis/v1"

gatewayv1 "github.com/solo-io/gloo/projects/gateway/pkg/api/v1"
"github.com/solo-io/gloo/projects/gateway2/controller/scheme"
"github.com/solo-io/gloo/projects/gateway2/extensions"
Expand All @@ -21,7 +13,13 @@ import (
api "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/enterprise/options/extauth/v1"
"github.com/solo-io/gloo/projects/gloo/pkg/bootstrap"
"github.com/solo-io/gloo/projects/gloo/pkg/plugins"
"github.com/solo-io/gloo/projects/gloo/pkg/servers/iosnapshot"
"github.com/solo-io/solo-kit/pkg/api/v2/reporter"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
apiv1 "sigs.k8s.io/gateway-api/apis/v1"
)

const (
Expand Down
3 changes: 1 addition & 2 deletions projects/gateway2/extensions/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package extensions
import (
"context"

v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/enterprise/options/extauth/v1"

gatewayv1 "github.com/solo-io/gloo/projects/gateway/pkg/api/v1"
"github.com/solo-io/gloo/projects/gateway2/query"
"github.com/solo-io/gloo/projects/gateway2/translator/plugins/registry"
v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/enterprise/options/extauth/v1"
"github.com/solo-io/solo-kit/pkg/api/v2/reporter"
controllerruntime "sigs.k8s.io/controller-runtime"
)
Expand Down
65 changes: 63 additions & 2 deletions projects/gateway2/wellknown/gwapi.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package wellknown

import (
"k8s.io/apimachinery/pkg/runtime/schema"
apiv1 "sigs.k8s.io/gateway-api/apis/v1"
)

const (
// Group string for Gateway resource
GatewayGroup = "gateway.networking.k8s.io"
// Group string for Gateway API resources
GatewayGroup = apiv1.GroupName

// Kind string for k8s service
ServiceKind = "Service"
Expand All @@ -12,4 +17,60 @@ const (

// Kind string for Gateway resource
GatewayKind = "Gateway"

// Kind string for GatewayClass resource
GatewayClassKind = "GatewayClass"

// Kind string for ReferenceGrant resource
ReferenceGrantKind = "ReferenceGrant"

// Kind strings for Gateway API list types
HTTPRouteListKind = "HTTPRouteList"
GatewayListKind = "GatewayList"
GatewayClassListKind = "GatewayClassList"
ReferenceGrantListKind = "ReferenceGrantList"
)

var (
GatewayGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1",
Kind: GatewayKind,
}
GatewayClassGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1",
Kind: GatewayClassKind,
}
HTTPRouteGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1",
Kind: HTTPRouteKind,
}
ReferenceGrantGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1beta1",
Kind: ReferenceGrantKind,
}

GatewayListGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1",
Kind: GatewayListKind,
}
GatewayClassListGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1",
Kind: GatewayClassListKind,
}
HTTPRouteListGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1",
Kind: HTTPRouteListKind,
}
ReferenceGrantListGVK = schema.GroupVersionKind{
Group: GatewayGroup,
Version: "v1beta1",
Kind: ReferenceGrantListKind,
}
)
16 changes: 5 additions & 11 deletions projects/gloo/pkg/plugins/utils/update_upstream_spec_test.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package utils_test

import (
"reflect"

"google.golang.org/protobuf/types/known/durationpb"

"github.com/golang/protobuf/ptypes/wrappers"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/solo-io/gloo/projects/gloo/pkg/api/external/envoy/api/v2/cluster"
envoycore_gloo "github.com/solo-io/gloo/projects/gloo/pkg/api/external/envoy/api/v2/core"
gloov1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1"
"github.com/solo-io/gloo/projects/gloo/pkg/api/v1/ssl"
"github.com/solo-io/gloo/projects/gloo/pkg/plugins/utils"
"github.com/solo-io/gloo/test/gomega/assertions"
"github.com/solo-io/solo-kit/pkg/api/v1/resources/core"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"google.golang.org/protobuf/types/known/durationpb"
)

var _ = Describe("UpdateUpstream", func() {
Expand Down Expand Up @@ -122,10 +119,7 @@ var _ = Describe("UpdateUpstream", func() {
// This test is important as it checks whether the upstream struct/proto have a new top level field.
// This should happen very rarely, and should be used as an indication that the `UpdateUpstream` function
// most likely needs to change.
Expect(reflect.TypeOf(gloov1.Upstream{}).NumField()).To(
Equal(29),
"wrong number of fields found",
)
assertions.ExpectNumFields(gloov1.Upstream{}, 29)
})

})
167 changes: 167 additions & 0 deletions projects/gloo/pkg/servers/iosnapshot/convert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package iosnapshot

import (
gatewayv1 "github.com/solo-io/gloo/projects/gateway/pkg/api/v1"
ratelimitv1alpha1 "github.com/solo-io/gloo/projects/gloo/pkg/api/external/solo/ratelimit"
gloov1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1"
extauthv1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/enterprise/options/extauth/v1"
graphqlv1beta1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/enterprise/options/graphql/v1beta1"
v1snap "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/gloosnapshot"
"github.com/solo-io/solo-kit/pkg/api/v1/clients/kube/crd"
crdv1 "github.com/solo-io/solo-kit/pkg/api/v1/clients/kube/crd/solo.io/v1"
"github.com/solo-io/solo-kit/pkg/api/v1/resources"
"github.com/solo-io/solo-kit/pkg/utils/kubeutils"
"github.com/solo-io/solo-kit/pkg/utils/protoutils"
)

// convert all the resources in the input snapshot, excluding Artifacts and Secrets, into Kubernetes format
func snapshotToKubeResources(snap *v1snap.ApiSnapshot) ([]crdv1.Resource, error) {
resources := []crdv1.Resource{}

// gloo.solo.io resources
for _, upstream := range snap.Upstreams {
kubeUpstream, err := gloov1.UpstreamCrd.KubeResource(upstream)
if err != nil {
return nil, err
}
resources = append(resources, *kubeUpstream)
}
for _, upstreamGroup := range snap.UpstreamGroups {
kubeUpstreamGroup, err := gloov1.UpstreamGroupCrd.KubeResource(upstreamGroup)
if err != nil {
return nil, err
}
resources = append(resources, *kubeUpstreamGroup)
}
for _, proxy := range snap.Proxies {
kubeProxy, err := gloov1.ProxyCrd.KubeResource(proxy)
if err != nil {
return nil, err
}
resources = append(resources, *kubeProxy)
}
// Endpoints are only stored in memory and don't have a Kubernetes resource equivalent,
// so we do custom conversion here to make the format consistent with the other resources
for _, endpoint := range snap.Endpoints {
kubeEndpoint, err := convertToKube(endpoint, gloov1.EndpointCrd)
if err != nil {
return nil, err
}
resources = append(resources, *kubeEndpoint)
}

// gateway.solo.io resources
for _, gw := range snap.Gateways {
kubeGw, err := gatewayv1.GatewayCrd.KubeResource(gw)
if err != nil {
return nil, err
}
resources = append(resources, *kubeGw)
}

for _, vs := range snap.VirtualServices {
kubeVs, err := gatewayv1.VirtualServiceCrd.KubeResource(vs)
if err != nil {
return nil, err
}
resources = append(resources, *kubeVs)
}
for _, rt := range snap.RouteTables {
kubeRt, err := gatewayv1.RouteTableCrd.KubeResource(rt)
if err != nil {
return nil, err
}
resources = append(resources, *kubeRt)
}
for _, vho := range snap.VirtualHostOptions {
kubeVho, err := gatewayv1.VirtualHostOptionCrd.KubeResource(vho)
if err != nil {
return nil, err
}
resources = append(resources, *kubeVho)
}
for _, rto := range snap.RouteOptions {
kubeRto, err := gatewayv1.RouteOptionCrd.KubeResource(rto)
if err != nil {
return nil, err
}
resources = append(resources, *kubeRto)
}
for _, hgw := range snap.HttpGateways {
kubeHgw, err := gatewayv1.MatchableHttpGatewayCrd.KubeResource(hgw)
if err != nil {
return nil, err
}
resources = append(resources, *kubeHgw)
}
for _, tgw := range snap.TcpGateways {
kubeTgw, err := gatewayv1.MatchableTcpGatewayCrd.KubeResource(tgw)
if err != nil {
return nil, err
}
resources = append(resources, *kubeTgw)
}

// enterprise.gloo.solo.io resources
for _, ac := range snap.AuthConfigs {
kubeAc, err := extauthv1.AuthConfigCrd.KubeResource(ac)
if err != nil {
return nil, err
}
resources = append(resources, *kubeAc)
}

// ratelimit.solo.io resources
for _, rlc := range snap.Ratelimitconfigs {
kubeRlc, err := ratelimitv1alpha1.RateLimitConfigCrd.KubeResource(rlc)
if err != nil {
return nil, err
}
resources = append(resources, *kubeRlc)
}

// graphql.gloo.solo.io resources
for _, gqlApi := range snap.GraphqlApis {
kubeGqlApi, err := graphqlv1beta1.GraphQLApiCrd.KubeResource(gqlApi)
if err != nil {
return nil, err
}
resources = append(resources, *kubeGqlApi)
}

return resources, nil
}

// standalone func to convert Settings (which is not part of the ApiSnapshot)
// into a solo-kit Kubernetes resource
func settingsToKubeResource(settings *gloov1.Settings) (*crdv1.Resource, error) {
kubeSettings, err := gloov1.SettingsCrd.KubeResource(settings)
if err != nil {
return nil, err
}
return kubeSettings, nil
}

// This converts a solo-kit VersionedResource to a solo-kit Kubernetes resource. It mirrors the
// solo-kit [KubeResource](https://github.com/solo-io/solo-kit/blob/1baf6de465942dc5be44e7f28f0f739dcd0b967b/pkg/api/v1/clients/kube/crd/crd.go#L78)
// func, except that it accepts "fake" resources such as Endpoints, which don't implement
// [InputResource](https://github.com/solo-io/solo-kit/blob/1baf6de465942dc5be44e7f28f0f739dcd0b967b/pkg/api/v1/resources/resource_interface.go#L47)
// (don't have statuses).
func convertToKube(resource resources.VersionedResource, crd crd.Crd) (*crdv1.Resource, error) {
var spec crdv1.Spec

data, err := protoutils.MarshalMap(resource)
if err != nil {
return nil, err
}

delete(data, "metadata")
spec = data

return &crdv1.Resource{
TypeMeta: crd.TypeMeta(),
ObjectMeta: kubeutils.ToKubeMetaMaintainNamespace(resource.GetMetadata()),
Spec: &spec,
Status: crdv1.Status{},
}, nil
}
17 changes: 17 additions & 0 deletions projects/gloo/pkg/servers/iosnapshot/convert_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package iosnapshot

import (
. "github.com/onsi/ginkgo/v2"
v1snap "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/gloosnapshot"
"github.com/solo-io/gloo/test/gomega/assertions"
)

var _ = Describe("Convert", func() {

It("will fail if the ApiSnapshot has a new top level field", func() {
// This test checks whether the ApiSnapshot has a new top-level field.
// If the number of fields changes, it should be used as an indication that the
// `snapshotToKubeResources` function might need to be updated to support the new field.
assertions.ExpectNumFields(v1snap.ApiSnapshot{}, 16)
})
})
Loading
Loading