Skip to content

Commit

Permalink
feat(konnect): add object counters for Konnect entities
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalek committed Oct 8, 2024
1 parent fc9e3c1 commit dcad62a
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 8 deletions.
1 change: 0 additions & 1 deletion api/v1alpha1/kongplugin_installation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ type KongPluginInstallationList struct {
// KongPluginInstallationSpec provides the information necessary to retrieve and install a Kong custom plugin.
// +apireference:kgo:include
type KongPluginInstallationSpec struct {

// The image is an OCI image URL for a packaged custom Kong plugin.
//
// +kubebuilder:validation:Required
Expand Down
43 changes: 43 additions & 0 deletions internal/telemetry/provider_objectcounter_konnect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package telemetry

import (
"github.com/kong/kubernetes-telemetry/pkg/provider"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"

"github.com/kong/gateway-operator/controller/konnect/constraints"
)

// NewObjectCountProvider creates a provider for number of objects in the cluster.
func NewObjectCountProvider[
T constraints.SupportedKonnectEntityType,
TEnt constraints.EntityType[T],
](dyn dynamic.Interface, restMapper meta.RESTMapper, group string, version string) (provider.Provider, error) {
kind := constraints.EntityTypeName[T]()
restMapping, err := restMapper.RESTMapping(
schema.GroupKind{
Group: group,
Kind: kind,
},

version,
)
if err != nil {
return nil, err
}

gvr := schema.GroupVersionResource{
Group: restMapping.Resource.Group,
Version: restMapping.Resource.Version,
Resource: restMapping.Resource.Resource,
}

return provider.NewK8sObjectCountProviderWithRESTMapper(
restMapping.Resource.Resource,
provider.Kind(kind),
dyn,
gvr,
restMapper,
)
}
66 changes: 66 additions & 0 deletions internal/telemetry/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,23 @@ import (
"github.com/kong/kubernetes-telemetry/pkg/serializers"
"github.com/kong/kubernetes-telemetry/pkg/telemetry"
"github.com/kong/kubernetes-telemetry/pkg/types"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"

operatorv1alpha1 "github.com/kong/gateway-operator/api/v1alpha1"
operatorv1beta1 "github.com/kong/gateway-operator/api/v1beta1"
"github.com/kong/gateway-operator/controller/konnect/constraints"
"github.com/kong/gateway-operator/modules/manager/metadata"
"github.com/kong/gateway-operator/modules/manager/scheme"
k8sutils "github.com/kong/gateway-operator/pkg/utils/kubernetes"

configurationv1 "github.com/kong/kubernetes-configuration/api/configuration/v1"
configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1"
configurationv1beta1 "github.com/kong/kubernetes-configuration/api/configuration/v1beta1"
konnectv1alpha1 "github.com/kong/kubernetes-configuration/api/konnect/v1alpha1"
)

const (
Expand Down Expand Up @@ -211,6 +218,41 @@ func createManager(
}
}

if cfg.KonnectControllerEnabled {
{
group, version := configurationv1.GroupVersion.Group, configurationv1.GroupVersion.Version
AddObjectCountProviderOrLog[configurationv1.KongConsumer](w, dyn, cl.RESTMapper(), log, group, version)
}
{
group, version := configurationv1beta1.GroupVersion.Group, configurationv1beta1.GroupVersion.Version
AddObjectCountProviderOrLog[configurationv1beta1.KongConsumerGroup](w, dyn, cl.RESTMapper(), log, group, version)
}
{
group, version := configurationv1alpha1.GroupVersion.Group, configurationv1alpha1.GroupVersion.Version
AddObjectCountProviderOrLog[configurationv1alpha1.KongRoute](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongService](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongCredentialACL](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongCredentialJWT](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongCredentialHMAC](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongCredentialAPIKey](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongCredentialBasicAuth](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongSNI](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongVault](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongCertificate](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongCACertificate](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongDataPlaneClientCertificate](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongKey](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongKeySet](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongPluginBinding](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongTarget](w, dyn, cl.RESTMapper(), log, group, version)
AddObjectCountProviderOrLog[configurationv1alpha1.KongUpstream](w, dyn, cl.RESTMapper(), log, group, version)
}
{
group, version := konnectv1alpha1.GroupVersion.Group, konnectv1alpha1.GroupVersion.Version
AddObjectCountProviderOrLog[konnectv1alpha1.KonnectGatewayControlPlane](w, dyn, cl.RESTMapper(), log, group, version)
}
}

m.AddWorkflow(w)
}
// Add state workflow
Expand Down Expand Up @@ -243,3 +285,27 @@ func createManager(

return m, nil
}

// AddObjectCountProviderOrLog adds a provider for counting objects of the specified
// type to the workflow.
// If this fails to create the provider, it logs the error on Info level (as this
// is not a critical operation).
func AddObjectCountProviderOrLog[
T constraints.SupportedKonnectEntityType,
TEnt constraints.EntityType[T],
](
w telemetry.Workflow,
dyn dynamic.Interface,
restMapper meta.RESTMapper,
log logr.Logger,
group string,
version string,
) {
p, err := NewObjectCountProvider[T, TEnt](dyn, restMapper, group, version)
if err != nil {
log.Info("failed to create object provider", "error", err, "kind", constraints.EntityTypeName[T]())
return
}

w.AddProvider(p)
}
111 changes: 105 additions & 6 deletions internal/telemetry/telemetry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,23 @@ import (
operatorv1alpha1 "github.com/kong/gateway-operator/api/v1alpha1"
operatorv1beta1 "github.com/kong/gateway-operator/api/v1beta1"
"github.com/kong/gateway-operator/modules/manager/metadata"

configurationv1 "github.com/kong/kubernetes-configuration/api/configuration/v1"
configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1"
configurationv1beta1 "github.com/kong/kubernetes-configuration/api/configuration/v1beta1"
konnectv1alpha1 "github.com/kong/kubernetes-configuration/api/konnect/v1alpha1"
)

func prepareScheme(t *testing.T) *runtime.Scheme {
scheme := runtime.NewScheme()
require.NoError(t, testk8sclient.AddToScheme(scheme))
require.NoError(t, operatorv1beta1.AddToScheme(scheme))
require.NoError(t, operatorv1alpha1.AddToScheme(scheme))
require.NoError(t, configurationv1alpha1.AddToScheme(scheme))
require.NoError(t, configurationv1beta1.AddToScheme(scheme))
require.NoError(t, configurationv1.AddToScheme(scheme))
require.NoError(t, konnectv1alpha1.AddToScheme(scheme))

return scheme
}

Expand Down Expand Up @@ -71,6 +81,38 @@ func createRESTMapper() meta.RESTMapper {
},
meta.RESTScopeNamespace,
)

restMapper.Add(schema.GroupVersionKind{
Group: configurationv1alpha1.SchemeGroupVersion.Group,
Version: configurationv1alpha1.SchemeGroupVersion.Version,
Kind: configurationv1alpha1.KongRoute{}.GetTypeName(),
}, meta.RESTScopeNamespace)
restMapper.Add(schema.GroupVersionKind{
Group: configurationv1alpha1.SchemeGroupVersion.Group,
Version: configurationv1alpha1.SchemeGroupVersion.Version,
Kind: configurationv1alpha1.KongService{}.GetTypeName(),
}, meta.RESTScopeNamespace)
restMapper.Add(schema.GroupVersionKind{
Group: configurationv1alpha1.SchemeGroupVersion.Group,
Version: configurationv1alpha1.SchemeGroupVersion.Version,
Kind: configurationv1alpha1.KongSNI{}.GetTypeName(),
}, meta.RESTScopeNamespace)
restMapper.Add(schema.GroupVersionKind{
Group: configurationv1.SchemeGroupVersion.Group,
Version: configurationv1.SchemeGroupVersion.Version,
Kind: configurationv1.KongConsumer{}.GetTypeName(),
}, meta.RESTScopeNamespace)
restMapper.Add(schema.GroupVersionKind{
Group: configurationv1beta1.SchemeGroupVersion.Group,
Version: configurationv1beta1.SchemeGroupVersion.Version,
Kind: configurationv1beta1.KongConsumerGroup{}.GetTypeName(),
}, meta.RESTScopeNamespace)
restMapper.Add(schema.GroupVersionKind{
Group: konnectv1alpha1.SchemeGroupVersion.Group,
Version: konnectv1alpha1.SchemeGroupVersion.Version,
Kind: konnectv1alpha1.KonnectGatewayControlPlane{}.GetTypeName(),
}, meta.RESTScopeNamespace)

return restMapper
}

Expand Down Expand Up @@ -117,7 +159,7 @@ func TestCreateManager(t *testing.T) {
"controller_dataplane_bg_enabled=false",
"controller_controlplane_enabled=false",
"controller_gateway_enabled=false",
"controller_konnect_enabled=false",
"controller_konnect_enabled=true",
"controller_kongplugininstallation_enabled=false",
},
},
Expand Down Expand Up @@ -153,7 +195,7 @@ func TestCreateManager(t *testing.T) {
"controller_dataplane_bg_enabled=false",
"controller_controlplane_enabled=false",
"controller_gateway_enabled=false",
"controller_konnect_enabled=false",
"controller_konnect_enabled=true",
"controller_kongplugininstallation_enabled=false",
},
},
Expand Down Expand Up @@ -235,7 +277,7 @@ func TestCreateManager(t *testing.T) {
"controller_dataplane_bg_enabled=false",
"controller_controlplane_enabled=false",
"controller_gateway_enabled=false",
"controller_konnect_enabled=false",
"controller_konnect_enabled=true",
"controller_kongplugininstallation_enabled=false",
},
},
Expand Down Expand Up @@ -290,7 +332,7 @@ func TestCreateManager(t *testing.T) {
"controller_dataplane_bg_enabled=false",
"controller_controlplane_enabled=false",
"controller_gateway_enabled=false",
"controller_konnect_enabled=false",
"controller_konnect_enabled=true",
"controller_kongplugininstallation_enabled=false",
},
},
Expand Down Expand Up @@ -324,7 +366,7 @@ func TestCreateManager(t *testing.T) {
"controller_dataplane_bg_enabled=false",
"controller_controlplane_enabled=false",
"controller_gateway_enabled=false",
"controller_konnect_enabled=false",
"controller_konnect_enabled=true",
"controller_kongplugininstallation_enabled=false",
},
},
Expand Down Expand Up @@ -359,14 +401,70 @@ func TestCreateManager(t *testing.T) {
"controller_dataplane_bg_enabled=false",
"controller_controlplane_enabled=false",
"controller_gateway_enabled=false",
"controller_konnect_enabled=false",
"controller_konnect_enabled=true",
"controller_kongplugininstallation_enabled=false",
},
},
{
name: "Konnect entities",
objects: []runtime.Object{
&configurationv1alpha1.KongService{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kong",
Name: "kongservice-1",
},
},
&configurationv1alpha1.KongService{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kong",
Name: "kongservice-2",
},
},
&configurationv1alpha1.KongRoute{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kong",
Name: "kongroute-1",
},
},
&configurationv1.KongConsumer{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kong",
Name: "kongconsumer-1",
},
},
&configurationv1beta1.KongConsumerGroup{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kong",
Name: "kongconsumergroup-1",
},
},
&configurationv1alpha1.KongSNI{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kong",
Name: "kongroute-1",
},
},
},
expectedReportParts: []string{
"signal=test-signal",
"k8s_kongroutes_count=1",
"k8s_kongservices_count=2",
"k8s_kongsnis_count=1",
"k8s_kongconsumers_count=1",
"k8s_kongconsumergroups_count=1",
"controller_dataplane_enabled=true",
"controller_dataplane_bg_enabled=false",
"controller_controlplane_enabled=false",
"controller_gateway_enabled=false",
"controller_konnect_enabled=true",
"controller_kongplugininstallation_enabled=false",
},
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
// scheme := scheme.Get() // prepareScheme(t)
scheme := prepareScheme(t)
k8sclient := testk8sclient.NewSimpleClientset()

Expand Down Expand Up @@ -394,6 +492,7 @@ func TestCreateManager(t *testing.T) {
}
cfg := Config{
DataPlaneControllerEnabled: true,
KonnectControllerEnabled: true,
}

m, err := createManager(
Expand Down
8 changes: 7 additions & 1 deletion modules/manager/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,13 @@ func (m *caManager) maybeCreateCACertificate(ctx context.Context) error {
// a cleanup function and an error.
// The caller is responsible to call the returned function - when the returned
// error is not nil - to stop the reports sending.
func setupAnonymousReports(ctx context.Context, restCfg *rest.Config, logger logr.Logger, metadata metadata.Info, cfg Config) (func(), error) {
func setupAnonymousReports(
ctx context.Context,
restCfg *rest.Config,
logger logr.Logger,
metadata metadata.Info,
cfg Config,
) (func(), error) {
logger.Info("starting anonymous reports")

// NOTE: this is needed to break the import cycle between telemetry and manager packages.
Expand Down

0 comments on commit dcad62a

Please sign in to comment.