Skip to content

Commit

Permalink
Add Installation Flags to Telemetry (#5586)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexFenlon authored May 22, 2024
1 parent 106890c commit 20fb00e
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cmd/nginx-ingress/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func main() {
fmt.Printf("NGINX Ingress Controller Version=%v Commit=%v Date=%v DirtyState=%v Arch=%v/%v Go=%v\n", version, commitHash, commitTime, dirtyBuild, runtime.GOOS, runtime.GOARCH, runtime.Version())

parseFlags()
parsedFlags := os.Args[1:]

config, kubeClient := createConfigAndKubeClient()

Expand Down Expand Up @@ -217,6 +218,7 @@ func main() {
TelemetryReportingEndpoint: telemetryEndpoint,
NICVersion: version,
DynamicWeightChangesReload: *enableDynamicWeightChangesReload,
InstallationFlags: parsedFlags,
}

lbc := k8s.NewLoadBalancerController(lbcInput)
Expand Down
1 change: 1 addition & 0 deletions docs/content/overview/product-telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ These are the data points collected and reported by NGINX Ingress Controller:
- **GlobalConfiguration** Represents the use of a GlobalConfiguration resource.
- **AppProtectVersion** The AppProtect version
- **IsPlus** Represents whether NGINX is Plus or OSS
- **InstallationFlags** List of command line arguments configured for NGINX Ingress Controller

## Opt out

Expand Down
2 changes: 2 additions & 0 deletions internal/k8s/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ type NewLoadBalancerControllerInput struct {
TelemetryReportingEndpoint string
NICVersion string
DynamicWeightChangesReload bool
InstallationFlags []string
}

// NewLoadBalancerController creates a controller
Expand Down Expand Up @@ -366,6 +367,7 @@ func NewLoadBalancerController(input NewLoadBalancerControllerInput) *LoadBalanc
K8sClientReader: input.KubeClient,
Version: input.NICVersion,
AppProtectVersion: input.AppProtectVersion,
InstallationFlags: input.InstallationFlags,
GlobalConfiguration: lbc.watchGlobalConfiguration,
Configurator: lbc.configurator,
SecretStore: lbc.secretStore,
Expand Down
5 changes: 5 additions & 0 deletions internal/telemetry/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ func (c *Collector) IsPlusEnabled() bool {
return c.Config.IsPlus
}

// InstallationFlags returns the list of all set flags
func (c *Collector) InstallationFlags() []string {
return c.Config.InstallationFlags
}

// lookupPlatform takes a string representing a K8s PlatformID
// retrieved from a cluster node and returns a string
// representing the platform name.
Expand Down
23 changes: 23 additions & 0 deletions internal/telemetry/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"testing"

"github.com/google/go-cmp/cmp"

"github.com/nginxinc/kubernetes-ingress/internal/telemetry"
appsV1 "k8s.io/api/apps/v1"
apiCoreV1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -436,6 +438,27 @@ func TestInstallationIDFailsOnMissingDaemonSet(t *testing.T) {
}
}

func TestGetInstallationFlags(t *testing.T) {
t.Parallel()

c, err := telemetry.NewCollector(
telemetry.CollectorConfig{
InstallationFlags: []string{
"-nginx-plus=true",
},
},
)
if err != nil {
t.Fatal(err)
}

got := c.InstallationFlags()
want := []string{"-nginx-plus=true"}
if !cmp.Equal(want, got) {
t.Error(cmp.Diff(want, got))
}
}

// newTestCollectorForClusterWithNodes returns a telemetry collector configured
// to simulate collecting data on a cluser with provided nodes.
func newTestCollectorForClusterWithNodes(t *testing.T, nodes ...runtime.Object) *telemetry.Collector {
Expand Down
8 changes: 8 additions & 0 deletions internal/telemetry/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ type CollectorConfig struct {

// IsPlus represents whether NGINX is Plus or OSS
IsPlus bool

// InstallationFlags represents the list of set flags managed by NIC
InstallationFlags []string
}

// NewCollector takes 0 or more options and creates a new TraceReporter.
Expand Down Expand Up @@ -141,6 +144,7 @@ func (c *Collector) Collect(ctx context.Context) {
IngressAnnotations: report.IngressAnnotations,
AppProtectVersion: report.AppProtectVersion,
IsPlus: report.IsPlus,
InstallationFlags: report.InstallationFlags,
},
}

Expand Down Expand Up @@ -183,6 +187,7 @@ type Report struct {
IngressAnnotations []string
AppProtectVersion string
IsPlus bool
InstallationFlags []string
}

// BuildReport takes context, collects telemetry data and builds the report.
Expand Down Expand Up @@ -255,6 +260,8 @@ func (c *Collector) BuildReport(ctx context.Context) (Report, error) {

isPlus := c.IsPlusEnabled()

installationFlags := c.InstallationFlags()

return Report{
Name: "NIC",
Version: c.Config.Version,
Expand Down Expand Up @@ -284,5 +291,6 @@ func (c *Collector) BuildReport(ctx context.Context) (Report, error) {
IngressAnnotations: ingressAnnotations,
AppProtectVersion: appProtectVersion,
IsPlus: isPlus,
InstallationFlags: installationFlags,
}, err
}
97 changes: 97 additions & 0 deletions internal/telemetry/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,103 @@ func TestCollectInvalidAppProtectVersion(t *testing.T) {
}
}

func TestCollectInstallationFlags(t *testing.T) {
t.Parallel()

testCases := []struct {
name string
setFlags []string
wantFlags []string
}{
{
name: "first flag",
setFlags: []string{
"nginx-plus=true",
},
wantFlags: []string{
"nginx-plus=true",
},
},
{
name: "second flag",
setFlags: []string{
"-v=3",
},
wantFlags: []string{
"-v=3",
},
},
{
name: "multiple flags",
setFlags: []string{
"nginx-plus=true",
"-v=3",
},
wantFlags: []string{
"nginx-plus=true",
"-v=3",
},
},
{
name: "no flags",
setFlags: []string{},
wantFlags: []string{},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
buf := &bytes.Buffer{}
exp := &telemetry.StdoutExporter{Endpoint: buf}

configurator := newConfigurator(t)

cfg := telemetry.CollectorConfig{
Configurator: configurator,
K8sClientReader: newTestClientset(node1, kubeNS),
Version: telemetryNICData.ProjectVersion,
InstallationFlags: tc.setFlags,
}

c, err := telemetry.NewCollector(cfg, telemetry.WithExporter(exp))
if err != nil {
t.Fatal(err)
}
c.Collect(context.Background())

telData := tel.Data{
ProjectName: telemetryNICData.ProjectName,
ProjectVersion: telemetryNICData.ProjectVersion,
ProjectArchitecture: telemetryNICData.ProjectArchitecture,
ClusterNodeCount: 1,
ClusterID: telemetryNICData.ClusterID,
ClusterVersion: telemetryNICData.ClusterVersion,
ClusterPlatform: "other",
}

nicResourceCounts := telemetry.NICResourceCounts{
VirtualServers: 0,
VirtualServerRoutes: 0,
TransportServers: 0,
Ingresses: 0,
InstallationFlags: tc.wantFlags,
}

td := telemetry.Data{
Data: telData,
NICResourceCounts: nicResourceCounts,
}

want := fmt.Sprintf("%+v", &td)

got := buf.String()
if !cmp.Equal(want, got) {
t.Error(cmp.Diff(got, want))
}
})
}
}

func TestCountVirtualServers(t *testing.T) {
t.Parallel()

Expand Down
3 changes: 3 additions & 0 deletions internal/telemetry/data.avdl
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,8 @@ It is the UID of the `kube-system` Namespace. */
/** IsPlus represents whether NGINX is Plus or OSS */
boolean? IsPlus = null;

/** InstallationFlags is the list of command line arguments configured for NGINX Ingress Controller */
union {null, array<string>} InstallationFlags = null;

}
}
2 changes: 2 additions & 0 deletions internal/telemetry/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,6 @@ type NICResourceCounts struct {
AppProtectVersion string
// IsPlus represents whether NGINX is Plus or OSS
IsPlus bool
// InstallationFlags is the list of command line arguments configured for NGINX Ingress Controller
InstallationFlags []string
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func (d *NICResourceCounts) Attributes() []attribute.KeyValue {
attrs = append(attrs, attribute.StringSlice("IngressAnnotations", d.IngressAnnotations))
attrs = append(attrs, attribute.String("AppProtectVersion", d.AppProtectVersion))
attrs = append(attrs, attribute.Bool("IsPlus", d.IsPlus))
attrs = append(attrs, attribute.StringSlice("InstallationFlags", d.InstallationFlags))

return attrs
}
Expand Down

0 comments on commit 20fb00e

Please sign in to comment.