diff --git a/client/fingerprint/consul.go b/client/fingerprint/consul.go index 183f39a79d0..e37ffb1a888 100644 --- a/client/fingerprint/consul.go +++ b/client/fingerprint/consul.go @@ -101,13 +101,16 @@ func (f *ConsulFingerprint) initialize(req *FingerprintRequest) error { } f.extractors = map[string]consulExtractor{ - "consul.server": f.server, - "consul.version": f.version, - "consul.sku": f.sku, - "consul.revision": f.revision, - "unique.consul.name": f.name, - "consul.datacenter": f.dc, - "consul.segment": f.segment, + "consul.server": f.server, + "consul.version": f.version, + "consul.sku": f.sku, + "consul.revision": f.revision, + "unique.consul.name": f.name, + "consul.datacenter": f.dc, + "consul.segment": f.segment, + "consul.connect": f.connect, + "consul.grpc": f.grpc, + "consul.ft.namespaces": f.namespaces, } } @@ -190,3 +193,39 @@ func (f *ConsulFingerprint) segment(info consulInfo) (string, bool) { s, ok := tags["segment"].(string) return s, ok } + +func (f *ConsulFingerprint) connect(info consulInfo) (string, bool) { + c, ok := info["DebugConfig"]["ConnectEnabled"].(bool) + return strconv.FormatBool(c), ok +} + +func (f *ConsulFingerprint) grpc(info consulInfo) (string, bool) { + p, ok := info["DebugConfig"]["GRPCPort"].(float64) + return fmt.Sprintf("%d", int(p)), ok +} + +func (f *ConsulFingerprint) namespaces(info consulInfo) (string, bool) { + return f.feature("Namespaces", info) +} + +// possible values as of v1.9.5+ent: +// Automated Backups, Automated Upgrades, Enhanced Read Scalability, +// Network Segments, Redundancy Zone, Advanced Network Federation, +// Namespaces, SSO, Audit Logging +func (f *ConsulFingerprint) feature(name string, info consulInfo) (string, bool) { + lic, licOK := info["Stats"]["license"].(map[string]interface{}) + if !licOK { + return "", false + } + + features, exists := lic["features"].(string) + if !exists { + return "", false + } + + if !strings.Contains(features, name) { + return "", false + } + + return "true", true +} diff --git a/client/fingerprint/consul_test.go b/client/fingerprint/consul_test.go index 5e3c40930b6..e5eda50b292 100644 --- a/client/fingerprint/consul_test.go +++ b/client/fingerprint/consul_test.go @@ -260,10 +260,105 @@ func TestConsulFingerprint_segment(t *testing.T) { }) } -func TestConsulFingerprint_Fingerprint(t *testing.T) { +func TestConsulFingerprint_connect(t *testing.T) { + t.Parallel() + + fp := newConsulFingerPrint(t) + + t.Run("connect enabled", func(t *testing.T) { + s, ok := fp.connect(consulInfo{ + "DebugConfig": {"ConnectEnabled": true}, + }) + require.True(t, ok) + require.Equal(t, "true", s) + }) + + t.Run("connect not enabled", func(t *testing.T) { + s, ok := fp.connect(consulInfo{ + "DebugConfig": {"ConnectEnabled": false}, + }) + require.True(t, ok) + require.Equal(t, "false", s) + }) + + t.Run("connect missing", func(t *testing.T) { + _, ok := fp.connect(consulInfo{ + "DebugConfig": {}, + }) + require.False(t, ok) + }) +} + +func TestConsulFingerprint_grpc(t *testing.T) { + t.Parallel() + + fp := newConsulFingerPrint(t) + + t.Run("grpc set", func(t *testing.T) { + s, ok := fp.grpc(consulInfo{ + "DebugConfig": {"GRPCPort": 8502.0}, // JSON numbers are floats + }) + require.True(t, ok) + require.Equal(t, "8502", s) + }) + + t.Run("grpc disabled", func(t *testing.T) { + s, ok := fp.grpc(consulInfo{ + "DebugConfig": {"GRPCPort": -1.0}, // JSON numbers are floats + }) + require.True(t, ok) + require.Equal(t, "-1", s) + }) + + t.Run("grpc missing", func(t *testing.T) { + _, ok := fp.grpc(consulInfo{ + "DebugConfig": {}, + }) + require.False(t, ok) + }) + +} + +func TestConsulFingerprint_namespaces(t *testing.T) { + t.Parallel() + + fp := newConsulFingerPrint(t) + + t.Run("supports namespaces", func(t *testing.T) { + s, ok := fp.namespaces(consulInfo{ + "Stats": {"license": map[string]interface{}{"features": "Automated Backups, Automated Upgrades, Enhanced Read Scalability, Network Segments, Redundancy Zone, Advanced Network Federation, Namespaces, SSO, Audit Logging"}}, + }) + require.True(t, ok) + require.Equal(t, "true", s) + }) + + t.Run("no namespaces", func(t *testing.T) { + _, ok := fp.namespaces(consulInfo{ + "Stats": {"license": map[string]interface{}{"features": "Automated Backups, Automated Upgrades, Enhanced Read Scalability, Network Segments, Redundancy Zone, Advanced Network Federation, SSO, Audit Logging"}}, + }) + require.False(t, ok) + }) + + t.Run("stats missing", func(t *testing.T) { + _, ok := fp.namespaces(consulInfo{}) + require.False(t, ok) + }) + + t.Run("license missing", func(t *testing.T) { + _, ok := fp.namespaces(consulInfo{"Stats": {}}) + require.False(t, ok) + }) + + t.Run("features missing", func(t *testing.T) { + _, ok := fp.namespaces(consulInfo{"Stats": {"license": map[string]interface{}{}}}) + require.False(t, ok) + }) +} + +func TestConsulFingerprint_Fingerprint_oss(t *testing.T) { cf := newConsulFingerPrint(t) - ts, cfg := fakeConsul(fakeConsulPayload(t, "test_fixtures/consul/agent_self.json")) + ts, cfg := fakeConsul(fakeConsulPayload(t, "test_fixtures/consul/agent_self_oss.json")) defer ts.Close() node := &structs.Node{Attributes: make(map[string]string)} @@ -282,6 +377,8 @@ func TestConsulFingerprint_Fingerprint(t *testing.T) { "consul.server": "true", "consul.sku": "oss", "consul.version": "1.9.5", + "consul.connect": "true", + "consul.grpc": "8502", "unique.consul.name": "HAL9000", }, resp.Attributes) require.True(t, resp.Detected) @@ -298,19 +395,24 @@ func TestConsulFingerprint_Fingerprint(t *testing.T) { node.Attributes["consul.server"] = "foo" node.Attributes["consul.sku"] = "foo" node.Attributes["consul.version"] = "foo" + node.Attributes["consul.connect"] = "foo" + node.Attributes["connect.grpc"] = "foo" node.Attributes["unique.consul.name"] = "foo" // execute second query with error err2 := cf.Fingerprint(&FingerprintRequest{Config: cfg, Node: node}, &resp2) require.NoError(t, err2) // does not return error require.Equal(t, map[string]string{ // attributes set empty - "consul.datacenter": "", - "consul.revision": "", - "consul.segment": "", - "consul.server": "", - "consul.sku": "", - "consul.version": "", - "unique.consul.name": "", + "consul.datacenter": "", + "consul.revision": "", + "consul.segment": "", + "consul.server": "", + "consul.sku": "", + "consul.version": "", + "unique.consul.name": "", + "consul.connect": "", + "consul.grpc": "", + "consul.ft.namespaces": "", }, resp2.Attributes) require.True(t, resp.Detected) // never downgrade @@ -328,6 +430,8 @@ func TestConsulFingerprint_Fingerprint(t *testing.T) { "consul.server": "true", "consul.sku": "oss", "consul.version": "1.9.5", + "consul.connect": "true", + "consul.grpc": "8502", "unique.consul.name": "HAL9000", }, resp3.Attributes) @@ -335,3 +439,91 @@ func TestConsulFingerprint_Fingerprint(t *testing.T) { require.Equal(t, consulAvailable, cf.lastState) require.True(t, resp.Detected) } + +func TestConsulFingerprint_Fingerprint_ent(t *testing.T) { + cf := newConsulFingerPrint(t) + + ts, cfg := fakeConsul(fakeConsulPayload(t, "test_fixtures/consul/agent_self_ent.json")) + defer ts.Close() + + node := &structs.Node{Attributes: make(map[string]string)} + + // consul not available before first run + require.Equal(t, consulUnavailable, cf.lastState) + + // execute first query with good response + var resp FingerprintResponse + err := cf.Fingerprint(&FingerprintRequest{Config: cfg, Node: node}, &resp) + require.NoError(t, err) + require.Equal(t, map[string]string{ + "consul.datacenter": "dc1", + "consul.revision": "22ce6c6ad", + "consul.segment": "seg1", + "consul.server": "true", + "consul.sku": "ent", + "consul.version": "1.9.5+ent", + "consul.ft.namespaces": "true", + "consul.connect": "true", + "consul.grpc": "8502", + "unique.consul.name": "HAL9000", + }, resp.Attributes) + require.True(t, resp.Detected) + + // consul now available + require.Equal(t, consulAvailable, cf.lastState) + + var resp2 FingerprintResponse + + // pretend attributes set for failing request + node.Attributes["consul.datacenter"] = "foo" + node.Attributes["consul.revision"] = "foo" + node.Attributes["consul.segment"] = "foo" + node.Attributes["consul.server"] = "foo" + node.Attributes["consul.sku"] = "foo" + node.Attributes["consul.version"] = "foo" + node.Attributes["consul.ft.namespaces"] = "foo" + node.Attributes["consul.connect"] = "foo" + node.Attributes["connect.grpc"] = "foo" + node.Attributes["unique.consul.name"] = "foo" + + // execute second query with error + err2 := cf.Fingerprint(&FingerprintRequest{Config: cfg, Node: node}, &resp2) + require.NoError(t, err2) // does not return error + require.Equal(t, map[string]string{ // attributes set empty + "consul.datacenter": "", + "consul.revision": "", + "consul.segment": "", + "consul.server": "", + "consul.sku": "", + "consul.version": "", + "consul.ft.namespaces": "", + "consul.connect": "", + "consul.grpc": "", + "unique.consul.name": "", + }, resp2.Attributes) + require.True(t, resp.Detected) // never downgrade + + // consul no longer available + require.Equal(t, consulUnavailable, cf.lastState) + + // execute third query no error + var resp3 FingerprintResponse + err3 := cf.Fingerprint(&FingerprintRequest{Config: cfg, Node: node}, &resp3) + require.NoError(t, err3) + require.Equal(t, map[string]string{ + "consul.datacenter": "dc1", + "consul.revision": "22ce6c6ad", + "consul.segment": "seg1", + "consul.server": "true", + "consul.sku": "ent", + "consul.version": "1.9.5+ent", + "consul.ft.namespaces": "true", + "consul.connect": "true", + "consul.grpc": "8502", + "unique.consul.name": "HAL9000", + }, resp3.Attributes) + + // consul now available again + require.Equal(t, consulAvailable, cf.lastState) + require.True(t, resp.Detected) +} diff --git a/client/fingerprint/test_fixtures/consul/agent_self_ent.json b/client/fingerprint/test_fixtures/consul/agent_self_ent.json new file mode 100644 index 00000000000..c045688cc23 --- /dev/null +++ b/client/fingerprint/test_fixtures/consul/agent_self_ent.json @@ -0,0 +1,502 @@ +{ + "Config": { + "Datacenter": "dc1", + "NodeName": "HAL9000", + "NodeID": "39588353-8c00-d756-ce83-9ee70bfa5b3a", + "Revision": "22ce6c6ad", + "Server": true, + "Version": "1.9.5+ent" + }, + "DebugConfig": { + "ACLDatacenter": "dc1", + "ACLDefaultPolicy": "allow", + "ACLDisabledTTL": "2m0s", + "ACLDownPolicy": "extend-cache", + "ACLEnableKeyListPolicy": false, + "ACLMasterToken": "hidden", + "ACLPolicyTTL": "30s", + "ACLRoleTTL": "0s", + "ACLTokenReplication": false, + "ACLTokenTTL": "30s", + "ACLTokens": { + "ACLAgentMasterToken": "hidden", + "ACLAgentToken": "hidden", + "ACLDefaultToken": "hidden", + "ACLReplicationToken": "hidden", + "DataDir": "", + "EnablePersistence": false, + "EnterpriseConfig": { + "ACLServiceProviderTokens": [] + } + }, + "ACLsEnabled": false, + "AEInterval": "1m0s", + "AdvertiseAddrLAN": "127.0.0.1", + "AdvertiseAddrWAN": "127.0.0.1", + "AdvertiseReconnectTimeout": "0s", + "AllowWriteHTTPFrom": [], + "AutoConfig": { + "Authorizer": { + "AllowReuse": false, + "AuthMethod": { + "ACLAuthMethodEnterpriseFields": { + "NamespaceRules": [] + }, + "Config": { + "BoundAudiences": null, + "BoundIssuer": "", + "ClaimMappings": null, + "ClockSkewLeeway": 0, + "ExpirationLeeway": 0, + "JWKSCACert": "", + "JWKSURL": "", + "JWTSupportedAlgs": null, + "JWTValidationPubKeys": null, + "ListClaimMappings": null, + "NotBeforeLeeway": 0, + "OIDCDiscoveryCACert": "", + "OIDCDiscoveryURL": "" + }, + "Description": "", + "DisplayName": "", + "EnterpriseMeta": { + "Namespace": "default" + }, + "MaxTokenTTL": "0s", + "Name": "Auto Config Authorizer", + "RaftIndex": { + "CreateIndex": 0, + "ModifyIndex": 0 + }, + "TokenLocality": "", + "Type": "jwt" + }, + "ClaimAssertions": [], + "Enabled": false + }, + "DNSSANs": [], + "Enabled": false, + "IPSANs": [], + "IntroToken": "hidden", + "IntroTokenFile": "", + "ServerAddresses": [] + }, + "AutoEncryptAllowTLS": false, + "AutoEncryptDNSSAN": [], + "AutoEncryptIPSAN": [], + "AutoEncryptTLS": false, + "AutopilotCleanupDeadServers": true, + "AutopilotDisableUpgradeMigration": false, + "AutopilotLastContactThreshold": "200ms", + "AutopilotMaxTrailingLogs": 250, + "AutopilotMinQuorum": 0, + "AutopilotRedundancyZoneTag": "", + "AutopilotServerStabilizationTime": "10s", + "AutopilotUpgradeVersionTag": "", + "BindAddr": "127.0.0.1", + "Bootstrap": false, + "BootstrapExpect": 0, + "CAFile": "", + "CAPath": "", + "Cache": { + "EntryFetchMaxBurst": 2, + "EntryFetchRate": 1.7976931348623157e+308, + "Logger": null + }, + "CertFile": "", + "CheckDeregisterIntervalMin": "1m0s", + "CheckOutputMaxSize": 4096, + "CheckReapInterval": "30s", + "CheckUpdateInterval": "5m0s", + "Checks": [], + "ClientAddrs": [ + "127.0.0.1" + ], + "ConfigEntryBootstrap": [], + "ConnectCAConfig": {}, + "ConnectCAProvider": "", + "ConnectEnabled": true, + "ConnectMeshGatewayWANFederationEnabled": false, + "ConnectSidecarMaxPort": 21255, + "ConnectSidecarMinPort": 21000, + "ConnectTestCALeafRootChangeSpread": "0s", + "ConsulCoordinateUpdateBatchSize": 128, + "ConsulCoordinateUpdateMaxBatches": 5, + "ConsulCoordinateUpdatePeriod": "100ms", + "ConsulRaftElectionTimeout": "52ms", + "ConsulRaftHeartbeatTimeout": "35ms", + "ConsulRaftLeaderLeaseTimeout": "20ms", + "ConsulServerHealthInterval": "10ms", + "DNSARecordLimit": 0, + "DNSAddrs": [ + "tcp://127.0.0.1:8600", + "udp://127.0.0.1:8600" + ], + "DNSAllowStale": true, + "DNSAltDomain": "", + "DNSCacheMaxAge": "0s", + "DNSDisableCompression": false, + "DNSDomain": "consul.", + "DNSEnableTruncate": false, + "DNSMaxStale": "87600h0m0s", + "DNSNodeMetaTXT": true, + "DNSNodeTTL": "0s", + "DNSOnlyPassing": false, + "DNSPort": 8600, + "DNSRecursorTimeout": "2s", + "DNSRecursors": [], + "DNSSOA": { + "Expire": 86400, + "Minttl": 0, + "Refresh": 3600, + "Retry": 600 + }, + "DNSServiceTTL": {}, + "DNSUDPAnswerLimit": 3, + "DNSUseCache": false, + "DataDir": "", + "Datacenter": "dc1", + "DefaultQueryTime": "5m0s", + "DevMode": true, + "DisableAnonymousSignature": true, + "DisableCoordinates": false, + "DisableHTTPUnprintableCharFilter": false, + "DisableHostNodeID": true, + "DisableKeyringFile": true, + "DisableRemoteExec": true, + "DisableUpdateCheck": true, + "DiscardCheckOutput": false, + "DiscoveryMaxStale": "0s", + "EnableAgentTLSForChecks": false, + "EnableCentralServiceConfig": true, + "EnableDebug": true, + "EnableLocalScriptChecks": false, + "EnableRemoteScriptChecks": false, + "EncryptKey": "hidden", + "EncryptVerifyIncoming": true, + "EncryptVerifyOutgoing": true, + "EnterpriseRuntimeConfig": { + "ACLMSPDisableBootstrap": false, + "AuditEnabled": false, + "AuditSinks": [], + "DNSPreferNamespace": false + }, + "ExposeMaxPort": 21755, + "ExposeMinPort": 21500, + "GRPCAddrs": [ + "tcp://127.0.0.1:8502" + ], + "GRPCPort": 8502, + "GossipLANGossipInterval": "100ms", + "GossipLANGossipNodes": 3, + "GossipLANProbeInterval": "100ms", + "GossipLANProbeTimeout": "100ms", + "GossipLANRetransmitMult": 4, + "GossipLANSuspicionMult": 3, + "GossipWANGossipInterval": "100ms", + "GossipWANGossipNodes": 3, + "GossipWANProbeInterval": "100ms", + "GossipWANProbeTimeout": "100ms", + "GossipWANRetransmitMult": 4, + "GossipWANSuspicionMult": 3, + "HTTPAddrs": [ + "tcp://127.0.0.1:8500" + ], + "HTTPBlockEndpoints": [], + "HTTPMaxConnsPerClient": 200, + "HTTPMaxHeaderBytes": 0, + "HTTPPort": 8500, + "HTTPResponseHeaders": {}, + "HTTPSAddrs": [], + "HTTPSHandshakeTimeout": "5s", + "HTTPSPort": -1, + "HTTPUseCache": true, + "KVMaxValueSize": 524288, + "KeyFile": "hidden", + "LeaveDrainTime": "5s", + "LeaveOnTerm": false, + "Logging": { + "EnableSyslog": false, + "LogFilePath": "", + "LogJSON": false, + "LogLevel": "DEBUG", + "LogRotateBytes": 0, + "LogRotateDuration": "0s", + "LogRotateMaxFiles": 0, + "Name": "", + "SyslogFacility": "LOCAL0" + }, + "MaxQueryTime": "10m0s", + "NodeID": "39588353-8c00-d756-ce83-9ee70bfa5b3a", + "NodeMeta": {}, + "NodeName": "x52", + "PidFile": "", + "PrimaryDatacenter": "dc1", + "PrimaryGateways": [], + "PrimaryGatewaysInterval": "30s", + "RPCAdvertiseAddr": "tcp://127.0.0.1:8300", + "RPCBindAddr": "tcp://127.0.0.1:8300", + "RPCConfig": { + "EnableStreaming": false + }, + "RPCHandshakeTimeout": "5s", + "RPCHoldTimeout": "7s", + "RPCMaxBurst": 1000, + "RPCMaxConnsPerClient": 100, + "RPCProtocol": 2, + "RPCRateLimit": -1, + "RaftProtocol": 3, + "RaftSnapshotInterval": "0s", + "RaftSnapshotThreshold": 0, + "RaftTrailingLogs": 0, + "ReadReplica": false, + "ReconnectTimeoutLAN": "0s", + "ReconnectTimeoutWAN": "0s", + "RejoinAfterLeave": false, + "RetryJoinIntervalLAN": "30s", + "RetryJoinIntervalWAN": "30s", + "RetryJoinLAN": [], + "RetryJoinMaxAttemptsLAN": 0, + "RetryJoinMaxAttemptsWAN": 0, + "RetryJoinWAN": [], + "Revision": "22ce6c6ad", + "SegmentLimit": 64, + "SegmentName": "", + "SegmentNameLimit": 64, + "Segments": [], + "SerfAdvertiseAddrLAN": "tcp://127.0.0.1:8301", + "SerfAdvertiseAddrWAN": "tcp://127.0.0.1:8302", + "SerfAllowedCIDRsLAN": [], + "SerfAllowedCIDRsWAN": [], + "SerfBindAddrLAN": "tcp://127.0.0.1:8301", + "SerfBindAddrWAN": "tcp://127.0.0.1:8302", + "SerfPortLAN": 8301, + "SerfPortWAN": 8302, + "ServerMode": true, + "ServerName": "", + "ServerPort": 8300, + "Services": [], + "SessionTTLMin": "0s", + "SkipLeaveOnInt": true, + "StartJoinAddrsLAN": [], + "StartJoinAddrsWAN": [], + "SyncCoordinateIntervalMin": "15s", + "SyncCoordinateRateTarget": 64, + "TLSCipherSuites": [], + "TLSMinVersion": "tls12", + "TLSPreferServerCipherSuites": false, + "TaggedAddresses": { + "lan": "127.0.0.1", + "lan_ipv4": "127.0.0.1", + "wan": "127.0.0.1", + "wan_ipv4": "127.0.0.1" + }, + "Telemetry": { + "AllowedPrefixes": [], + "BlockedPrefixes": [], + "CirconusAPIApp": "", + "CirconusAPIToken": "hidden", + "CirconusAPIURL": "", + "CirconusBrokerID": "", + "CirconusBrokerSelectTag": "", + "CirconusCheckDisplayName": "", + "CirconusCheckForceMetricActivation": "", + "CirconusCheckID": "", + "CirconusCheckInstanceID": "", + "CirconusCheckSearchTag": "", + "CirconusCheckTags": "", + "CirconusSubmissionInterval": "", + "CirconusSubmissionURL": "", + "Disable": false, + "DisableCompatOneNine": false, + "DisableHostname": false, + "DogstatsdAddr": "", + "DogstatsdTags": [], + "FilterDefault": true, + "MetricsPrefix": "consul", + "PrometheusOpts": { + "CounterDefinitions": [], + "Expiration": "0s", + "GaugeDefinitions": [], + "Registerer": null, + "SummaryDefinitions": [] + }, + "StatsdAddr": "", + "StatsiteAddr": "" + }, + "TranslateWANAddrs": false, + "TxnMaxReqLen": 524288, + "UIConfig": { + "ContentPath": "/ui/", + "DashboardURLTemplates": {}, + "Dir": "", + "Enabled": true, + "MetricsProvider": "", + "MetricsProviderFiles": [], + "MetricsProviderOptionsJSON": "", + "MetricsProxy": { + "AddHeaders": [], + "BaseURL": "", + "PathAllowlist": [] + } + }, + "UnixSocketGroup": "", + "UnixSocketMode": "", + "UnixSocketUser": "", + "UseStreamingBackend": false, + "VerifyIncoming": false, + "VerifyIncomingHTTPS": false, + "VerifyIncomingRPC": false, + "VerifyOutgoing": false, + "VerifyServerHostname": false, + "Version": "1.9.5+ent", + "VersionPrerelease": "", + "Watches": [] + }, + "Coord": { + "Vec": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "Error": 1.5, + "Adjustment": 0, + "Height": 0.00001 + }, + "Member": { + "Name": "x52", + "Addr": "127.0.0.1", + "Port": 8301, + "Tags": { + "acls": "0", + "build": "1.9.5+ent:22ce6c6a", + "dc": "dc1", + "ft_fs": "1", + "ft_ns": "1", + "ft_si": "1", + "id": "39588353-8c00-d756-ce83-9ee70bfa5b3a", + "port": "8300", + "raft_vsn": "3", + "role": "consul", + "segment": "seg1", + "vsn": "2", + "vsn_max": "3", + "vsn_min": "2", + "wan_join_port": "8302" + }, + "Status": 1, + "ProtocolMin": 1, + "ProtocolMax": 5, + "ProtocolCur": 2, + "DelegateMin": 2, + "DelegateMax": 5, + "DelegateCur": 4 + }, + "Stats": { + "agent": { + "check_monitors": "0", + "check_ttls": "0", + "checks": "0", + "services": "0" + }, + "build": { + "prerelease": "", + "revision": "22ce6c6a", + "version": "1.9.5+ent" + }, + "consul": { + "acl": "disabled", + "bootstrap": "false", + "known_datacenters": "1", + "leader": "true", + "leader_addr": "127.0.0.1:8300", + "server": "true" + }, + "license": { + "customer": "temporary", + "expiration_time": "2021-06-03 16:44:05.553068285 -0500 CDT", + "features": "Automated Backups, Automated Upgrades, Enhanced Read Scalability, Network Segments, Redundancy Zone, Advanced Network Federation, Namespaces, SSO, Audit Logging", + "id": "temporary", + "install_id": "*", + "issue_time": "2021-06-03 10:44:05.553068285 -0500 CDT", + "modules": "", + "package": "premium", + "product": "consul", + "start_time": "2021-06-03 10:39:05.553068285 -0500 CDT" + }, + "raft": { + "applied_index": "14", + "commit_index": "14", + "fsm_pending": "0", + "last_contact": "0", + "last_log_index": "14", + "last_log_term": "2", + "last_snapshot_index": "0", + "last_snapshot_term": "0", + "latest_configuration": "[{Suffrage:Voter ID:39588353-8c00-d756-ce83-9ee70bfa5b3a Address:127.0.0.1:8300}]", + "latest_configuration_index": "0", + "num_peers": "0", + "protocol_version": "3", + "protocol_version_max": "3", + "protocol_version_min": "0", + "snapshot_version_max": "1", + "snapshot_version_min": "0", + "state": "Leader", + "term": "2" + }, + "runtime": { + "arch": "amd64", + "cpu_count": "24", + "goroutines": "96", + "max_procs": "24", + "os": "linux", + "version": "go1.16.4" + }, + "serf_lan": { + "coordinate_resets": "0", + "encrypted": "false", + "event_queue": "1", + "event_time": "2", + "failed": "0", + "health_score": "0", + "intent_queue": "0", + "left": "0", + "member_time": "1", + "members": "1", + "query_queue": "0", + "query_time": "1" + }, + "serf_wan": { + "coordinate_resets": "0", + "encrypted": "false", + "event_queue": "0", + "event_time": "1", + "failed": "0", + "health_score": "0", + "intent_queue": "0", + "left": "0", + "member_time": "1", + "members": "1", + "query_queue": "0", + "query_time": "1" + } + }, + "Meta": { + "consul-network-segment": "" + }, + "xDS": { + "SupportedProxies": { + "envoy": [ + "1.16.2", + "1.15.3", + "1.14.6", + "1.13.7" + ] + } + } +} diff --git a/client/fingerprint/test_fixtures/consul/agent_self.json b/client/fingerprint/test_fixtures/consul/agent_self_oss.json similarity index 100% rename from client/fingerprint/test_fixtures/consul/agent_self.json rename to client/fingerprint/test_fixtures/consul/agent_self_oss.json