Skip to content

Commit

Permalink
feat: enable reporter for KIC 2.0 cli (#1261)
Browse files Browse the repository at this point in the history
  • Loading branch information
shaneutt authored May 3, 2021
1 parent 0c051bb commit 213396b
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 14 deletions.
3 changes: 2 additions & 1 deletion Dockerfile.railgun
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ COPY railgun/controllers/ railgun/controllers/
COPY railgun/manager/ railgun/manager/
COPY railgun/pkg/ railgun/pkg/
COPY railgun/main.go railgun/main.go
COPY railgun/internal/ railgun/internal/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager ./railgun/main.go
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager -ldflags "-s -w -X manager.Release=$TAG -X manager.Commit=$COMMIT -X manager.Repo=$REPO_INFO" ./railgun/main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
Expand Down
24 changes: 20 additions & 4 deletions railgun/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
KIND_CLUSTER_NAME ?= "integration-tests"
##@ Versioning

ifndef COMMIT
COMMIT := $(shell git rev-parse --short HEAD)
endif
REPO_INFO=$(shell git config --get remote.origin.url)

##@ Container Image Vars

# Image URL to use all building/pushing image targets
IMG ?= controller:latest
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
# TODO: investigate `go-kong` changes that would allow us to remove `allowDangerousTypes=true`.
# See: https://github.com/Kong/go-kong/issues/54
CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false,allowDangerousTypes=true"

##@ Testing Vars

KIND_CLUSTER_NAME ?= "integration-tests"

##@ Build Vars

CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false,allowDangerousTypes=true"
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
Expand Down Expand Up @@ -54,7 +68,10 @@ test: manifests generate fmt vet ## Run tests.
##@ Build

build: generate fmt vet ## Build manager binary.
go build -o bin/manager main.go
go build -a -o bin/manager -ldflags "-s -w \
-X github.com/kong/kubernetes-ingress-controller/railgun/manager.Release=$(TAG) \
-X github.com/kong/kubernetes-ingress-controller/railgun/manager.Commit=$(COMMIT) \
-X github.com/kong/kubernetes-ingress-controller/railgun/manager.Repo=$(REPO_INFO)" main.go

run: manifests generate fmt vet ## Run a controller from your host.
KONG_EXTERNAL_CONTROLLER=true go run ./main.go
Expand All @@ -77,7 +94,6 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/default | kubectl delete -f -


CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
controller-gen: ## Download controller-gen locally if necessary.
$(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1)
Expand Down
79 changes: 79 additions & 0 deletions railgun/internal/mgrutils/reports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package mgrutils

import (
"context"
"fmt"
"os"

"github.com/hashicorp/go-uuid"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"

"github.com/kong/kubernetes-ingress-controller/pkg/sendconfig"
"github.com/kong/kubernetes-ingress-controller/pkg/util"
)

// RunReport runs the anonymous data report and reports any errors that have occurred.
func RunReport(ctx context.Context, kubeCfg *rest.Config, kongCfg sendconfig.Kong, kicVersion string) error {
// if anonymous reports are enabled this helps provide Kong with insights about usage of the ingress controller
// which is non-sensitive and predominantly informs us of the controller and cluster versions in use.
// This data helps inform us what versions, features, e.t.c. end-users are actively using which helps to inform
// our prioritization of work and we appreciate when our end-users provide them, however if you do feel
// uncomfortable and would rather turn them off run the controller with the "--anonymous-reports false" flag.

// record the system hostname
hostname, err := os.Hostname()
if err != nil {
return fmt.Errorf("failed to fetch hostname: %w", err)
}

// create a universal unique identifer for this system
uuid, err := uuid.GenerateUUID()
if err != nil {
return fmt.Errorf("failed to generate a random uuid: %w", err)
}

// record the current Kubernetes server version
kc, err := kubernetes.NewForConfig(kubeCfg)
if err != nil {
return fmt.Errorf("could not create client-go for Kubernetes discovery: %w", err)
}
k8sVersion, err := kc.Discovery().ServerVersion()
if err != nil {
return fmt.Errorf("failed to fetch k8s api-server version: %w", err)
}

// gather versioning information from the kong client
root, err := kongCfg.Client.Root(ctx)
if err != nil {
return fmt.Errorf("failed to get Kong root config data: %w", err)
}
kongVersion, ok := root["version"].(string)
if !ok {
return fmt.Errorf("malformed Kong version found in Kong client root")
}
cfg, ok := root["configuration"].(map[string]interface{})
if !ok {
return fmt.Errorf("malformed Kong configuration found in Kong client root")
}
kongDB, ok := cfg["database"].(string)
if !ok {
return fmt.Errorf("malformed database configuration found in Kong client root")
}

// build the final report
info := util.Info{
KongVersion: kongVersion,
KICVersion: kicVersion,
KubernetesVersion: k8sVersion.String(),
Hostname: hostname,
ID: uuid,
KongDB: kongDB,
}

// run the reporter in the background
reporter := util.Reporter{Info: info}
go reporter.Run(ctx.Done())

return nil
}
49 changes: 40 additions & 9 deletions railgun/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import (
"reflect"

"github.com/kong/go-kong/kong"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/clientcmd"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/kong/kubernetes-ingress-controller/pkg/adminapi"
"github.com/kong/kubernetes-ingress-controller/pkg/annotations"
"github.com/kong/kubernetes-ingress-controller/pkg/sendconfig"
Expand All @@ -20,15 +30,24 @@ import (
kongctrl "github.com/kong/kubernetes-ingress-controller/railgun/controllers/configuration"
"github.com/kong/kubernetes-ingress-controller/railgun/controllers/corev1"
"github.com/kong/kubernetes-ingress-controller/railgun/internal/ctrlutils"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/clientcmd"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"github.com/kong/kubernetes-ingress-controller/railgun/internal/mgrutils"
)

var (
// Release returns the release version
// NOTE: the value of this is set at compile time using the -X flag for go tool link.
// See: "go doc cmd/link" for details, and "../Dockerfile.railgun" for invocation via "go build".
Release = "UNKNOWN"

// Repo returns the git repository URL
// NOTE: the value of this is set at compile time using the -X flag for go tool link.
// See: "go doc cmd/link" for details, and "../Dockerfile.railgun" for invocation via "go build".
Repo = "UNKNOWN"

// Commit returns the short sha from git
// NOTE: the value of this is set at compile time using the -X flag for go tool link.
// See: "go doc cmd/link" for details, and "../Dockerfile.railgun" for invocation via "go build".
Commit = "UNKNOWN"
)

// Config collects all configuration that the controller manager takes from the environment.
Expand All @@ -45,6 +64,7 @@ type Config struct {
Concurrency int
KubeconfigPath string
IngressClassName string
AnonymousReports bool

KongAdminAPIConfig adminapi.HTTPClientOpts

Expand Down Expand Up @@ -82,6 +102,7 @@ func MakeFlagSetFor(c *Config) *pflag.FlagSet {
flagSet.IntVar(&c.Concurrency, "kong-concurrency", 10, "TODO")
flagSet.StringVar(&c.KubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file.")
flagSet.StringVar(&c.IngressClassName, "ingress-class", annotations.DefaultIngressClass, `Name of the ingress class to route through this controller.`)
flagSet.BoolVar(&c.AnonymousReports, "anonymous-reports", true, `Send anonymized usage data to help improve Kong`)

flagSet.BoolVar(&c.KongAdminAPIConfig.TLSSkipVerify, "kong-admin-tls-skip-verify", false,
"Disable verification of TLS certificate of Kong's Admin endpoint.")
Expand Down Expand Up @@ -176,6 +197,7 @@ func (c *ControllerDef) MaybeSetupWithManager(mgr ctrl.Manager) error {
func Run(ctx context.Context, c *Config) error {
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&c.ZapOptions)))
setupLog := ctrl.Log.WithName("setup")
setupLog.Info("starting controller manager", "release", Release, "repo", Repo, "commit", Commit)

scheme := runtime.NewScheme()
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
Expand Down Expand Up @@ -414,6 +436,15 @@ func Run(ctx context.Context, c *Config) error {
return fmt.Errorf("unable to setup readyz: %w", err)
}

if c.AnonymousReports {
setupLog.Info("running anonymous reports")
if err := mgrutils.RunReport(ctx, kubeconfig, kongCFG, Release); err != nil {
setupLog.Error(err, "anonymous reporting failed")
}
} else {
setupLog.Info("anonymous reports disabled, skipping")
}

setupLog.Info("starting manager")
return mgr.Start(ctx)
}

0 comments on commit 213396b

Please sign in to comment.