mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-24 16:41:35 -04:00
Merge pull request #10309 from kobergj/RemoveDeprecations
Remove Deprecations
This commit is contained in:
5
changelog/unreleased/remove-deprecations.md
Normal file
5
changelog/unreleased/remove-deprecations.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Enhancement: Remove Deprecations
|
||||
|
||||
Remove deprecated stores/caches/registries and envvars from the codebase.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/10305
|
||||
@@ -71,9 +71,9 @@ func runIntermediateCode(intermediateCodePath string) {
|
||||
defaultDataPath := "/var/lib/ocis"
|
||||
os.Setenv("OCIS_BASE_DATA_PATH", defaultDataPath)
|
||||
os.Setenv("OCIS_CONFIG_DIR", defaultConfigPath)
|
||||
out, err := exec.Command("go", "run", intermediateCodePath).Output()
|
||||
out, err := exec.Command("go", "run", intermediateCodePath).CombinedOutput()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatal(string(out), err)
|
||||
}
|
||||
fmt.Println(string(out))
|
||||
}
|
||||
|
||||
@@ -167,9 +167,8 @@ ACTIVITYLOG_STORE:
|
||||
name: OCIS_PERSISTENT_STORE;ACTIVITYLOG_STORE
|
||||
defaultValue: nats-js-kv
|
||||
type: string
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''ocmem'',
|
||||
''etcd'', ''redis'', ''redis-sentinel'', ''nats-js'', ''noop''. See the text description
|
||||
for details.'
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''nats-js-kv'',
|
||||
''redis-sentinel'', ''noop''. See the text description for details.'
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -208,9 +207,9 @@ ACTIVITYLOG_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -3182,9 +3181,8 @@ EVENTHISTORY_STORE:
|
||||
name: OCIS_PERSISTENT_STORE;EVENTHISTORY_STORE
|
||||
defaultValue: nats-js-kv
|
||||
type: string
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''ocmem'',
|
||||
''etcd'', ''redis'', ''redis-sentinel'', ''nats-js'', ''noop''. See the text description
|
||||
for details.'
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''nats-js-kv'',
|
||||
''redis-sentinel'', ''noop''. See the text description for details.'
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -3223,9 +3221,9 @@ EVENTHISTORY_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -3872,9 +3870,9 @@ FRONTEND_OCS_STAT_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -4210,9 +4208,9 @@ GATEWAY_CREATE_HOME_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -4434,9 +4432,9 @@ GATEWAY_PROVIDER_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -4714,9 +4712,9 @@ GRAPH_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store are configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -7483,12 +7481,12 @@ NOTIFICATIONS_SMTP_ENCRYPTION:
|
||||
defaultValue: none
|
||||
type: string
|
||||
description: Encryption method for the SMTP communication. Possible values are 'starttls',
|
||||
'ssl', 'ssltls', 'tls' and 'none'.
|
||||
'ssltls' and 'none'.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: 5.0.0
|
||||
removalVersion: '%%NEXT_PRODUCTION_VERSION%%'
|
||||
deprecationInfo: The NOTIFICATIONS_SMTP_ENCRYPTION values 'ssl' and 'tls' are deprecated
|
||||
and will be removed in the future.
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: 'The NOTIFICATIONS_SMTP_ENCRYPTION values ''ssl'' and ''tls'' are
|
||||
deprecated and will be removed in the future. | '
|
||||
NOTIFICATIONS_SMTP_HOST:
|
||||
name: NOTIFICATIONS_SMTP_HOST
|
||||
defaultValue: ""
|
||||
@@ -7927,7 +7925,7 @@ OCIS_ASSET_THEMES_PATH:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_ASYNC_UPLOADS:
|
||||
name: OCIS_ASYNC_UPLOADS
|
||||
name: OCIS_ASYNC_UPLOADS;SEARCH_EVENTS_ASYNC_UPLOADS
|
||||
defaultValue: "true"
|
||||
type: bool
|
||||
description: Enable asynchronous file uploads.
|
||||
@@ -7936,28 +7934,28 @@ OCIS_ASYNC_UPLOADS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_AUTH_PASSWORD:
|
||||
name: OCIS_CACHE_AUTH_PASSWORD;GATEWAY_CREATE_HOME_CACHE_AUTH_PASSWORD
|
||||
name: OCIS_CACHE_AUTH_PASSWORD;STORAGE_SYSTEM_CACHE_AUTH_PASSWORD
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The password to use for authentication. Only applies when store type
|
||||
'nats-js-kv' is configured.
|
||||
description: Password for the configured store. Only applies when store type 'nats-js-kv'
|
||||
is configured.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_AUTH_USERNAME:
|
||||
name: OCIS_CACHE_AUTH_USERNAME;GATEWAY_CREATE_HOME_CACHE_AUTH_USERNAME
|
||||
name: OCIS_CACHE_AUTH_USERNAME;STORAGE_SYSTEM_CACHE_AUTH_USERNAME
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The username to use for authentication. Only applies when store type
|
||||
'nats-js-kv' is configured.
|
||||
description: Username for the configured store. Only applies when store type 'nats-js-kv'
|
||||
is configured.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_DATABASE:
|
||||
name: OCIS_CACHE_DATABASE
|
||||
defaultValue: cache-createhome
|
||||
defaultValue: storage-system
|
||||
type: string
|
||||
description: The database name the configured store should use.
|
||||
introductionVersion: pre5.0
|
||||
@@ -7965,11 +7963,11 @@ OCIS_CACHE_DATABASE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_DISABLE_PERSISTENCE:
|
||||
name: OCIS_CACHE_DISABLE_PERSISTENCE;GATEWAY_CREATE_HOME_CACHE_DISABLE_PERSISTENCE
|
||||
name: OCIS_CACHE_DISABLE_PERSISTENCE;STORAGE_SYSTEM_CACHE_DISABLE_PERSISTENCE
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Disables persistence of the create home cache. Only applies when store
|
||||
type 'nats-js-kv' is configured. Defaults to false.
|
||||
description: Disables persistence of the cache. Only applies when store type 'nats-js-kv'
|
||||
is configured. Defaults to false.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -7986,7 +7984,7 @@ OCIS_CACHE_SIZE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_STORE:
|
||||
name: OCIS_CACHE_STORE;GATEWAY_CREATE_HOME_CACHE_STORE
|
||||
name: OCIS_CACHE_STORE;STORAGE_SYSTEM_CACHE_STORE
|
||||
defaultValue: memory
|
||||
type: string
|
||||
description: 'The type of the cache store. Supported values are: ''memory'', ''redis-sentinel'',
|
||||
@@ -7996,30 +7994,30 @@ OCIS_CACHE_STORE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_STORE_NODES:
|
||||
name: OCIS_CACHE_STORE_NODES;GATEWAY_CREATE_HOME_CACHE_STORE_NODES
|
||||
name: OCIS_CACHE_STORE_NODES;STORAGE_SYSTEM_CACHE_STORE_NODES
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_TTL:
|
||||
name: OCIS_CACHE_TTL;GATEWAY_CREATE_HOME_CACHE_TTL
|
||||
defaultValue: 5m0s
|
||||
name: OCIS_CACHE_TTL;STORAGE_SYSTEM_CACHE_TTL
|
||||
defaultValue: 24m0s
|
||||
type: Duration
|
||||
description: Default time to live for user info in the cache. Only applied when
|
||||
access tokens has no expiration. See the Environment Variable Types description
|
||||
description: Default time to live for user info in the user info cache. Only applied
|
||||
when access tokens has no expiration. See the Environment Variable Types description
|
||||
for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_CREDENTIALS:
|
||||
name: OCIS_CORS_ALLOW_CREDENTIALS;WEBDAV_CORS_ALLOW_CREDENTIALS
|
||||
name: OCIS_CORS_ALLOW_CREDENTIALS;ACTIVITYLOG_CORS_ALLOW_CREDENTIALS
|
||||
defaultValue: "true"
|
||||
type: bool
|
||||
description: 'Allow credentials for CORS.See following chapter for more details:
|
||||
@@ -8029,9 +8027,9 @@ OCIS_CORS_ALLOW_CREDENTIALS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_HEADERS:
|
||||
name: OCIS_CORS_ALLOW_HEADERS;WEBDAV_CORS_ALLOW_HEADERS
|
||||
name: OCIS_CORS_ALLOW_HEADERS;ACTIVITYLOG_CORS_ALLOW_HEADERS
|
||||
defaultValue: '[Authorization Origin Content-Type Accept X-Requested-With X-Request-Id
|
||||
Cache-Control]'
|
||||
Ocs-Apirequest]'
|
||||
type: '[]string'
|
||||
description: 'A list of allowed CORS headers. See following chapter for more details:
|
||||
*Access-Control-Request-Headers* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers.
|
||||
@@ -8041,8 +8039,8 @@ OCIS_CORS_ALLOW_HEADERS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_METHODS:
|
||||
name: OCIS_CORS_ALLOW_METHODS;WEBDAV_CORS_ALLOW_METHODS
|
||||
defaultValue: '[GET POST PUT PATCH DELETE OPTIONS]'
|
||||
name: OCIS_CORS_ALLOW_METHODS;ACTIVITYLOG_CORS_ALLOW_METHODS
|
||||
defaultValue: '[GET]'
|
||||
type: '[]string'
|
||||
description: 'A list of allowed CORS methods. See following chapter for more details:
|
||||
*Access-Control-Request-Method* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method.
|
||||
@@ -8052,7 +8050,7 @@ OCIS_CORS_ALLOW_METHODS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_ORIGINS:
|
||||
name: OCIS_CORS_ALLOW_ORIGINS;WEBDAV_CORS_ALLOW_ORIGINS
|
||||
name: OCIS_CORS_ALLOW_ORIGINS;ACTIVITYLOG_CORS_ALLOW_ORIGINS
|
||||
defaultValue: '[*]'
|
||||
type: '[]string'
|
||||
description: 'A list of allowed CORS origins. See following chapter for more details:
|
||||
@@ -8113,7 +8111,7 @@ OCIS_DEFAULT_LANGUAGE:
|
||||
type: string
|
||||
description: The default language used by services and the WebUI. If not defined,
|
||||
English will be used as default. See the documentation for more details.
|
||||
introductionVersion: "5.0"
|
||||
introductionVersion: '%%NEXT%%'
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
@@ -8196,7 +8194,7 @@ OCIS_ENABLE_RESHARING:
|
||||
removalVersion: ""
|
||||
deprecationInfo: Resharing will be removed in the future.
|
||||
OCIS_EVENTS_AUTH_PASSWORD:
|
||||
name: OCIS_EVENTS_AUTH_PASSWORD;SSE_EVENTS_AUTH_PASSWORD
|
||||
name: OCIS_EVENTS_AUTH_PASSWORD
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The password to authenticate with the events broker. The events broker
|
||||
@@ -8206,7 +8204,7 @@ OCIS_EVENTS_AUTH_PASSWORD:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_AUTH_USERNAME:
|
||||
name: OCIS_EVENTS_AUTH_USERNAME;SSE_EVENTS_AUTH_USERNAME
|
||||
name: OCIS_EVENTS_AUTH_USERNAME
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The username to authenticate with the events broker. The events broker
|
||||
@@ -8216,7 +8214,7 @@ OCIS_EVENTS_AUTH_USERNAME:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_CLUSTER:
|
||||
name: OCIS_EVENTS_CLUSTER;SSE_EVENTS_CLUSTER
|
||||
name: OCIS_EVENTS_CLUSTER
|
||||
defaultValue: ocis-cluster
|
||||
type: string
|
||||
description: The clusterID of the event system. The event system is the message
|
||||
@@ -8227,7 +8225,7 @@ OCIS_EVENTS_CLUSTER:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_ENABLE_TLS:
|
||||
name: OCIS_EVENTS_ENABLE_TLS;SSE_EVENTS_ENABLE_TLS
|
||||
name: OCIS_EVENTS_ENABLE_TLS
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Enable TLS for the connection to the events broker. The events broker
|
||||
@@ -8237,7 +8235,7 @@ OCIS_EVENTS_ENABLE_TLS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_ENDPOINT:
|
||||
name: OCIS_EVENTS_ENDPOINT;SSE_EVENTS_ENDPOINT
|
||||
name: OCIS_EVENTS_ENDPOINT
|
||||
defaultValue: 127.0.0.1:9233
|
||||
type: string
|
||||
description: The address of the event system. The event system is the message queuing
|
||||
@@ -8247,11 +8245,11 @@ OCIS_EVENTS_ENDPOINT:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE:
|
||||
name: OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE;SSE_EVENTS_TLS_ROOT_CA_CERTIFICATE
|
||||
name: OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The root CA certificate used to validate the server's TLS certificate.
|
||||
If provided SSE_EVENTS_TLS_INSECURE will be seen as false.
|
||||
If provided NOTIFICATIONS_EVENTS_TLS_INSECURE will be seen as false.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8289,7 +8287,7 @@ OCIS_GRPC_CLIENT_TLS_MODE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_GRPC_PROTOCOL:
|
||||
name: OCIS_GRPC_PROTOCOL;GROUPS_GRPC_PROTOCOL
|
||||
name: OCIS_GRPC_PROTOCOL;APP_REGISTRY_GRPC_PROTOCOL
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The transport protocol of the GRPC service.
|
||||
@@ -8329,7 +8327,7 @@ OCIS_HTTP_TLS_KEY:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_INSECURE:
|
||||
name: OCIS_INSECURE;SSE_EVENTS_TLS_INSECURE
|
||||
name: OCIS_INSECURE
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Whether to verify the server TLS certificates.
|
||||
@@ -8338,11 +8336,11 @@ OCIS_INSECURE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_JWT_SECRET:
|
||||
name: OCIS_JWT_SECRET;SSE_JWT_SECRET
|
||||
name: OCIS_JWT_SECRET;ACTIVITYLOG_JWT_SECRET
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The secret to mint and validate jwt tokens.
|
||||
introductionVersion: "5.0"
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
@@ -8455,7 +8453,7 @@ OCIS_LDAP_DISABLED_USERS_GROUP_DN:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_BASE_DN:
|
||||
name: OCIS_LDAP_GROUP_BASE_DN;GROUPS_LDAP_GROUP_BASE_DN
|
||||
name: OCIS_LDAP_GROUP_BASE_DN;AUTH_BASIC_LDAP_GROUP_BASE_DN
|
||||
defaultValue: ou=groups,o=libregraph-idm
|
||||
type: string
|
||||
description: Search base DN for looking up LDAP groups.
|
||||
@@ -8464,7 +8462,7 @@ OCIS_LDAP_GROUP_BASE_DN:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_FILTER:
|
||||
name: OCIS_LDAP_GROUP_FILTER;GROUPS_LDAP_GROUP_FILTER
|
||||
name: OCIS_LDAP_GROUP_FILTER;AUTH_BASIC_LDAP_GROUP_FILTER
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: LDAP filter to add to the default filters for group searches.
|
||||
@@ -8473,7 +8471,7 @@ OCIS_LDAP_GROUP_FILTER:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_OBJECTCLASS:
|
||||
name: OCIS_LDAP_GROUP_OBJECTCLASS;GROUPS_LDAP_GROUP_OBJECTCLASS
|
||||
name: OCIS_LDAP_GROUP_OBJECTCLASS;AUTH_BASIC_LDAP_GROUP_OBJECTCLASS
|
||||
defaultValue: groupOfNames
|
||||
type: string
|
||||
description: The object class to use for groups in the default group search filter
|
||||
@@ -8483,7 +8481,7 @@ OCIS_LDAP_GROUP_OBJECTCLASS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME:
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME;GROUPS_LDAP_GROUP_SCHEMA_DISPLAYNAME
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME;AUTH_BASIC_LDAP_GROUP_SCHEMA_DISPLAYNAME
|
||||
defaultValue: cn
|
||||
type: string
|
||||
description: LDAP Attribute to use for the displayname of groups (often the same
|
||||
@@ -8493,7 +8491,7 @@ OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_SCHEMA_GROUPNAME:
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_GROUPNAME;GROUPS_LDAP_GROUP_SCHEMA_GROUPNAME
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_GROUPNAME;AUTH_BASIC_LDAP_GROUP_SCHEMA_GROUPNAME
|
||||
defaultValue: cn
|
||||
type: string
|
||||
description: LDAP Attribute to use for the name of groups.
|
||||
@@ -8502,28 +8500,28 @@ OCIS_LDAP_GROUP_SCHEMA_GROUPNAME:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_SCHEMA_ID:
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_ID;GROUPS_LDAP_GROUP_SCHEMA_ID
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_ID;AUTH_BASIC_LDAP_GROUP_SCHEMA_ID
|
||||
defaultValue: ownclouduuid
|
||||
type: string
|
||||
description: LDAP Attribute to use as the unique id for groups. This should be a
|
||||
stable globally unique ID like a UUID.
|
||||
stable globally unique id (e.g. a UUID).
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING:
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;GROUPS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;AUTH_BASIC_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Set this to true if the defined 'id' attribute for groups is of the
|
||||
'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute
|
||||
of Active Directory for the group ID's.
|
||||
of Active Directory for the group IDs.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_SCHEMA_MAIL:
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_MAIL;GROUPS_LDAP_GROUP_SCHEMA_MAIL
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_MAIL;AUTH_BASIC_LDAP_GROUP_SCHEMA_MAIL
|
||||
defaultValue: mail
|
||||
type: string
|
||||
description: LDAP Attribute to use for the email address of groups (can be empty).
|
||||
@@ -8532,7 +8530,7 @@ OCIS_LDAP_GROUP_SCHEMA_MAIL:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_SCHEMA_MEMBER:
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_MEMBER;GROUPS_LDAP_GROUP_SCHEMA_MEMBER
|
||||
name: OCIS_LDAP_GROUP_SCHEMA_MEMBER;AUTH_BASIC_LDAP_GROUP_SCHEMA_MEMBER
|
||||
defaultValue: member
|
||||
type: string
|
||||
description: LDAP Attribute that is used for group members.
|
||||
@@ -8541,10 +8539,10 @@ OCIS_LDAP_GROUP_SCHEMA_MEMBER:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_GROUP_SCOPE:
|
||||
name: OCIS_LDAP_GROUP_SCOPE;GROUPS_LDAP_GROUP_SCOPE
|
||||
name: OCIS_LDAP_GROUP_SCOPE;AUTH_BASIC_LDAP_GROUP_SCOPE
|
||||
defaultValue: sub
|
||||
type: string
|
||||
description: LDAP search scope to use when looking up groups. Supported scopes are
|
||||
description: LDAP search scope to use when looking up groups. Supported values are
|
||||
'base', 'one' and 'sub'.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
@@ -8618,7 +8616,7 @@ OCIS_LDAP_USER_OBJECTCLASS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_USER_SCHEMA_DISPLAYNAME:
|
||||
name: OCIS_LDAP_USER_SCHEMA_DISPLAYNAME;GROUPS_LDAP_USER_SCHEMA_DISPLAYNAME
|
||||
name: OCIS_LDAP_USER_SCHEMA_DISPLAYNAME;AUTH_BASIC_LDAP_USER_SCHEMA_DISPLAYNAME
|
||||
defaultValue: displayname
|
||||
type: string
|
||||
description: LDAP Attribute to use for the displayname of users.
|
||||
@@ -8636,12 +8634,12 @@ OCIS_LDAP_USER_SCHEMA_ID:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING:
|
||||
name: OCIS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;GROUPS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING
|
||||
name: OCIS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;AUTH_BASIC_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Set this to true if the defined 'ID' attribute for users is of the
|
||||
'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute
|
||||
of Active Directory for the user ID's.
|
||||
of Active Directory for the user IDs.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8685,39 +8683,39 @@ OCIS_LDAP_USER_SCOPE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_COLOR:
|
||||
name: OCIS_LOG_COLOR;WEBDAV_LOG_COLOR
|
||||
name: OCIS_LOG_COLOR;ACTIVITYLOG_LOG_COLOR
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Activates colorized log output.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_FILE:
|
||||
name: OCIS_LOG_FILE;WEBDAV_LOG_FILE
|
||||
name: OCIS_LOG_FILE;ACTIVITYLOG_LOG_FILE
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The path to the log file. Activates logging to this file if set.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_LEVEL:
|
||||
name: OCIS_LOG_LEVEL;WEBDAV_LOG_LEVEL
|
||||
name: OCIS_LOG_LEVEL;ACTIVITYLOG_LOG_LEVEL
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: 'The log level. Valid values are: ''panic'', ''fatal'', ''error'',
|
||||
''warn'', ''info'', ''debug'', ''trace''.'
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_PRETTY:
|
||||
name: OCIS_LOG_PRETTY;WEBDAV_LOG_PRETTY
|
||||
name: OCIS_LOG_PRETTY;ACTIVITYLOG_LOG_PRETTY
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Activates pretty log output.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
@@ -8819,18 +8817,17 @@ OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE:
|
||||
name: OCIS_PERSISTENT_STORE;EVENTHISTORY_STORE
|
||||
name: OCIS_PERSISTENT_STORE;ACTIVITYLOG_STORE
|
||||
defaultValue: nats-js-kv
|
||||
type: string
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''ocmem'',
|
||||
''etcd'', ''redis'', ''redis-sentinel'', ''nats-js'', ''noop''. See the text description
|
||||
for details.'
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''nats-js-kv'',
|
||||
''redis-sentinel'', ''noop''. See the text description for details.'
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_AUTH_PASSWORD:
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_PASSWORD;EVENTHISTORY_STORE_AUTH_PASSWORD
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_PASSWORD;ACTIVITYLOG_STORE_AUTH_PASSWORD
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The password to authenticate with the store. Only applies when store
|
||||
@@ -8840,7 +8837,7 @@ OCIS_PERSISTENT_STORE_AUTH_PASSWORD:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_AUTH_USERNAME:
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_USERNAME;EVENTHISTORY_STORE_AUTH_USERNAME
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_USERNAME;ACTIVITYLOG_STORE_AUTH_USERNAME
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The username to authenticate with the store. Only applies when store
|
||||
@@ -8850,13 +8847,13 @@ OCIS_PERSISTENT_STORE_AUTH_USERNAME:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_NODES:
|
||||
name: OCIS_PERSISTENT_STORE_NODES;EVENTHISTORY_STORE_NODES
|
||||
name: OCIS_PERSISTENT_STORE_NODES;ACTIVITYLOG_STORE_NODES
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8873,11 +8870,11 @@ OCIS_PERSISTENT_STORE_SIZE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_TTL:
|
||||
name: OCIS_PERSISTENT_STORE_TTL;EVENTHISTORY_STORE_TTL
|
||||
defaultValue: 336h0m0s
|
||||
name: OCIS_PERSISTENT_STORE_TTL;ACTIVITYLOG_STORE_TTL
|
||||
defaultValue: 0s
|
||||
type: Duration
|
||||
description: Time to live for events in the store. Defaults to '336h' (2 weeks).
|
||||
See the Environment Variable Types description for more details.
|
||||
description: Time to live for events in the store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8896,7 +8893,7 @@ OCIS_REVA_GATEWAY:
|
||||
defaultValue: com.owncloud.api.gateway
|
||||
type: string
|
||||
description: CS3 gateway used to look up user metadata
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
@@ -8923,7 +8920,7 @@ OCIS_REVA_GATEWAY_TLS_MODE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SERVICE_ACCOUNT_ID:
|
||||
name: OCIS_SERVICE_ACCOUNT_ID;USERLOG_SERVICE_ACCOUNT_ID
|
||||
name: OCIS_SERVICE_ACCOUNT_ID;ACTIVITYLOG_SERVICE_ACCOUNT_ID
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The ID of the service account the service should use. See the 'auth-service'
|
||||
@@ -8933,7 +8930,7 @@ OCIS_SERVICE_ACCOUNT_ID:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SERVICE_ACCOUNT_SECRET:
|
||||
name: OCIS_SERVICE_ACCOUNT_SECRET;USERLOG_SERVICE_ACCOUNT_SECRET
|
||||
name: OCIS_SERVICE_ACCOUNT_SECRET;ACTIVITYLOG_SERVICE_ACCOUNT_SECRET
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The service account secret.
|
||||
@@ -8991,10 +8988,10 @@ OCIS_SYSTEM_USER_API_KEY:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SYSTEM_USER_ID:
|
||||
name: OCIS_SYSTEM_USER_ID;SETTINGS_SYSTEM_USER_ID
|
||||
name: OCIS_SYSTEM_USER_ID
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: ID of the oCIS STORAGE-SYSTEM system user. Admins need to set the ID
|
||||
description: ID of the oCIS storage-system system user. Admins need to set the ID
|
||||
for the STORAGE-SYSTEM system user in this config option which is then used to
|
||||
reference the user. Any reasonable long string is possible, preferably this would
|
||||
be an UUIDv4 format.
|
||||
@@ -9003,7 +9000,7 @@ OCIS_SYSTEM_USER_ID:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SYSTEM_USER_IDP:
|
||||
name: OCIS_SYSTEM_USER_IDP;SETTINGS_SYSTEM_USER_IDP
|
||||
name: OCIS_SYSTEM_USER_IDP;SHARING_PUBLIC_CS3_SYSTEM_USER_IDP
|
||||
defaultValue: internal
|
||||
type: string
|
||||
description: IDP of the oCIS STORAGE-SYSTEM system user.
|
||||
@@ -9012,40 +9009,40 @@ OCIS_SYSTEM_USER_IDP:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_COLLECTOR:
|
||||
name: OCIS_TRACING_COLLECTOR;WEBDAV_TRACING_COLLECTOR
|
||||
name: OCIS_TRACING_COLLECTOR;ACTIVITYLOG_TRACING_COLLECTOR
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The HTTP endpoint for sending spans directly to a collector, i.e. http://jaeger-collector:14268/api/traces.
|
||||
Only used if the tracing endpoint is unset.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_ENABLED:
|
||||
name: OCIS_TRACING_ENABLED;WEBDAV_TRACING_ENABLED
|
||||
name: OCIS_TRACING_ENABLED;ACTIVITYLOG_TRACING_ENABLED
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Activates tracing.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_ENDPOINT:
|
||||
name: OCIS_TRACING_ENDPOINT;WEBDAV_TRACING_ENDPOINT
|
||||
name: OCIS_TRACING_ENDPOINT;ACTIVITYLOG_TRACING_ENDPOINT
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The endpoint of the tracing agent.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_TYPE:
|
||||
name: OCIS_TRACING_TYPE;WEBDAV_TRACING_TYPE
|
||||
name: OCIS_TRACING_TYPE;ACTIVITYLOG_TRACING_TYPE
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The type of tracing. Defaults to '', which is the same as 'jaeger'.
|
||||
Allowed tracing types are 'jaeger' and '' as of now.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
@@ -9059,21 +9056,21 @@ OCIS_TRANSFER_SECRET:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRANSLATION_PATH:
|
||||
name: OCIS_TRANSLATION_PATH;USERLOG_TRANSLATION_PATH
|
||||
name: OCIS_TRANSLATION_PATH;ACTIVITYLOG_TRANSLATION_PATH
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: (optional) Set this to a path with custom translations to overwrite
|
||||
the builtin translations. Note that file and folder naming rules apply, see the
|
||||
documentation for more details.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: '%%NEXT%%'
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_URL:
|
||||
name: OCIS_URL;OCIS_PUBLIC_URL
|
||||
defaultValue: https://127.0.0.1:9200
|
||||
name: OCIS_URL;OCIS_OIDC_ISSUER;IDP_ISS
|
||||
defaultValue: https://localhost:9200
|
||||
type: string
|
||||
description: URL, where oCIS is reachable for users.
|
||||
description: The OIDC issuer URL to use.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -10239,9 +10236,8 @@ POSTPROCESSING_STORE:
|
||||
name: OCIS_PERSISTENT_STORE;POSTPROCESSING_STORE
|
||||
defaultValue: nats-js-kv
|
||||
type: string
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''ocmem'',
|
||||
''etcd'', ''redis'', ''redis-sentinel'', ''nats-js'', ''noop''. See the text description
|
||||
for details.'
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''redis-sentinel'',
|
||||
''nats-js-kv'', ''noop''. See the text description for details.'
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -10280,9 +10276,9 @@ POSTPROCESSING_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -10790,9 +10786,9 @@ PROXY_OIDC_USERINFO_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -11418,9 +11414,9 @@ SETTINGS_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -12960,9 +12956,9 @@ STORAGE_SYSTEM_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -13517,9 +13513,9 @@ STORAGE_USERS_FILEMETADATA_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -13648,9 +13644,9 @@ STORAGE_USERS_ID_CACHE_STORE_NODES:
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -15095,9 +15091,8 @@ USERLOG_STORE:
|
||||
name: OCIS_PERSISTENT_STORE;USERLOG_STORE
|
||||
defaultValue: memory
|
||||
type: string
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''ocmem'',
|
||||
''etcd'', ''redis'', ''redis-sentinel'', ''nats-js'', ''noop''. See the text description
|
||||
for details.'
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''nats-js-kv'',
|
||||
''redis-sentinel'', ''noop''. See the text description for details.'
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -15136,9 +15131,9 @@ USERLOG_STORE_NODES:
|
||||
defaultValue: '[]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
when 'memory' store is configured. Note that the behaviour how nodes are used
|
||||
is dependent on the library of the configured store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
|
||||
@@ -75,18 +75,16 @@ variables:
|
||||
description: ""
|
||||
do_ignore: true
|
||||
- rawname: _registryEnv
|
||||
path: ocis-pkg/registry/registry.go:114
|
||||
path: ocis-pkg/registry/registry.go:87
|
||||
foundincode: true
|
||||
name: MICRO_REGISTRY
|
||||
type: string
|
||||
default_value: nats-js-kv
|
||||
description: 'The Go micro registry type to use. Supported types are: ''memory'',
|
||||
''nats-js-kv'' (default) and ''kubernetes''. Note that ''nats'', ''etcd'', ''consul''
|
||||
and ''mdns'' are deprecated and will be removed in a later version. Only change
|
||||
on supervision of ownCloud Support.'
|
||||
description: 'The Go micro registry type to use. Supported types are: ''memory''
|
||||
and ''nats-js-kv'' (default). Only change on supervision of ownCloud Support.'
|
||||
do_ignore: false
|
||||
- rawname: _registryAddressEnv
|
||||
path: ocis-pkg/registry/registry.go:118
|
||||
path: ocis-pkg/registry/registry.go:91
|
||||
foundincode: true
|
||||
name: MICRO_REGISTRY_ADDRESS
|
||||
type: ""
|
||||
|
||||
15
go.mod
15
go.mod
@@ -27,12 +27,7 @@ require (
|
||||
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3
|
||||
github.com/go-micro/plugins/v4/client/grpc v1.2.1
|
||||
github.com/go-micro/plugins/v4/logger/zerolog v1.2.0
|
||||
github.com/go-micro/plugins/v4/registry/consul v1.2.1
|
||||
github.com/go-micro/plugins/v4/registry/etcd v1.2.0
|
||||
github.com/go-micro/plugins/v4/registry/kubernetes v1.1.2
|
||||
github.com/go-micro/plugins/v4/registry/mdns v1.2.0
|
||||
github.com/go-micro/plugins/v4/registry/memory v1.2.0
|
||||
github.com/go-micro/plugins/v4/registry/nats v1.2.2
|
||||
github.com/go-micro/plugins/v4/server/grpc v1.2.0
|
||||
github.com/go-micro/plugins/v4/server/http v1.2.2
|
||||
github.com/go-micro/plugins/v4/store/nats-js-kv v0.0.0-20231226212146-94a49ba3e06e
|
||||
@@ -132,7 +127,6 @@ require (
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/alexedwards/argon2id v1.0.0 // indirect
|
||||
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/armon/go-radix v1.0.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go v1.45.1 // indirect
|
||||
@@ -235,15 +229,8 @@ require (
|
||||
github.com/gorilla/handlers v1.5.1 // indirect
|
||||
github.com/gorilla/schema v1.4.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/hashicorp/consul/api v1.25.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-msgpack v1.1.5 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.1 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/golang-lru v0.6.0 // indirect
|
||||
github.com/hashicorp/serf v0.10.1 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||
@@ -275,9 +262,7 @@ require (
|
||||
github.com/minio/minio-go/v7 v7.0.66 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/hashstructure v1.1.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
|
||||
73
go.sum
73
go.sum
@@ -64,7 +64,6 @@ github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/CiscoM31/godata v1.0.10 h1:DZdJ6M8QNh4HquvDDOqNLu6h77Wl86KGK7Qlbmb90sk=
|
||||
github.com/CiscoM31/godata v1.0.10/go.mod h1:ZMiT6JuD3Rm83HEtiTx4JEChsd25YCrxchKGag/sdTc=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c h1:ocsNvQ2tNHme4v/lTs17HROamc7mFzZfzWcg4m+UXN0=
|
||||
github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||
github.com/KimMachineGun/automemlimit v0.6.1 h1:ILa9j1onAAMadBsyyUJv5cack8Y1WT26yLj/V+ulKp8=
|
||||
@@ -119,8 +118,6 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
@@ -221,8 +218,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4=
|
||||
github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
@@ -317,7 +312,6 @@ github.com/evanphx/json-patch/v5 v5.5.0 h1:bAmFiUJ+o0o2B4OiTFeE3MqCOtyo+jjPP9iZ0
|
||||
github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
||||
github.com/exoscale/egoscale v0.46.0/go.mod h1:mpEXBpROAa/2i5GC0r33rfxG+TxSEka11g1PIXt9+zc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||
@@ -404,18 +398,8 @@ github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20231215124540-f7f8d3274bf
|
||||
github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20231215124540-f7f8d3274bf9/go.mod h1:cL0O63th39fZ+M/aRJvajz7Qnmv+UTXugOq1k3qrYiQ=
|
||||
github.com/go-micro/plugins/v4/logger/zerolog v1.2.0 h1:JZ516VQ9zekRoi868XG7x0EWxZ2AMq/euHIBChITsTI=
|
||||
github.com/go-micro/plugins/v4/logger/zerolog v1.2.0/go.mod h1:AieYOIeOxobYa5B8WGEqxXM3Ndi26tDIu9fZ4RYkCvQ=
|
||||
github.com/go-micro/plugins/v4/registry/consul v1.2.1 h1:3wctYMtstwQLCjoJ1HA6mKGGFF1hcdKDv5MzHakB1jE=
|
||||
github.com/go-micro/plugins/v4/registry/consul v1.2.1/go.mod h1:wTat7/K9XQ+i64VbbcMYFcEwipYfSgJM51HcA/sgsM4=
|
||||
github.com/go-micro/plugins/v4/registry/etcd v1.2.0 h1:tcHlU1GzvX3oZa8WQH8ylMCGie5qD5g98YWTESJjeqQ=
|
||||
github.com/go-micro/plugins/v4/registry/etcd v1.2.0/go.mod h1:CQeTHkjN3xMtIQsynaTTquMz2sHEdsTfRIfFzrX7aug=
|
||||
github.com/go-micro/plugins/v4/registry/kubernetes v1.1.2 h1:ZLDgMhpnqj7RjDphedrIqCbmCL2z8m7+8Ex5tdT8GxU=
|
||||
github.com/go-micro/plugins/v4/registry/kubernetes v1.1.2/go.mod h1:u78+qWLUq8jxu/CF4UW+1UUtNgBz67x27ar2kV5Dd/o=
|
||||
github.com/go-micro/plugins/v4/registry/mdns v1.2.0 h1:BsGnco+PgycvSX+HS0XbeUQEPoPT3a+dDiHWV6dbVDs=
|
||||
github.com/go-micro/plugins/v4/registry/mdns v1.2.0/go.mod h1:re0JvO5F56n59WEDaAKj2jtboKa2dklAd6iWyz5xa54=
|
||||
github.com/go-micro/plugins/v4/registry/memory v1.2.0 h1:R0G2tltffuG+fQnk+/JuAdgEJX4J+LuOafZDoNd8ow0=
|
||||
github.com/go-micro/plugins/v4/registry/memory v1.2.0/go.mod h1:4t5YiXJT5BVtMWImxy807lY3ywjv/PHpdHnN+LXSsI4=
|
||||
github.com/go-micro/plugins/v4/registry/nats v1.2.2 h1:+M1ZzEA77CXJBvhPb71Q8+dZ5vZPkpDTvqWzzwpWSS0=
|
||||
github.com/go-micro/plugins/v4/registry/nats v1.2.2/go.mod h1:RDsrDhcjJggCzAvvUzo/Bzy68d9s9+tu0KOfofXVCog=
|
||||
github.com/go-micro/plugins/v4/server/grpc v1.2.0 h1:lXfM+/0oE/u1g0hVBYsvbP4lYOYXYOmwf5qH7ghi7Cc=
|
||||
github.com/go-micro/plugins/v4/server/grpc v1.2.0/go.mod h1:+Ah9Pf/vMSXxBM3fup/hc3N+zN2as3nIpcRaR4sBjnY=
|
||||
github.com/go-micro/plugins/v4/server/http v1.2.2 h1:UK2/09AU0zV3wHELuR72TZzVU2vTUhbx9qrRGrQSIWg=
|
||||
@@ -535,8 +519,6 @@ github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws
|
||||
github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM=
|
||||
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@@ -615,64 +597,34 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjw
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE=
|
||||
github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs=
|
||||
github.com/hashicorp/consul/sdk v0.14.1/go.mod h1:vFt03juSzocLRFo59NkeQHHmQa6+g7oU0pfzdI1mUhg=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs=
|
||||
github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI=
|
||||
github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
|
||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4=
|
||||
github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM=
|
||||
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
||||
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
@@ -726,7 +678,6 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@@ -805,7 +756,6 @@ github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxq
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
@@ -816,7 +766,6 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@@ -838,9 +787,7 @@ github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b/go.mod h1:KirJ
|
||||
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZyWckaLfucYG6KYOXLWo4co8pZYNY=
|
||||
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103/go.mod h1:o9YPB5aGP8ob35Vy6+vyq3P3bWe7NQWzf+JLiXCiMaE=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
|
||||
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
|
||||
github.com/mileusna/useragent v1.3.4 h1:MiuRRuvGjEie1+yZHO88UBYg8YBC/ddF6T7F56i3PCk=
|
||||
@@ -854,19 +801,15 @@ github.com/minio/minio-go/v7 v7.0.66/go.mod h1:DHAgmyQEGdW3Cif0UooKOyrT3Vxs82zNd
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0=
|
||||
github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
@@ -949,8 +892,6 @@ github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwU
|
||||
github.com/pablodz/inotifywaitgo v0.0.7 h1:1ii49dGBnRn0t1Sz7RGZS6/NberPEDQprwKHN49Bv6U=
|
||||
github.com/pablodz/inotifywaitgo v0.0.7/go.mod h1:OtzRCsYTJlIr+vAzlOtauTkfQ1c25ebFuXq8tbbf8cw=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
||||
@@ -977,7 +918,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k=
|
||||
github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
|
||||
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
@@ -989,7 +929,6 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
@@ -1011,7 +950,6 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
@@ -1025,7 +963,6 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
@@ -1068,7 +1005,6 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sacloud/libsacloud v1.36.2/go.mod h1:P7YAOVmnIn3DKHqCZcUKYUXmSwGBm3yS7IBEjKVSrjg=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0=
|
||||
github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg=
|
||||
@@ -1174,7 +1110,6 @@ github.com/trustelem/zxcvbn v1.0.1 h1:mp4JFtzdDYGj9WYSD3KQSkwwUumWNFzXaAjckaTYps
|
||||
github.com/trustelem/zxcvbn v1.0.1/go.mod h1:zonUyKeh7sw6psPf/e3DtRqkRyZvAbOfjNz/aO7YQ5s=
|
||||
github.com/tus/tusd/v2 v2.5.0 h1:72/2Ws3kF0upYqENcbb0yr4aca0HByDNkIjOs5yh0es=
|
||||
github.com/tus/tusd/v2 v2.5.0/go.mod h1:dUDNT4TvTMSqsTZvdAokc8e5xsZ+SsxvOCOPoyEeOJQ=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
@@ -1286,7 +1221,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@@ -1382,7 +1316,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
@@ -1449,7 +1382,6 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1483,8 +1415,6 @@ golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -1499,7 +1429,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -1562,7 +1491,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
@@ -1570,7 +1498,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
||||
@@ -8,12 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
rRegistry "github.com/cs3org/reva/v2/pkg/registry"
|
||||
consulr "github.com/go-micro/plugins/v4/registry/consul"
|
||||
etcdr "github.com/go-micro/plugins/v4/registry/etcd"
|
||||
kubernetesr "github.com/go-micro/plugins/v4/registry/kubernetes"
|
||||
mdnsr "github.com/go-micro/plugins/v4/registry/mdns"
|
||||
memr "github.com/go-micro/plugins/v4/registry/memory"
|
||||
natsr "github.com/go-micro/plugins/v4/registry/nats"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/natsjsregistry"
|
||||
mRegistry "go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/registry/cache"
|
||||
@@ -68,28 +63,6 @@ func GetRegistry(opts ...Option) mRegistry.Registry {
|
||||
case "memory":
|
||||
_reg = memr.NewRegistry()
|
||||
cfg.DisableCache = true // no cache needed for in-memory registry
|
||||
case "kubernetes":
|
||||
fmt.Println("Attention: kubernetes registry is deprecated, use nats-js-kv instead")
|
||||
_reg = kubernetesr.NewRegistry()
|
||||
case "nats":
|
||||
fmt.Println("Attention: nats registry is deprecated, use nats-js-kv instead")
|
||||
_reg = natsr.NewRegistry(
|
||||
mRegistry.Addrs(cfg.Addresses...),
|
||||
natsr.RegisterAction("put"),
|
||||
)
|
||||
case "etcd":
|
||||
fmt.Println("Attention: etcd registry is deprecated, use nats-js-kv instead")
|
||||
_reg = etcdr.NewRegistry(
|
||||
mRegistry.Addrs(cfg.Addresses...),
|
||||
)
|
||||
case "consul":
|
||||
fmt.Println("Attention: consul registry is deprecated, use nats-js-kv instead")
|
||||
_reg = consulr.NewRegistry(
|
||||
mRegistry.Addrs(cfg.Addresses...),
|
||||
)
|
||||
case "mdns":
|
||||
fmt.Println("Attention: mdns registry is deprecated, use nats-js-kv instead")
|
||||
_reg = mdnsr.NewRegistry()
|
||||
}
|
||||
|
||||
// Disable cache if wanted
|
||||
|
||||
@@ -57,11 +57,10 @@ type HTTPServiceTLS struct {
|
||||
|
||||
type Cache struct {
|
||||
Store string `yaml:"store" env:"OCIS_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES" desc:"A comma separated list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES" desc:"A comma separated list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"OCIS_CACHE_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
Table string `yaml:"table" env:"OCIS_CACHE_STORE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_CACHE_TTL" desc:"Time to live for events in the store. The duration can be set as number followed by a unit identifier like s, m or h." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_CACHE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured." introductionVersion:"pre5.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
AuthUsername string `yaml:"auth_username" env:"OCIS_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"pre5.0"`
|
||||
AuthPassword string `yaml:"auth_password" env:"OCIS_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"pre5.0"`
|
||||
|
||||
@@ -9,13 +9,9 @@ This package also configures the service registry which will be used to look up
|
||||
Available registries are:
|
||||
|
||||
- nats-js-kv (default)
|
||||
- kubernetes
|
||||
- memory
|
||||
- etcd (deprecated)
|
||||
- consul (deprecated)
|
||||
- mdns (deprecated)
|
||||
|
||||
To configure which registry to use, you have to set the environment variable `MICRO_REGISTRY`, and for all except `memory` and `mdns` you also have to set the registry address via `MICRO_REGISTRY_ADDRESS`.
|
||||
To configure which registry to use, you have to set the environment variable `MICRO_REGISTRY`, and for all except `memory` you also have to set the registry address via `MICRO_REGISTRY_ADDRESS`.
|
||||
|
||||
## Memory limits
|
||||
|
||||
|
||||
@@ -79,7 +79,6 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
evStore := store.Create(
|
||||
store.Store(cfg.Store.Store),
|
||||
store.TTL(cfg.Store.TTL),
|
||||
store.Size(cfg.Store.Size),
|
||||
microstore.Nodes(cfg.Store.Nodes...),
|
||||
microstore.Database(cfg.Store.Database),
|
||||
microstore.Table(cfg.Store.Table),
|
||||
|
||||
@@ -47,12 +47,11 @@ type Events struct {
|
||||
|
||||
// Store configures the store to use
|
||||
type Store struct {
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;ACTIVITYLOG_STORE" desc:"The type of the store. Supported values are: 'memory', 'ocmem', 'etcd', 'redis', 'redis-sentinel', 'nats-js', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;ACTIVITYLOG_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;ACTIVITYLOG_STORE" desc:"The type of the store. Supported values are: 'memory', 'nats-js-kv', 'redis-sentinel', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;ACTIVITYLOG_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"ACTIVITYLOG_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
Table string `yaml:"table" env:"ACTIVITYLOG_STORE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_PERSISTENT_STORE_TTL;ACTIVITYLOG_STORE_TTL" desc:"Time to live for events in the store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_PERSISTENT_STORE_SIZE;ACTIVITYLOG_STORE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not explicitly set as default." introductionVersion:"pre5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_PERSISTENT_STORE_AUTH_USERNAME;ACTIVITYLOG_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_PERSISTENT_STORE_AUTH_PASSWORD;ACTIVITYLOG_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
}
|
||||
|
||||
@@ -73,8 +73,7 @@ type ClamAV struct {
|
||||
|
||||
// ICAP provides configuration options for icap
|
||||
type ICAP struct {
|
||||
DeprecatedTimeout int64 `yaml:"timeout" env:"ANTIVIRUS_ICAP_TIMEOUT" desc:"Timeout for the ICAP client." introductionVersion:"pre5.0" deprecationVersion:"5.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"Changing the envvar type for consistency reasons." deprecationReplacement:"ANTIVIRUS_ICAP_SCAN_TIMEOUT"`
|
||||
Timeout time.Duration `yaml:"scan_timeout" env:"ANTIVIRUS_ICAP_SCAN_TIMEOUT" desc:"Scan timeout for the ICAP client. Defaults to '5m' (5 minutes). See the Environment Variable Types description for more details." introductionVersion:"5.0"`
|
||||
URL string `yaml:"url" env:"ANTIVIRUS_ICAP_URL" desc:"URL of the ICAP server." introductionVersion:"pre5.0"`
|
||||
Service string `yaml:"service" env:"ANTIVIRUS_ICAP_SERVICE" desc:"The name of the ICAP service." introductionVersion:"pre5.0"`
|
||||
Timeout time.Duration `yaml:"scan_timeout" env:"ANTIVIRUS_ICAP_SCAN_TIMEOUT" desc:"Scan timeout for the ICAP client. Defaults to '5m' (5 minutes). See the Environment Variable Types description for more details." introductionVersion:"5.0"`
|
||||
URL string `yaml:"url" env:"ANTIVIRUS_ICAP_URL" desc:"URL of the ICAP server." introductionVersion:"pre5.0"`
|
||||
Service string `yaml:"service" env:"ANTIVIRUS_ICAP_SERVICE" desc:"The name of the ICAP service." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@ package parser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/v2/services/antivirus/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/antivirus/pkg/config/defaults"
|
||||
|
||||
@@ -36,10 +34,5 @@ func ParseConfig(cfg *config.Config) error {
|
||||
|
||||
// Validate validates our little config
|
||||
func Validate(cfg *config.Config) error {
|
||||
if cfg.Scanner.ICAP.DeprecatedTimeout != 0 {
|
||||
cfg.Scanner.ICAP.Timeout = time.Duration(cfg.Scanner.ICAP.DeprecatedTimeout) * time.Second
|
||||
log.Deprecation("ANTIVIRUS_ICAP_TIMEOUT is deprecated, use ANTIVIRUS_ICAP_SCAN_TIMEOUT instead")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,10 +17,6 @@ The `eventhistory` service stores each consumed event via the configured store i
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
st := store.Create(
|
||||
store.Store(cfg.Store.Store),
|
||||
store.TTL(cfg.Store.TTL),
|
||||
store.Size(cfg.Store.Size),
|
||||
microstore.Nodes(cfg.Store.Nodes...),
|
||||
microstore.Database(cfg.Store.Database),
|
||||
microstore.Table(cfg.Store.Table),
|
||||
|
||||
@@ -37,12 +37,11 @@ type GRPCConfig struct {
|
||||
|
||||
// Store configures the store to use
|
||||
type Store struct {
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;EVENTHISTORY_STORE" desc:"The type of the store. Supported values are: 'memory', 'ocmem', 'etcd', 'redis', 'redis-sentinel', 'nats-js', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;EVENTHISTORY_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;EVENTHISTORY_STORE" desc:"The type of the store. Supported values are: 'memory', 'nats-js-kv', 'redis-sentinel', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;EVENTHISTORY_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"EVENTHISTORY_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
Table string `yaml:"table" env:"EVENTHISTORY_STORE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_PERSISTENT_STORE_TTL;EVENTHISTORY_STORE_TTL" desc:"Time to live for events in the store. Defaults to '336h' (2 weeks). See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_PERSISTENT_STORE_SIZE;EVENTHISTORY_STORE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived and used from the ocmem package though no explicit default was set." introductionVersion:"pre5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_PERSISTENT_STORE_AUTH_USERNAME;EVENTHISTORY_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_PERSISTENT_STORE_AUTH_PASSWORD;EVENTHISTORY_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
}
|
||||
|
||||
@@ -51,10 +51,6 @@ The `frontend` service can use a configured store via `FRONTEND_OCS_STAT_CACHE_S
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -129,11 +129,10 @@ type OCS struct {
|
||||
HomeNamespace string `yaml:"home_namespace" env:"FRONTEND_OCS_PERSONAL_NAMESPACE" desc:"Home namespace identifier." introductionVersion:"pre5.0"`
|
||||
AdditionalInfoAttribute string `yaml:"additional_info_attribute" env:"FRONTEND_OCS_ADDITIONAL_INFO_ATTRIBUTE" desc:"Additional information attribute for the user like {{.Mail}}." introductionVersion:"pre5.0"`
|
||||
StatCacheType string `yaml:"stat_cache_type" env:"OCIS_CACHE_STORE;FRONTEND_OCS_STAT_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
StatCacheNodes []string `yaml:"stat_cache_nodes" env:"OCIS_CACHE_STORE_NODES;FRONTEND_OCS_STAT_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
StatCacheNodes []string `yaml:"stat_cache_nodes" env:"OCIS_CACHE_STORE_NODES;FRONTEND_OCS_STAT_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
StatCacheDatabase string `yaml:"stat_cache_database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
StatCacheTable string `yaml:"stat_cache_table" env:"FRONTEND_OCS_STAT_CACHE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
StatCacheTTL time.Duration `yaml:"stat_cache_ttl" env:"OCIS_CACHE_TTL;FRONTEND_OCS_STAT_CACHE_TTL" desc:"Default time to live for user info in the cache. Only applied when access tokens has no expiration. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
StatCacheSize int `yaml:"stat_cache_size" env:"OCIS_CACHE_SIZE;FRONTEND_OCS_STAT_CACHE_SIZE" desc:"Max number of entries to hold in the cache." introductionVersion:"pre5.0"`
|
||||
StatCacheDisablePersistence bool `yaml:"stat_cache_disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;FRONTEND_OCS_STAT_CACHE_DISABLE_PERSISTENCE" desc:"Disable persistence of the cache. Only applies when using the 'nats-js-kv' store type. Defaults to false." introductionVersion:"5.0"`
|
||||
StatCacheAuthUsername string `yaml:"stat_cache_auth_username" env:"OCIS_CACHE_AUTH_USERNAME;FRONTEND_OCS_STAT_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when using the 'nats-js-kv' store type." introductionVersion:"5.0"`
|
||||
StatCacheAuthPassword string `yaml:"stat_cache_auth_password" env:"OCIS_CACHE_AUTH_PASSWORD;FRONTEND_OCS_STAT_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when using the 'nats-js-kv' store type." introductionVersion:"5.0"`
|
||||
|
||||
@@ -168,7 +168,6 @@ func FrontendConfigFromStruct(cfg *config.Config, logger log.Logger) (map[string
|
||||
"cache_database": cfg.OCS.StatCacheDatabase,
|
||||
"cache_table": cfg.OCS.StatCacheTable,
|
||||
"cache_ttl": cfg.OCS.StatCacheTTL,
|
||||
"cache_size": cfg.OCS.StatCacheSize,
|
||||
"cache_disable_persistence": cfg.OCS.StatCacheDisablePersistence,
|
||||
"cache_auth_username": cfg.OCS.StatCacheAuthUsername,
|
||||
"cache_auth_password": cfg.OCS.StatCacheAuthPassword,
|
||||
|
||||
@@ -15,10 +15,6 @@ Use `OCIS_CACHE_STORE` (`GATEWAY_PROVIDER_CACHE_STORE`, `GATEWAY_CREATE_HOME_CAC
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -87,18 +87,16 @@ type StorageRegistry struct {
|
||||
// Cache holds cache config
|
||||
type Cache struct {
|
||||
ProviderCacheStore string `yaml:"provider_cache_store" env:"OCIS_CACHE_STORE;GATEWAY_PROVIDER_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
ProviderCacheNodes []string `yaml:"provider_cache_nodes" env:"OCIS_CACHE_STORE_NODES;GATEWAY_PROVIDER_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
ProviderCacheNodes []string `yaml:"provider_cache_nodes" env:"OCIS_CACHE_STORE_NODES;GATEWAY_PROVIDER_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
ProviderCacheDatabase string `yaml:"provider_cache_database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
ProviderCacheTTL time.Duration `yaml:"provider_cache_ttl" env:"OCIS_CACHE_TTL;GATEWAY_PROVIDER_CACHE_TTL" desc:"Default time to live for user info in the cache. Only applied when access tokens has no expiration. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
ProviderCacheSize int `yaml:"provider_cache_size" env:"OCIS_CACHE_SIZE;GATEWAY_PROVIDER_CACHE_SIZE" desc:"The maximum quantity of items in the cache. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not explicitly set as default." introductionVersion:"pre5.0"`
|
||||
ProviderCacheDisablePersistence bool `yaml:"provider_cache_disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;GATEWAY_PROVIDER_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the provider cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
ProviderCacheAuthUsername string `yaml:"provider_cache_auth_username" env:"OCIS_CACHE_AUTH_USERNAME;GATEWAY_PROVIDER_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
ProviderCacheAuthPassword string `yaml:"provider_cache_auth_password" env:"OCIS_CACHE_AUTH_PASSWORD;GATEWAY_PROVIDER_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
CreateHomeCacheStore string `yaml:"create_home_cache_store" env:"OCIS_CACHE_STORE;GATEWAY_CREATE_HOME_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
CreateHomeCacheNodes []string `yaml:"create_home_cache_nodes" env:"OCIS_CACHE_STORE_NODES;GATEWAY_CREATE_HOME_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
CreateHomeCacheNodes []string `yaml:"create_home_cache_nodes" env:"OCIS_CACHE_STORE_NODES;GATEWAY_CREATE_HOME_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
CreateHomeCacheDatabase string `yaml:"create_home_cache_database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
CreateHomeCacheTTL time.Duration `yaml:"create_home_cache_ttl" env:"OCIS_CACHE_TTL;GATEWAY_CREATE_HOME_CACHE_TTL" desc:"Default time to live for user info in the cache. Only applied when access tokens has no expiration. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
CreateHomeCacheSize int `yaml:"create_home_cache_size" env:"OCIS_CACHE_SIZE;GATEWAY_CREATE_HOME_CACHE_SIZE" desc:"The maximum quantity of items in the cache. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not explicitly set as default." introductionVersion:"pre5.0"`
|
||||
CreateHomeCacheDisablePersistence bool `yaml:"create_home_cache_disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;GATEWAY_CREATE_HOME_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the create home cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
CreateHomeCacheAuthUsername string `yaml:"create_home_cache_auth_username" env:"OCIS_CACHE_AUTH_USERNAME;GATEWAY_CREATE_HOME_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
CreateHomeCacheAuthPassword string `yaml:"create_home_cache_auth_password" env:"OCIS_CACHE_AUTH_PASSWORD;GATEWAY_CREATE_HOME_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
|
||||
@@ -71,7 +71,6 @@ func GatewayConfigFromStruct(cfg *config.Config, logger log.Logger) map[string]i
|
||||
"cache_database": cfg.Cache.ProviderCacheDatabase,
|
||||
"cache_table": "provider",
|
||||
"cache_ttl": cfg.Cache.ProviderCacheTTL,
|
||||
"cache_size": cfg.Cache.ProviderCacheSize,
|
||||
"disable_persistence": cfg.Cache.ProviderCacheDisablePersistence,
|
||||
"cache_auth_username": cfg.Cache.ProviderCacheAuthUsername,
|
||||
"cache_auth_password": cfg.Cache.ProviderCacheAuthPassword,
|
||||
@@ -82,7 +81,6 @@ func GatewayConfigFromStruct(cfg *config.Config, logger log.Logger) map[string]i
|
||||
"cache_database": cfg.Cache.CreateHomeCacheDatabase,
|
||||
"cache_table": "create_personal_space",
|
||||
"cache_ttl": cfg.Cache.CreateHomeCacheTTL,
|
||||
"cache_size": cfg.Cache.CreateHomeCacheSize,
|
||||
"cache_disable_persistence": cfg.Cache.CreateHomeCacheDisablePersistence,
|
||||
"cache_auth_username": cfg.Cache.CreateHomeCacheAuthUsername,
|
||||
"cache_auth_password": cfg.Cache.CreateHomeCacheAuthPassword,
|
||||
|
||||
@@ -66,10 +66,6 @@ The `graph` service can use a configured store via `GRAPH_CACHE_STORE`. Possible
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -5,11 +5,10 @@ import "time"
|
||||
// Cache defines the available configuration for a cache store
|
||||
type Cache struct {
|
||||
Store string `yaml:"store" env:"OCIS_CACHE_STORE;GRAPH_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;GRAPH_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;GRAPH_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"GRAPH_CACHE_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
Table string `yaml:"table" env:"GRAPH_CACHE_STORE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_CACHE_TTL;GRAPH_CACHE_TTL" desc:"Time to live for cache records in the graph. Defaults to '336h' (2 weeks). See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_CACHE_SIZE;GRAPH_CACHE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not explicitly set as default." introductionVersion:"pre5.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;GRAPH_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_CACHE_AUTH_USERNAME;GRAPH_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_CACHE_AUTH_PASSWORD;GRAPH_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
|
||||
@@ -155,7 +155,6 @@ func EnsureDefaults(cfg *config.Config) {
|
||||
cfg.Cache = &config.Cache{
|
||||
Store: cfg.Commons.Cache.Store,
|
||||
Nodes: cfg.Commons.Cache.Nodes,
|
||||
Size: cfg.Commons.Cache.Size,
|
||||
}
|
||||
} else if cfg.Cache == nil {
|
||||
cfg.Cache = &config.Cache{}
|
||||
|
||||
@@ -182,7 +182,6 @@ func NewService(opts ...Option) (Graph, error) { //nolint:maintidx
|
||||
storeOptions := []microstore.Option{
|
||||
store.Store(options.Config.Cache.Store),
|
||||
store.TTL(options.Config.Cache.TTL),
|
||||
store.Size(options.Config.Cache.Size),
|
||||
microstore.Nodes(options.Config.Cache.Nodes...),
|
||||
microstore.Database(options.Config.Cache.Database),
|
||||
microstore.Table(options.Config.Cache.Table),
|
||||
|
||||
@@ -12,8 +12,6 @@ As the service name suggests, this service is based on [NATS](https://nats.io/)
|
||||
|
||||
By default, `nats-js-kv` is configured as embedded default registry via the `MICRO_REGISTRY` environment variable. If you do not want using the build-in nats registry, set `MICRO_REGISTRY_ADDRESS` to the address of the nats-js cluster, which is the same value as `OCIS_EVENTS_ENDPOINT`. Optionally use `MICRO_REGISTRY_AUTH_USERNAME` and `MICRO_REGISTRY_AUTH_PASSWORD` to authenticate with the external nats cluster.
|
||||
|
||||
Note that when `MICRO_REGISTRY` is configured using `kubernetes`, the NATS service will not be used but the Kubernetes registry. In this case, the `MICRO_REGISTRY_ADDRESS` environment variable needs to be set to the url of the Kubernetes registry.
|
||||
|
||||
## Persistance
|
||||
|
||||
To be able to deliver events even after a system or service restart, nats will store events in a folder on the local filesystem. This folder can be specified by setting the `NATS_NATS_STORE_DIR` enviroment variable. If not set, the service will fall back to `$OCIS_BASE_DATA_PATH/nats`.
|
||||
|
||||
@@ -84,14 +84,9 @@ func (m Mail) getMailClient() (*mail.SMTPClient, error) {
|
||||
}
|
||||
|
||||
switch strings.ToLower(m.conf.Notifications.SMTP.Encryption) {
|
||||
case "tls":
|
||||
server.Encryption = mail.EncryptionTLS
|
||||
server.TLSConfig.ServerName = m.conf.Notifications.SMTP.Host
|
||||
case "starttls":
|
||||
server.Encryption = mail.EncryptionSTARTTLS
|
||||
server.TLSConfig.ServerName = m.conf.Notifications.SMTP.Host
|
||||
case "ssl":
|
||||
server.Encryption = mail.EncryptionSSL
|
||||
case "ssltls":
|
||||
server.Encryption = mail.EncryptionSSLTLS
|
||||
case "none":
|
||||
|
||||
@@ -46,7 +46,7 @@ type SMTP struct {
|
||||
Password string `yaml:"smtp_password" env:"NOTIFICATIONS_SMTP_PASSWORD" desc:"Password for the SMTP host to connect to." introductionVersion:"pre5.0"`
|
||||
Insecure bool `yaml:"insecure" env:"NOTIFICATIONS_SMTP_INSECURE" desc:"Allow insecure connections to the SMTP server." introductionVersion:"pre5.0"`
|
||||
Authentication string `yaml:"smtp_authentication" env:"NOTIFICATIONS_SMTP_AUTHENTICATION" desc:"Authentication method for the SMTP communication. Possible values are 'login', 'plain', 'crammd5', 'none' or 'auto'. If set to 'auto' or unset, the authentication method is automatically negotiated with the server." introductionVersion:"pre5.0"`
|
||||
Encryption string `yaml:"smtp_encryption" env:"NOTIFICATIONS_SMTP_ENCRYPTION" desc:"Encryption method for the SMTP communication. Possible values are 'starttls', 'ssl', 'ssltls', 'tls' and 'none'." introductionVersion:"pre5.0" deprecationVersion:"5.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"The NOTIFICATIONS_SMTP_ENCRYPTION values 'ssl' and 'tls' are deprecated and will be removed in the future." deprecationReplacement:"Use 'starttls' instead of 'tls' and 'ssltls' instead of 'ssl'."`
|
||||
Encryption string `yaml:"smtp_encryption" env:"NOTIFICATIONS_SMTP_ENCRYPTION" desc:"Encryption method for the SMTP communication. Possible values are 'starttls', 'ssltls' and 'none'." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
// Events combines the configuration options for the event bus.
|
||||
|
||||
@@ -14,7 +14,7 @@ Possible stores that can be configured via `OCS_PRESIGNEDURL_SIGNING_KEYS_STORE`
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `ocisstoreservice`: Stores data in the legacy ocis store service. Requires setting `OCS_PRESIGNEDURL_SIGNING_KEYS_STORE_NODES` to `com.owncloud.api.store`.
|
||||
|
||||
The `memory` or `ocmem` stores cannot be used as they do not share the memory from the ocs service signing key memory store, even in a single process.
|
||||
The `memory` store cannot be used as it does not share the memory from the ocs service signing key memory store, even in a single process.
|
||||
|
||||
Make sure to configure the same store in the proxy service.
|
||||
|
||||
|
||||
@@ -23,10 +23,6 @@ The `postprocessing` service stores its metadata via the configured store in `PO
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
st := store.Create(
|
||||
store.Store(cfg.Store.Store),
|
||||
store.TTL(cfg.Store.TTL),
|
||||
store.Size(cfg.Store.Size),
|
||||
microstore.Nodes(cfg.Store.Nodes...),
|
||||
microstore.Database(cfg.Store.Database),
|
||||
microstore.Table(cfg.Store.Table),
|
||||
|
||||
@@ -55,12 +55,11 @@ type Debug struct {
|
||||
|
||||
// Store configures the store to use
|
||||
type Store struct {
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;POSTPROCESSING_STORE" desc:"The type of the store. Supported values are: 'memory', 'ocmem', 'etcd', 'redis', 'redis-sentinel', 'nats-js', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;POSTPROCESSING_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;POSTPROCESSING_STORE" desc:"The type of the store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;POSTPROCESSING_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"POSTPROCESSING_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
Table string `yaml:"table" env:"POSTPROCESSING_STORE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_PERSISTENT_STORE_TTL;POSTPROCESSING_STORE_TTL" desc:"Time to live for events in the store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_PERSISTENT_STORE_SIZE;POSTPROCESSING_STORE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not exclicitly set as default." introductionVersion:"pre5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_PERSISTENT_STORE_AUTH_USERNAME;POSTPROCESSING_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_PERSISTENT_STORE_AUTH_PASSWORD;POSTPROCESSING_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
}
|
||||
|
||||
@@ -214,10 +214,6 @@ The `proxy` service can use a configured store via `PROXY_OIDC_USERINFO_CACHE_ST
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
@@ -238,7 +234,7 @@ To authenticate presigned URLs the proxy service needs to read signing keys from
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `ocisstoreservice`: Stores data in the legacy ocis store service. Requires setting `PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE_NODES` to `com.owncloud.api.store`.
|
||||
|
||||
The `memory` or `ocmem` stores cannot be used as they do not share the memory from the ocs service signing key memory store, even in a single process.
|
||||
The `memory` store cannot be used as it does not share the memory from the ocs service signing key memory store, even in a single process.
|
||||
|
||||
Make sure to configure the same store in the ocs service.
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
userInfoCache := store.Create(
|
||||
store.Store(cfg.OIDC.UserinfoCache.Store),
|
||||
store.TTL(cfg.OIDC.UserinfoCache.TTL),
|
||||
store.Size(cfg.OIDC.UserinfoCache.Size),
|
||||
microstore.Nodes(cfg.OIDC.UserinfoCache.Nodes...),
|
||||
microstore.Database(cfg.OIDC.UserinfoCache.Database),
|
||||
microstore.Table(cfg.OIDC.UserinfoCache.Table),
|
||||
|
||||
@@ -128,11 +128,10 @@ type JWKS struct {
|
||||
// Cache is a TTL cache configuration.
|
||||
type Cache struct {
|
||||
Store string `yaml:"store" env:"OCIS_CACHE_STORE;PROXY_OIDC_USERINFO_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"addresses" env:"OCIS_CACHE_STORE_NODES;PROXY_OIDC_USERINFO_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"addresses" env:"OCIS_CACHE_STORE_NODES;PROXY_OIDC_USERINFO_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
Table string `yaml:"table" env:"PROXY_OIDC_USERINFO_CACHE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_CACHE_TTL;PROXY_OIDC_USERINFO_CACHE_TTL" desc:"Default time to live for user info in the user info cache. Only applied when access tokens has no expiration. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_CACHE_SIZE;PROXY_OIDC_USERINFO_CACHE_SIZE" desc:"The maximum quantity of items in the user info cache. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not explicitly set as default." introductionVersion:"pre5.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;PROXY_OIDC_USERINFO_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"pre5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_CACHE_AUTH_USERNAME;PROXY_OIDC_USERINFO_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_CACHE_AUTH_PASSWORD;PROXY_OIDC_USERINFO_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
|
||||
@@ -303,7 +303,6 @@ func EnsureDefaults(cfg *config.Config) {
|
||||
cfg.OIDC.UserinfoCache = &config.Cache{
|
||||
Store: cfg.Commons.Cache.Store,
|
||||
Nodes: cfg.Commons.Cache.Nodes,
|
||||
Size: cfg.Commons.Cache.Size,
|
||||
}
|
||||
} else if cfg.OIDC.UserinfoCache == nil {
|
||||
cfg.OIDC.UserinfoCache = &config.Cache{}
|
||||
|
||||
@@ -39,10 +39,6 @@ The store used for the cache can be configured using the `SETTINGS_CACHE_STORE`
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -56,12 +56,11 @@ type Metadata struct {
|
||||
// Cache configures the cache of the Metadata store
|
||||
type Cache struct {
|
||||
Store string `yaml:"store" env:"OCIS_CACHE_STORE;SETTINGS_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"addresses" env:"OCIS_CACHE_STORE_NODES;SETTINGS_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"addresses" env:"OCIS_CACHE_STORE_NODES;SETTINGS_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
FileTable string `yaml:"files_table" env:"SETTINGS_FILE_CACHE_TABLE" desc:"The database table the store should use for the file cache." introductionVersion:"pre5.0"`
|
||||
DirectoryTable string `yaml:"directories_table" env:"SETTINGS_DIRECTORY_CACHE_TABLE" desc:"The database table the store should use for the directory cache." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_CACHE_TTL;SETTINGS_CACHE_TTL" desc:"Default time to live for entries in the cache. Only applied when access tokens has no expiration. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_CACHE_SIZE;SETTINGS_CACHE_SIZE" desc:"The maximum quantity of items in the cache. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not exclicitly set as default." introductionVersion:"pre5.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;SETTINGS_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_CACHE_AUTH_USERNAME;SETTINGS_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_CACHE_AUTH_PASSWORD;SETTINGS_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
|
||||
@@ -135,7 +135,6 @@ func (c *CachedMDC) Init(ctx context.Context, id string) error {
|
||||
c.dirsCache = store.Create(
|
||||
store.Store(c.cfg.Metadata.Cache.Store),
|
||||
store.TTL(c.cfg.Metadata.Cache.TTL),
|
||||
store.Size(c.cfg.Metadata.Cache.Size),
|
||||
microstore.Nodes(c.cfg.Metadata.Cache.Nodes...),
|
||||
microstore.Database(c.cfg.Metadata.Cache.Database),
|
||||
microstore.Table(c.cfg.Metadata.Cache.DirectoryTable),
|
||||
@@ -145,7 +144,6 @@ func (c *CachedMDC) Init(ctx context.Context, id string) error {
|
||||
c.filesCache = store.Create(
|
||||
store.Store(c.cfg.Metadata.Cache.Store),
|
||||
store.TTL(c.cfg.Metadata.Cache.TTL),
|
||||
store.Size(c.cfg.Metadata.Cache.Size),
|
||||
microstore.Nodes(c.cfg.Metadata.Cache.Nodes...),
|
||||
microstore.Database(c.cfg.Metadata.Cache.Database),
|
||||
microstore.Table(c.cfg.Metadata.Cache.FileTable),
|
||||
|
||||
@@ -9,10 +9,6 @@ The `storage-system` service caches file metadata via the configured store in `S
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -88,10 +88,9 @@ type OCISDriver struct {
|
||||
// Cache holds cache config
|
||||
type Cache struct {
|
||||
Store string `yaml:"store" env:"OCIS_CACHE_STORE;STORAGE_SYSTEM_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;STORAGE_SYSTEM_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;STORAGE_SYSTEM_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_CACHE_TTL;STORAGE_SYSTEM_CACHE_TTL" desc:"Default time to live for user info in the user info cache. Only applied when access tokens has no expiration. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_CACHE_SIZE;STORAGE_SYSTEM_CACHE_SIZE" desc:"The maximum quantity of items in the user info cache. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not exclicitly set as default." introductionVersion:"pre5.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;STORAGE_SYSTEM_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
AuthUsername string `yaml:"auth_username" env:"OCIS_CACHE_AUTH_USERNAME;STORAGE_SYSTEM_CACHE_AUTH_USERNAME" desc:"Username for the configured store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"auth_password" env:"OCIS_CACHE_AUTH_PASSWORD;STORAGE_SYSTEM_CACHE_AUTH_PASSWORD" desc:"Password for the configured store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
|
||||
@@ -168,7 +168,6 @@ func metadataDrivers(localEndpoint string, cfg *config.Config) map[string]interf
|
||||
"cache_nodes": cfg.FileMetadataCache.Nodes,
|
||||
"cache_database": cfg.FileMetadataCache.Database,
|
||||
"cache_ttl": cfg.FileMetadataCache.TTL,
|
||||
"cache_size": cfg.FileMetadataCache.Size,
|
||||
"cache_disable_persistence": cfg.FileMetadataCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.FileMetadataCache.AuthUsername,
|
||||
"cache_auth_password": cfg.FileMetadataCache.AuthPassword,
|
||||
|
||||
@@ -219,10 +219,6 @@ The `storage-users` service caches stat, metadata and uuids of files and folders
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -223,10 +223,9 @@ type Events struct {
|
||||
// FilemetadataCache holds cache config
|
||||
type FilemetadataCache struct {
|
||||
Store string `yaml:"store" env:"OCIS_CACHE_STORE;STORAGE_USERS_FILEMETADATA_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;STORAGE_USERS_FILEMETADATA_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;STORAGE_USERS_FILEMETADATA_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_CACHE_TTL;STORAGE_USERS_FILEMETADATA_CACHE_TTL" desc:"Default time to live for user info in the user info cache. Only applied when access tokens has no expiration. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_CACHE_SIZE;STORAGE_USERS_FILEMETADATA_CACHE_SIZE" desc:"The maximum quantity of items in the user info cache. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not exclicitly set as default." introductionVersion:"pre5.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;STORAGE_USERS_FILEMETADATA_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_CACHE_AUTH_USERNAME;STORAGE_USERS_FILEMETADATA_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_CACHE_AUTH_PASSWORD;STORAGE_USERS_FILEMETADATA_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
@@ -235,10 +234,9 @@ type FilemetadataCache struct {
|
||||
// IDCache holds cache config
|
||||
type IDCache struct {
|
||||
Store string `yaml:"store" env:"OCIS_CACHE_STORE;STORAGE_USERS_ID_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;STORAGE_USERS_ID_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_CACHE_STORE_NODES;STORAGE_USERS_ID_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"OCIS_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_CACHE_TTL;STORAGE_USERS_ID_CACHE_TTL" desc:"Default time to live for user info in the user info cache. Only applied when access tokens have no expiration. Defaults to 300s which is derived from the underlaying package though not explicitly set as default. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_CACHE_SIZE;STORAGE_USERS_ID_CACHE_SIZE" desc:"The maximum quantity of items in the user info cache. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not exclicitly set as default." introductionVersion:"pre5.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OCIS_CACHE_DISABLE_PERSISTENCE;STORAGE_USERS_ID_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_CACHE_AUTH_USERNAME;STORAGE_USERS_ID_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_CACHE_AUTH_PASSWORD;STORAGE_USERS_ID_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
|
||||
@@ -101,7 +101,6 @@ func Posix(cfg *config.Config, enableFSWatch bool) map[string]interface{} {
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_size": cfg.IDCache.Size,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -111,7 +110,6 @@ func Posix(cfg *config.Config, enableFSWatch bool) map[string]interface{} {
|
||||
"cache_nodes": cfg.FilemetadataCache.Nodes,
|
||||
"cache_database": cfg.FilemetadataCache.Database,
|
||||
"cache_ttl": cfg.FilemetadataCache.TTL,
|
||||
"cache_size": cfg.FilemetadataCache.Size,
|
||||
"cache_disable_persistence": cfg.FilemetadataCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.FilemetadataCache.AuthUsername,
|
||||
"cache_auth_password": cfg.FilemetadataCache.AuthPassword,
|
||||
@@ -186,7 +184,6 @@ func Ocis(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.FilemetadataCache.Nodes,
|
||||
"cache_database": cfg.FilemetadataCache.Database,
|
||||
"cache_ttl": cfg.FilemetadataCache.TTL,
|
||||
"cache_size": cfg.FilemetadataCache.Size,
|
||||
"cache_disable_persistence": cfg.FilemetadataCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.FilemetadataCache.AuthUsername,
|
||||
"cache_auth_password": cfg.FilemetadataCache.AuthPassword,
|
||||
@@ -196,7 +193,6 @@ func Ocis(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_size": cfg.IDCache.Size,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -242,7 +238,6 @@ func OcisNoEvents(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.FilemetadataCache.Nodes,
|
||||
"cache_database": cfg.FilemetadataCache.Database,
|
||||
"cache_ttl": cfg.FilemetadataCache.TTL,
|
||||
"cache_size": cfg.FilemetadataCache.Size,
|
||||
"cache_disable_persistence": cfg.FilemetadataCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.FilemetadataCache.AuthUsername,
|
||||
"cache_auth_password": cfg.FilemetadataCache.AuthPassword,
|
||||
@@ -252,7 +247,6 @@ func OcisNoEvents(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_size": cfg.IDCache.Size,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -313,7 +307,6 @@ func S3NG(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.FilemetadataCache.Nodes,
|
||||
"cache_database": cfg.FilemetadataCache.Database,
|
||||
"cache_ttl": cfg.FilemetadataCache.TTL,
|
||||
"cache_size": cfg.FilemetadataCache.Size,
|
||||
"cache_disable_persistence": cfg.FilemetadataCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.FilemetadataCache.AuthUsername,
|
||||
"cache_auth_password": cfg.FilemetadataCache.AuthPassword,
|
||||
@@ -323,7 +316,6 @@ func S3NG(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_size": cfg.IDCache.Size,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -373,7 +365,6 @@ func S3NGNoEvents(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.FilemetadataCache.Nodes,
|
||||
"cache_database": cfg.FilemetadataCache.Database,
|
||||
"cache_ttl": cfg.FilemetadataCache.TTL,
|
||||
"cache_size": cfg.FilemetadataCache.Size,
|
||||
"cache_disable_persistence": cfg.FilemetadataCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.FilemetadataCache.AuthUsername,
|
||||
"cache_auth_password": cfg.FilemetadataCache.AuthPassword,
|
||||
@@ -383,7 +374,6 @@ func S3NGNoEvents(cfg *config.Config) map[string]interface{} {
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_size": cfg.IDCache.Size,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
|
||||
@@ -20,10 +20,6 @@ The `userlog` service persists information via the configured store in `USERLOG_
|
||||
- `redis-sentinel`: Stores data in a configured Redis Sentinel cluster.
|
||||
- `nats-js-kv`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
|
||||
- `noop`: Stores nothing. Useful for testing. Not recommended in production environments.
|
||||
- `ocmem`: Advanced in-memory store allowing max size. (deprecated)
|
||||
- `redis`: Stores data in a configured Redis cluster. (deprecated)
|
||||
- `etcd`: Stores data in a configured etcd cluster. (deprecated)
|
||||
- `nats-js`: Stores data using object-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/obj_store) (deprecated)
|
||||
|
||||
Other store types may work but are not supported currently.
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
st := store.Create(
|
||||
store.Store(cfg.Persistence.Store),
|
||||
store.TTL(cfg.Persistence.TTL),
|
||||
store.Size(cfg.Persistence.Size),
|
||||
microstore.Nodes(cfg.Persistence.Nodes...),
|
||||
microstore.Database(cfg.Persistence.Database),
|
||||
microstore.Table(cfg.Persistence.Table),
|
||||
|
||||
@@ -39,12 +39,11 @@ type Config struct {
|
||||
|
||||
// Persistence configures the store to use
|
||||
type Persistence struct {
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;USERLOG_STORE" desc:"The type of the store. Supported values are: 'memory', 'ocmem', 'etcd', 'redis', 'redis-sentinel', 'nats-js', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;USERLOG_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Store string `yaml:"store" env:"OCIS_PERSISTENT_STORE;USERLOG_STORE" desc:"The type of the store. Supported values are: 'memory', 'nats-js-kv', 'redis-sentinel', 'noop'. See the text description for details." introductionVersion:"pre5.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OCIS_PERSISTENT_STORE_NODES;USERLOG_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Database string `yaml:"database" env:"USERLOG_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"pre5.0"`
|
||||
Table string `yaml:"table" env:"USERLOG_STORE_TABLE" desc:"The database table the store should use." introductionVersion:"pre5.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OCIS_PERSISTENT_STORE_TTL;USERLOG_STORE_TTL" desc:"Time to live for events in the store. Defaults to '336h' (2 weeks). See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
|
||||
Size int `yaml:"size" env:"OCIS_PERSISTENT_STORE_SIZE;USERLOG_STORE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured. Defaults to 512 which is derived from the ocmem package though not exclicitly set as default." introductionVersion:"pre5.0"`
|
||||
AuthUsername string `yaml:"username" env:"OCIS_PERSISTENT_STORE_AUTH_USERNAME;USERLOG_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
AuthPassword string `yaml:"password" env:"OCIS_PERSISTENT_STORE_AUTH_PASSWORD;USERLOG_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"5.0"`
|
||||
}
|
||||
|
||||
@@ -31,10 +31,9 @@ type Config struct {
|
||||
|
||||
// Asset defines the available asset configuration.
|
||||
type Asset struct {
|
||||
DeprecatedPath string `yaml:"path" env:"WEB_ASSET_PATH" desc:"Serve ownCloud Web assets from a path on the filesystem instead of the builtin assets." introductionVersion:"pre5.0" deprecationVersion:"5.1.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"The WEB_ASSET_PATH is deprecated and will be removed in the future." deprecationReplacement:"Use WEB_ASSET_CORE_PATH instead."`
|
||||
CorePath string `yaml:"core_path" env:"WEB_ASSET_CORE_PATH" desc:"Serve ownCloud Web assets from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OCIS_BASE_DATA_PATH/web/assets/core" introductionVersion:"6.0.0"`
|
||||
ThemesPath string `yaml:"themes_path" env:"OCIS_ASSET_THEMES_PATH;WEB_ASSET_THEMES_PATH" desc:"Serve ownCloud themes from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OCIS_BASE_DATA_PATH/web/assets/themes" introductionVersion:"6.0.0"`
|
||||
AppsPath string `yaml:"apps_path" env:"WEB_ASSET_APPS_PATH" desc:"Serve ownCloud Web apps assets from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OCIS_BASE_DATA_PATH/web/assets/apps" introductionVersion:"6.0.0"`
|
||||
CorePath string `yaml:"core_path" env:"WEB_ASSET_CORE_PATH" desc:"Serve ownCloud Web assets from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OCIS_BASE_DATA_PATH/web/assets/core" introductionVersion:"6.0.0"`
|
||||
ThemesPath string `yaml:"themes_path" env:"OCIS_ASSET_THEMES_PATH;WEB_ASSET_THEMES_PATH" desc:"Serve ownCloud themes from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OCIS_BASE_DATA_PATH/web/assets/themes" introductionVersion:"6.0.0"`
|
||||
AppsPath string `yaml:"apps_path" env:"WEB_ASSET_APPS_PATH" desc:"Serve ownCloud Web apps assets from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OCIS_BASE_DATA_PATH/web/assets/apps" introductionVersion:"6.0.0"`
|
||||
}
|
||||
|
||||
// CustomStyle references additional css to be loaded into ownCloud Web.
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/config/envdecode"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
|
||||
"github.com/owncloud/ocis/v2/services/web/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/web/pkg/config/defaults"
|
||||
@@ -45,19 +44,5 @@ func Validate(cfg *config.Config) error {
|
||||
return shared.MissingJWTTokenError(cfg.Service.Name)
|
||||
}
|
||||
|
||||
// deprecation: migration requested
|
||||
// check if the config still uses the deprecated asset path, if so,
|
||||
// log a warning and copy the value to the setting that is actually used
|
||||
// this is to ensure a smooth transition from the old to the new core asset path (pre 5.1 to 5.1)
|
||||
if cfg.Asset.DeprecatedPath != "" {
|
||||
if cfg.Asset.CorePath == "" {
|
||||
cfg.Asset.CorePath = cfg.Asset.DeprecatedPath
|
||||
}
|
||||
|
||||
// message should be logged to the console,
|
||||
// do not use a logger here because the message MUST be visible independent of the log level
|
||||
log.Deprecation("WEB_ASSET_PATH is deprecated and will be removed in the future. Use WEB_ASSET_CORE_PATH instead.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
26
vendor/github.com/armon/go-metrics/.gitignore
generated
vendored
26
vendor/github.com/armon/go-metrics/.gitignore
generated
vendored
@@ -1,26 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
|
||||
/metrics.out
|
||||
|
||||
.idea
|
||||
13
vendor/github.com/armon/go-metrics/.travis.yml
generated
vendored
13
vendor/github.com/armon/go-metrics/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- "1.x"
|
||||
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
|
||||
install:
|
||||
- go get ./...
|
||||
|
||||
script:
|
||||
- go test ./...
|
||||
20
vendor/github.com/armon/go-metrics/LICENSE
generated
vendored
20
vendor/github.com/armon/go-metrics/LICENSE
generated
vendored
@@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Armon Dadgar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
91
vendor/github.com/armon/go-metrics/README.md
generated
vendored
91
vendor/github.com/armon/go-metrics/README.md
generated
vendored
@@ -1,91 +0,0 @@
|
||||
go-metrics
|
||||
==========
|
||||
|
||||
This library provides a `metrics` package which can be used to instrument code,
|
||||
expose application metrics, and profile runtime performance in a flexible manner.
|
||||
|
||||
Current API: [](https://godoc.org/github.com/armon/go-metrics)
|
||||
|
||||
Sinks
|
||||
-----
|
||||
|
||||
The `metrics` package makes use of a `MetricSink` interface to support delivery
|
||||
to any type of backend. Currently the following sinks are provided:
|
||||
|
||||
* StatsiteSink : Sinks to a [statsite](https://github.com/armon/statsite/) instance (TCP)
|
||||
* StatsdSink: Sinks to a [StatsD](https://github.com/etsy/statsd/) / statsite instance (UDP)
|
||||
* PrometheusSink: Sinks to a [Prometheus](http://prometheus.io/) metrics endpoint (exposed via HTTP for scrapes)
|
||||
* InmemSink : Provides in-memory aggregation, can be used to export stats
|
||||
* FanoutSink : Sinks to multiple sinks. Enables writing to multiple statsite instances for example.
|
||||
* BlackholeSink : Sinks to nowhere
|
||||
|
||||
In addition to the sinks, the `InmemSignal` can be used to catch a signal,
|
||||
and dump a formatted output of recent metrics. For example, when a process gets
|
||||
a SIGUSR1, it can dump to stderr recent performance metrics for debugging.
|
||||
|
||||
Labels
|
||||
------
|
||||
|
||||
Most metrics do have an equivalent ending with `WithLabels`, such methods
|
||||
allow to push metrics with labels and use some features of underlying Sinks
|
||||
(ex: translated into Prometheus labels).
|
||||
|
||||
Since some of these labels may increase greatly cardinality of metrics, the
|
||||
library allow to filter labels using a blacklist/whitelist filtering system
|
||||
which is global to all metrics.
|
||||
|
||||
* If `Config.AllowedLabels` is not nil, then only labels specified in this value will be sent to underlying Sink, otherwise, all labels are sent by default.
|
||||
* If `Config.BlockedLabels` is not nil, any label specified in this value will not be sent to underlying Sinks.
|
||||
|
||||
By default, both `Config.AllowedLabels` and `Config.BlockedLabels` are nil, meaning that
|
||||
no tags are filetered at all, but it allow to a user to globally block some tags with high
|
||||
cardinality at application level.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Here is an example of using the package:
|
||||
|
||||
```go
|
||||
func SlowMethod() {
|
||||
// Profiling the runtime of a method
|
||||
defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now())
|
||||
}
|
||||
|
||||
// Configure a statsite sink as the global metrics sink
|
||||
sink, _ := metrics.NewStatsiteSink("statsite:8125")
|
||||
metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink)
|
||||
|
||||
// Emit a Key/Value pair
|
||||
metrics.EmitKey([]string{"questions", "meaning of life"}, 42)
|
||||
```
|
||||
|
||||
Here is an example of setting up a signal handler:
|
||||
|
||||
```go
|
||||
// Setup the inmem sink and signal handler
|
||||
inm := metrics.NewInmemSink(10*time.Second, time.Minute)
|
||||
sig := metrics.DefaultInmemSignal(inm)
|
||||
metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm)
|
||||
|
||||
// Run some code
|
||||
inm.SetGauge([]string{"foo"}, 42)
|
||||
inm.EmitKey([]string{"bar"}, 30)
|
||||
|
||||
inm.IncrCounter([]string{"baz"}, 42)
|
||||
inm.IncrCounter([]string{"baz"}, 1)
|
||||
inm.IncrCounter([]string{"baz"}, 80)
|
||||
|
||||
inm.AddSample([]string{"method", "wow"}, 42)
|
||||
inm.AddSample([]string{"method", "wow"}, 100)
|
||||
inm.AddSample([]string{"method", "wow"}, 22)
|
||||
|
||||
....
|
||||
```
|
||||
|
||||
When a signal comes in, output like the following will be dumped to stderr:
|
||||
|
||||
[2014-01-28 14:57:33.04 -0800 PST][G] 'foo': 42.000
|
||||
[2014-01-28 14:57:33.04 -0800 PST][P] 'bar': 30.000
|
||||
[2014-01-28 14:57:33.04 -0800 PST][C] 'baz': Count: 3 Min: 1.000 Mean: 41.000 Max: 80.000 Stddev: 39.509
|
||||
[2014-01-28 14:57:33.04 -0800 PST][S] 'method.wow': Count: 3 Min: 22.000 Mean: 54.667 Max: 100.000 Stddev: 40.513
|
||||
12
vendor/github.com/armon/go-metrics/const_unix.go
generated
vendored
12
vendor/github.com/armon/go-metrics/const_unix.go
generated
vendored
@@ -1,12 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultSignal is used with DefaultInmemSignal
|
||||
DefaultSignal = syscall.SIGUSR1
|
||||
)
|
||||
13
vendor/github.com/armon/go-metrics/const_windows.go
generated
vendored
13
vendor/github.com/armon/go-metrics/const_windows.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultSignal is used with DefaultInmemSignal
|
||||
// Windows has no SIGUSR1, use SIGBREAK
|
||||
DefaultSignal = syscall.Signal(21)
|
||||
)
|
||||
339
vendor/github.com/armon/go-metrics/inmem.go
generated
vendored
339
vendor/github.com/armon/go-metrics/inmem.go
generated
vendored
@@ -1,339 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var spaceReplacer = strings.NewReplacer(" ", "_")
|
||||
|
||||
// InmemSink provides a MetricSink that does in-memory aggregation
|
||||
// without sending metrics over a network. It can be embedded within
|
||||
// an application to provide profiling information.
|
||||
type InmemSink struct {
|
||||
// How long is each aggregation interval
|
||||
interval time.Duration
|
||||
|
||||
// Retain controls how many metrics interval we keep
|
||||
retain time.Duration
|
||||
|
||||
// maxIntervals is the maximum length of intervals.
|
||||
// It is retain / interval.
|
||||
maxIntervals int
|
||||
|
||||
// intervals is a slice of the retained intervals
|
||||
intervals []*IntervalMetrics
|
||||
intervalLock sync.RWMutex
|
||||
|
||||
rateDenom float64
|
||||
}
|
||||
|
||||
// IntervalMetrics stores the aggregated metrics
|
||||
// for a specific interval
|
||||
type IntervalMetrics struct {
|
||||
sync.RWMutex
|
||||
|
||||
// The start time of the interval
|
||||
Interval time.Time
|
||||
|
||||
// Gauges maps the key to the last set value
|
||||
Gauges map[string]GaugeValue
|
||||
|
||||
// Points maps the string to the list of emitted values
|
||||
// from EmitKey
|
||||
Points map[string][]float32
|
||||
|
||||
// Counters maps the string key to a sum of the counter
|
||||
// values
|
||||
Counters map[string]SampledValue
|
||||
|
||||
// Samples maps the key to an AggregateSample,
|
||||
// which has the rolled up view of a sample
|
||||
Samples map[string]SampledValue
|
||||
|
||||
// done is closed when this interval has ended, and a new IntervalMetrics
|
||||
// has been created to receive any future metrics.
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// NewIntervalMetrics creates a new IntervalMetrics for a given interval
|
||||
func NewIntervalMetrics(intv time.Time) *IntervalMetrics {
|
||||
return &IntervalMetrics{
|
||||
Interval: intv,
|
||||
Gauges: make(map[string]GaugeValue),
|
||||
Points: make(map[string][]float32),
|
||||
Counters: make(map[string]SampledValue),
|
||||
Samples: make(map[string]SampledValue),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// AggregateSample is used to hold aggregate metrics
|
||||
// about a sample
|
||||
type AggregateSample struct {
|
||||
Count int // The count of emitted pairs
|
||||
Rate float64 // The values rate per time unit (usually 1 second)
|
||||
Sum float64 // The sum of values
|
||||
SumSq float64 `json:"-"` // The sum of squared values
|
||||
Min float64 // Minimum value
|
||||
Max float64 // Maximum value
|
||||
LastUpdated time.Time `json:"-"` // When value was last updated
|
||||
}
|
||||
|
||||
// Computes a Stddev of the values
|
||||
func (a *AggregateSample) Stddev() float64 {
|
||||
num := (float64(a.Count) * a.SumSq) - math.Pow(a.Sum, 2)
|
||||
div := float64(a.Count * (a.Count - 1))
|
||||
if div == 0 {
|
||||
return 0
|
||||
}
|
||||
return math.Sqrt(num / div)
|
||||
}
|
||||
|
||||
// Computes a mean of the values
|
||||
func (a *AggregateSample) Mean() float64 {
|
||||
if a.Count == 0 {
|
||||
return 0
|
||||
}
|
||||
return a.Sum / float64(a.Count)
|
||||
}
|
||||
|
||||
// Ingest is used to update a sample
|
||||
func (a *AggregateSample) Ingest(v float64, rateDenom float64) {
|
||||
a.Count++
|
||||
a.Sum += v
|
||||
a.SumSq += (v * v)
|
||||
if v < a.Min || a.Count == 1 {
|
||||
a.Min = v
|
||||
}
|
||||
if v > a.Max || a.Count == 1 {
|
||||
a.Max = v
|
||||
}
|
||||
a.Rate = float64(a.Sum) / rateDenom
|
||||
a.LastUpdated = time.Now()
|
||||
}
|
||||
|
||||
func (a *AggregateSample) String() string {
|
||||
if a.Count == 0 {
|
||||
return "Count: 0"
|
||||
} else if a.Stddev() == 0 {
|
||||
return fmt.Sprintf("Count: %d Sum: %0.3f LastUpdated: %s", a.Count, a.Sum, a.LastUpdated)
|
||||
} else {
|
||||
return fmt.Sprintf("Count: %d Min: %0.3f Mean: %0.3f Max: %0.3f Stddev: %0.3f Sum: %0.3f LastUpdated: %s",
|
||||
a.Count, a.Min, a.Mean(), a.Max, a.Stddev(), a.Sum, a.LastUpdated)
|
||||
}
|
||||
}
|
||||
|
||||
// NewInmemSinkFromURL creates an InmemSink from a URL. It is used
|
||||
// (and tested) from NewMetricSinkFromURL.
|
||||
func NewInmemSinkFromURL(u *url.URL) (MetricSink, error) {
|
||||
params := u.Query()
|
||||
|
||||
interval, err := time.ParseDuration(params.Get("interval"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Bad 'interval' param: %s", err)
|
||||
}
|
||||
|
||||
retain, err := time.ParseDuration(params.Get("retain"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Bad 'retain' param: %s", err)
|
||||
}
|
||||
|
||||
return NewInmemSink(interval, retain), nil
|
||||
}
|
||||
|
||||
// NewInmemSink is used to construct a new in-memory sink.
|
||||
// Uses an aggregation interval and maximum retention period.
|
||||
func NewInmemSink(interval, retain time.Duration) *InmemSink {
|
||||
rateTimeUnit := time.Second
|
||||
i := &InmemSink{
|
||||
interval: interval,
|
||||
retain: retain,
|
||||
maxIntervals: int(retain / interval),
|
||||
rateDenom: float64(interval.Nanoseconds()) / float64(rateTimeUnit.Nanoseconds()),
|
||||
}
|
||||
i.intervals = make([]*IntervalMetrics, 0, i.maxIntervals)
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *InmemSink) SetGauge(key []string, val float32) {
|
||||
i.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (i *InmemSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
k, name := i.flattenKeyLabels(key, labels)
|
||||
intv := i.getInterval()
|
||||
|
||||
intv.Lock()
|
||||
defer intv.Unlock()
|
||||
intv.Gauges[k] = GaugeValue{Name: name, Value: val, Labels: labels}
|
||||
}
|
||||
|
||||
func (i *InmemSink) EmitKey(key []string, val float32) {
|
||||
k := i.flattenKey(key)
|
||||
intv := i.getInterval()
|
||||
|
||||
intv.Lock()
|
||||
defer intv.Unlock()
|
||||
vals := intv.Points[k]
|
||||
intv.Points[k] = append(vals, val)
|
||||
}
|
||||
|
||||
func (i *InmemSink) IncrCounter(key []string, val float32) {
|
||||
i.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (i *InmemSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
k, name := i.flattenKeyLabels(key, labels)
|
||||
intv := i.getInterval()
|
||||
|
||||
intv.Lock()
|
||||
defer intv.Unlock()
|
||||
|
||||
agg, ok := intv.Counters[k]
|
||||
if !ok {
|
||||
agg = SampledValue{
|
||||
Name: name,
|
||||
AggregateSample: &AggregateSample{},
|
||||
Labels: labels,
|
||||
}
|
||||
intv.Counters[k] = agg
|
||||
}
|
||||
agg.Ingest(float64(val), i.rateDenom)
|
||||
}
|
||||
|
||||
func (i *InmemSink) AddSample(key []string, val float32) {
|
||||
i.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (i *InmemSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
k, name := i.flattenKeyLabels(key, labels)
|
||||
intv := i.getInterval()
|
||||
|
||||
intv.Lock()
|
||||
defer intv.Unlock()
|
||||
|
||||
agg, ok := intv.Samples[k]
|
||||
if !ok {
|
||||
agg = SampledValue{
|
||||
Name: name,
|
||||
AggregateSample: &AggregateSample{},
|
||||
Labels: labels,
|
||||
}
|
||||
intv.Samples[k] = agg
|
||||
}
|
||||
agg.Ingest(float64(val), i.rateDenom)
|
||||
}
|
||||
|
||||
// Data is used to retrieve all the aggregated metrics
|
||||
// Intervals may be in use, and a read lock should be acquired
|
||||
func (i *InmemSink) Data() []*IntervalMetrics {
|
||||
// Get the current interval, forces creation
|
||||
i.getInterval()
|
||||
|
||||
i.intervalLock.RLock()
|
||||
defer i.intervalLock.RUnlock()
|
||||
|
||||
n := len(i.intervals)
|
||||
intervals := make([]*IntervalMetrics, n)
|
||||
|
||||
copy(intervals[:n-1], i.intervals[:n-1])
|
||||
current := i.intervals[n-1]
|
||||
|
||||
// make its own copy for current interval
|
||||
intervals[n-1] = &IntervalMetrics{}
|
||||
copyCurrent := intervals[n-1]
|
||||
current.RLock()
|
||||
*copyCurrent = *current
|
||||
// RWMutex is not safe to copy, so create a new instance on the copy
|
||||
copyCurrent.RWMutex = sync.RWMutex{}
|
||||
|
||||
copyCurrent.Gauges = make(map[string]GaugeValue, len(current.Gauges))
|
||||
for k, v := range current.Gauges {
|
||||
copyCurrent.Gauges[k] = v
|
||||
}
|
||||
// saved values will be not change, just copy its link
|
||||
copyCurrent.Points = make(map[string][]float32, len(current.Points))
|
||||
for k, v := range current.Points {
|
||||
copyCurrent.Points[k] = v
|
||||
}
|
||||
copyCurrent.Counters = make(map[string]SampledValue, len(current.Counters))
|
||||
for k, v := range current.Counters {
|
||||
copyCurrent.Counters[k] = v.deepCopy()
|
||||
}
|
||||
copyCurrent.Samples = make(map[string]SampledValue, len(current.Samples))
|
||||
for k, v := range current.Samples {
|
||||
copyCurrent.Samples[k] = v.deepCopy()
|
||||
}
|
||||
current.RUnlock()
|
||||
|
||||
return intervals
|
||||
}
|
||||
|
||||
// getInterval returns the current interval. A new interval is created if no
|
||||
// previous interval exists, or if the current time is beyond the window for the
|
||||
// current interval.
|
||||
func (i *InmemSink) getInterval() *IntervalMetrics {
|
||||
intv := time.Now().Truncate(i.interval)
|
||||
|
||||
// Attempt to return the existing interval first, because it only requires
|
||||
// a read lock.
|
||||
i.intervalLock.RLock()
|
||||
n := len(i.intervals)
|
||||
if n > 0 && i.intervals[n-1].Interval == intv {
|
||||
defer i.intervalLock.RUnlock()
|
||||
return i.intervals[n-1]
|
||||
}
|
||||
i.intervalLock.RUnlock()
|
||||
|
||||
i.intervalLock.Lock()
|
||||
defer i.intervalLock.Unlock()
|
||||
|
||||
// Re-check for an existing interval now that the lock is re-acquired.
|
||||
n = len(i.intervals)
|
||||
if n > 0 && i.intervals[n-1].Interval == intv {
|
||||
return i.intervals[n-1]
|
||||
}
|
||||
|
||||
current := NewIntervalMetrics(intv)
|
||||
i.intervals = append(i.intervals, current)
|
||||
if n > 0 {
|
||||
close(i.intervals[n-1].done)
|
||||
}
|
||||
|
||||
n++
|
||||
// Prune old intervals if the count exceeds the max.
|
||||
if n >= i.maxIntervals {
|
||||
copy(i.intervals[0:], i.intervals[n-i.maxIntervals:])
|
||||
i.intervals = i.intervals[:i.maxIntervals]
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
// Flattens the key for formatting, removes spaces
|
||||
func (i *InmemSink) flattenKey(parts []string) string {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
joined := strings.Join(parts, ".")
|
||||
|
||||
spaceReplacer.WriteString(buf, joined)
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Flattens the key for formatting along with its labels, removes spaces
|
||||
func (i *InmemSink) flattenKeyLabels(parts []string, labels []Label) (string, string) {
|
||||
key := i.flattenKey(parts)
|
||||
buf := bytes.NewBufferString(key)
|
||||
|
||||
for _, label := range labels {
|
||||
spaceReplacer.WriteString(buf, fmt.Sprintf(";%s=%s", label.Name, label.Value))
|
||||
}
|
||||
|
||||
return buf.String(), key
|
||||
}
|
||||
162
vendor/github.com/armon/go-metrics/inmem_endpoint.go
generated
vendored
162
vendor/github.com/armon/go-metrics/inmem_endpoint.go
generated
vendored
@@ -1,162 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MetricsSummary holds a roll-up of metrics info for a given interval
|
||||
type MetricsSummary struct {
|
||||
Timestamp string
|
||||
Gauges []GaugeValue
|
||||
Points []PointValue
|
||||
Counters []SampledValue
|
||||
Samples []SampledValue
|
||||
}
|
||||
|
||||
type GaugeValue struct {
|
||||
Name string
|
||||
Hash string `json:"-"`
|
||||
Value float32
|
||||
|
||||
Labels []Label `json:"-"`
|
||||
DisplayLabels map[string]string `json:"Labels"`
|
||||
}
|
||||
|
||||
type PointValue struct {
|
||||
Name string
|
||||
Points []float32
|
||||
}
|
||||
|
||||
type SampledValue struct {
|
||||
Name string
|
||||
Hash string `json:"-"`
|
||||
*AggregateSample
|
||||
Mean float64
|
||||
Stddev float64
|
||||
|
||||
Labels []Label `json:"-"`
|
||||
DisplayLabels map[string]string `json:"Labels"`
|
||||
}
|
||||
|
||||
// deepCopy allocates a new instance of AggregateSample
|
||||
func (source *SampledValue) deepCopy() SampledValue {
|
||||
dest := *source
|
||||
if source.AggregateSample != nil {
|
||||
dest.AggregateSample = &AggregateSample{}
|
||||
*dest.AggregateSample = *source.AggregateSample
|
||||
}
|
||||
return dest
|
||||
}
|
||||
|
||||
// DisplayMetrics returns a summary of the metrics from the most recent finished interval.
|
||||
func (i *InmemSink) DisplayMetrics(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
data := i.Data()
|
||||
|
||||
var interval *IntervalMetrics
|
||||
n := len(data)
|
||||
switch {
|
||||
case n == 0:
|
||||
return nil, fmt.Errorf("no metric intervals have been initialized yet")
|
||||
case n == 1:
|
||||
// Show the current interval if it's all we have
|
||||
interval = data[0]
|
||||
default:
|
||||
// Show the most recent finished interval if we have one
|
||||
interval = data[n-2]
|
||||
}
|
||||
|
||||
return newMetricSummaryFromInterval(interval), nil
|
||||
}
|
||||
|
||||
func newMetricSummaryFromInterval(interval *IntervalMetrics) MetricsSummary {
|
||||
interval.RLock()
|
||||
defer interval.RUnlock()
|
||||
|
||||
summary := MetricsSummary{
|
||||
Timestamp: interval.Interval.Round(time.Second).UTC().String(),
|
||||
Gauges: make([]GaugeValue, 0, len(interval.Gauges)),
|
||||
Points: make([]PointValue, 0, len(interval.Points)),
|
||||
}
|
||||
|
||||
// Format and sort the output of each metric type, so it gets displayed in a
|
||||
// deterministic order.
|
||||
for name, points := range interval.Points {
|
||||
summary.Points = append(summary.Points, PointValue{name, points})
|
||||
}
|
||||
sort.Slice(summary.Points, func(i, j int) bool {
|
||||
return summary.Points[i].Name < summary.Points[j].Name
|
||||
})
|
||||
|
||||
for hash, value := range interval.Gauges {
|
||||
value.Hash = hash
|
||||
value.DisplayLabels = make(map[string]string)
|
||||
for _, label := range value.Labels {
|
||||
value.DisplayLabels[label.Name] = label.Value
|
||||
}
|
||||
value.Labels = nil
|
||||
|
||||
summary.Gauges = append(summary.Gauges, value)
|
||||
}
|
||||
sort.Slice(summary.Gauges, func(i, j int) bool {
|
||||
return summary.Gauges[i].Hash < summary.Gauges[j].Hash
|
||||
})
|
||||
|
||||
summary.Counters = formatSamples(interval.Counters)
|
||||
summary.Samples = formatSamples(interval.Samples)
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func formatSamples(source map[string]SampledValue) []SampledValue {
|
||||
output := make([]SampledValue, 0, len(source))
|
||||
for hash, sample := range source {
|
||||
displayLabels := make(map[string]string)
|
||||
for _, label := range sample.Labels {
|
||||
displayLabels[label.Name] = label.Value
|
||||
}
|
||||
|
||||
output = append(output, SampledValue{
|
||||
Name: sample.Name,
|
||||
Hash: hash,
|
||||
AggregateSample: sample.AggregateSample,
|
||||
Mean: sample.AggregateSample.Mean(),
|
||||
Stddev: sample.AggregateSample.Stddev(),
|
||||
DisplayLabels: displayLabels,
|
||||
})
|
||||
}
|
||||
sort.Slice(output, func(i, j int) bool {
|
||||
return output[i].Hash < output[j].Hash
|
||||
})
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
type Encoder interface {
|
||||
Encode(interface{}) error
|
||||
}
|
||||
|
||||
// Stream writes metrics using encoder.Encode each time an interval ends. Runs
|
||||
// until the request context is cancelled, or the encoder returns an error.
|
||||
// The caller is responsible for logging any errors from encoder.
|
||||
func (i *InmemSink) Stream(ctx context.Context, encoder Encoder) {
|
||||
interval := i.getInterval()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-interval.done:
|
||||
summary := newMetricSummaryFromInterval(interval)
|
||||
if err := encoder.Encode(summary); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// update interval to the next one
|
||||
interval = i.getInterval()
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
117
vendor/github.com/armon/go-metrics/inmem_signal.go
generated
vendored
117
vendor/github.com/armon/go-metrics/inmem_signal.go
generated
vendored
@@ -1,117 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// InmemSignal is used to listen for a given signal, and when received,
|
||||
// to dump the current metrics from the InmemSink to an io.Writer
|
||||
type InmemSignal struct {
|
||||
signal syscall.Signal
|
||||
inm *InmemSink
|
||||
w io.Writer
|
||||
sigCh chan os.Signal
|
||||
|
||||
stop bool
|
||||
stopCh chan struct{}
|
||||
stopLock sync.Mutex
|
||||
}
|
||||
|
||||
// NewInmemSignal creates a new InmemSignal which listens for a given signal,
|
||||
// and dumps the current metrics out to a writer
|
||||
func NewInmemSignal(inmem *InmemSink, sig syscall.Signal, w io.Writer) *InmemSignal {
|
||||
i := &InmemSignal{
|
||||
signal: sig,
|
||||
inm: inmem,
|
||||
w: w,
|
||||
sigCh: make(chan os.Signal, 1),
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
signal.Notify(i.sigCh, sig)
|
||||
go i.run()
|
||||
return i
|
||||
}
|
||||
|
||||
// DefaultInmemSignal returns a new InmemSignal that responds to SIGUSR1
|
||||
// and writes output to stderr. Windows uses SIGBREAK
|
||||
func DefaultInmemSignal(inmem *InmemSink) *InmemSignal {
|
||||
return NewInmemSignal(inmem, DefaultSignal, os.Stderr)
|
||||
}
|
||||
|
||||
// Stop is used to stop the InmemSignal from listening
|
||||
func (i *InmemSignal) Stop() {
|
||||
i.stopLock.Lock()
|
||||
defer i.stopLock.Unlock()
|
||||
|
||||
if i.stop {
|
||||
return
|
||||
}
|
||||
i.stop = true
|
||||
close(i.stopCh)
|
||||
signal.Stop(i.sigCh)
|
||||
}
|
||||
|
||||
// run is a long running routine that handles signals
|
||||
func (i *InmemSignal) run() {
|
||||
for {
|
||||
select {
|
||||
case <-i.sigCh:
|
||||
i.dumpStats()
|
||||
case <-i.stopCh:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dumpStats is used to dump the data to output writer
|
||||
func (i *InmemSignal) dumpStats() {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
data := i.inm.Data()
|
||||
// Skip the last period which is still being aggregated
|
||||
for j := 0; j < len(data)-1; j++ {
|
||||
intv := data[j]
|
||||
intv.RLock()
|
||||
for _, val := range intv.Gauges {
|
||||
name := i.flattenLabels(val.Name, val.Labels)
|
||||
fmt.Fprintf(buf, "[%v][G] '%s': %0.3f\n", intv.Interval, name, val.Value)
|
||||
}
|
||||
for name, vals := range intv.Points {
|
||||
for _, val := range vals {
|
||||
fmt.Fprintf(buf, "[%v][P] '%s': %0.3f\n", intv.Interval, name, val)
|
||||
}
|
||||
}
|
||||
for _, agg := range intv.Counters {
|
||||
name := i.flattenLabels(agg.Name, agg.Labels)
|
||||
fmt.Fprintf(buf, "[%v][C] '%s': %s\n", intv.Interval, name, agg.AggregateSample)
|
||||
}
|
||||
for _, agg := range intv.Samples {
|
||||
name := i.flattenLabels(agg.Name, agg.Labels)
|
||||
fmt.Fprintf(buf, "[%v][S] '%s': %s\n", intv.Interval, name, agg.AggregateSample)
|
||||
}
|
||||
intv.RUnlock()
|
||||
}
|
||||
|
||||
// Write out the bytes
|
||||
i.w.Write(buf.Bytes())
|
||||
}
|
||||
|
||||
// Flattens the key for formatting along with its labels, removes spaces
|
||||
func (i *InmemSignal) flattenLabels(name string, labels []Label) string {
|
||||
buf := bytes.NewBufferString(name)
|
||||
replacer := strings.NewReplacer(" ", "_", ":", "_")
|
||||
|
||||
for _, label := range labels {
|
||||
replacer.WriteString(buf, ".")
|
||||
replacer.WriteString(buf, label.Value)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
299
vendor/github.com/armon/go-metrics/metrics.go
generated
vendored
299
vendor/github.com/armon/go-metrics/metrics.go
generated
vendored
@@ -1,299 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
iradix "github.com/hashicorp/go-immutable-radix"
|
||||
)
|
||||
|
||||
type Label struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
func (m *Metrics) SetGauge(key []string, val float32) {
|
||||
m.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
if m.HostName != "" {
|
||||
if m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
} else if m.EnableHostname {
|
||||
key = insert(0, m.HostName, key)
|
||||
}
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "gauge", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
allowed, labelsFiltered := m.allowMetric(key, labels)
|
||||
if !allowed {
|
||||
return
|
||||
}
|
||||
m.sink.SetGaugeWithLabels(key, val, labelsFiltered)
|
||||
}
|
||||
|
||||
func (m *Metrics) EmitKey(key []string, val float32) {
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "kv", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
allowed, _ := m.allowMetric(key, nil)
|
||||
if !allowed {
|
||||
return
|
||||
}
|
||||
m.sink.EmitKey(key, val)
|
||||
}
|
||||
|
||||
func (m *Metrics) IncrCounter(key []string, val float32) {
|
||||
m.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
if m.HostName != "" && m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "counter", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
allowed, labelsFiltered := m.allowMetric(key, labels)
|
||||
if !allowed {
|
||||
return
|
||||
}
|
||||
m.sink.IncrCounterWithLabels(key, val, labelsFiltered)
|
||||
}
|
||||
|
||||
func (m *Metrics) AddSample(key []string, val float32) {
|
||||
m.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
if m.HostName != "" && m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "sample", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
allowed, labelsFiltered := m.allowMetric(key, labels)
|
||||
if !allowed {
|
||||
return
|
||||
}
|
||||
m.sink.AddSampleWithLabels(key, val, labelsFiltered)
|
||||
}
|
||||
|
||||
func (m *Metrics) MeasureSince(key []string, start time.Time) {
|
||||
m.MeasureSinceWithLabels(key, start, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) MeasureSinceWithLabels(key []string, start time.Time, labels []Label) {
|
||||
if m.HostName != "" && m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "timer", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
allowed, labelsFiltered := m.allowMetric(key, labels)
|
||||
if !allowed {
|
||||
return
|
||||
}
|
||||
now := time.Now()
|
||||
elapsed := now.Sub(start)
|
||||
msec := float32(elapsed.Nanoseconds()) / float32(m.TimerGranularity)
|
||||
m.sink.AddSampleWithLabels(key, msec, labelsFiltered)
|
||||
}
|
||||
|
||||
// UpdateFilter overwrites the existing filter with the given rules.
|
||||
func (m *Metrics) UpdateFilter(allow, block []string) {
|
||||
m.UpdateFilterAndLabels(allow, block, m.AllowedLabels, m.BlockedLabels)
|
||||
}
|
||||
|
||||
// UpdateFilterAndLabels overwrites the existing filter with the given rules.
|
||||
func (m *Metrics) UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) {
|
||||
m.filterLock.Lock()
|
||||
defer m.filterLock.Unlock()
|
||||
|
||||
m.AllowedPrefixes = allow
|
||||
m.BlockedPrefixes = block
|
||||
|
||||
if allowedLabels == nil {
|
||||
// Having a white list means we take only elements from it
|
||||
m.allowedLabels = nil
|
||||
} else {
|
||||
m.allowedLabels = make(map[string]bool)
|
||||
for _, v := range allowedLabels {
|
||||
m.allowedLabels[v] = true
|
||||
}
|
||||
}
|
||||
m.blockedLabels = make(map[string]bool)
|
||||
for _, v := range blockedLabels {
|
||||
m.blockedLabels[v] = true
|
||||
}
|
||||
m.AllowedLabels = allowedLabels
|
||||
m.BlockedLabels = blockedLabels
|
||||
|
||||
m.filter = iradix.New()
|
||||
for _, prefix := range m.AllowedPrefixes {
|
||||
m.filter, _, _ = m.filter.Insert([]byte(prefix), true)
|
||||
}
|
||||
for _, prefix := range m.BlockedPrefixes {
|
||||
m.filter, _, _ = m.filter.Insert([]byte(prefix), false)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Metrics) Shutdown() {
|
||||
if ss, ok := m.sink.(ShutdownSink); ok {
|
||||
ss.Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
// labelIsAllowed return true if a should be included in metric
|
||||
// the caller should lock m.filterLock while calling this method
|
||||
func (m *Metrics) labelIsAllowed(label *Label) bool {
|
||||
labelName := (*label).Name
|
||||
if m.blockedLabels != nil {
|
||||
_, ok := m.blockedLabels[labelName]
|
||||
if ok {
|
||||
// If present, let's remove this label
|
||||
return false
|
||||
}
|
||||
}
|
||||
if m.allowedLabels != nil {
|
||||
_, ok := m.allowedLabels[labelName]
|
||||
return ok
|
||||
}
|
||||
// Allow by default
|
||||
return true
|
||||
}
|
||||
|
||||
// filterLabels return only allowed labels
|
||||
// the caller should lock m.filterLock while calling this method
|
||||
func (m *Metrics) filterLabels(labels []Label) []Label {
|
||||
if labels == nil {
|
||||
return nil
|
||||
}
|
||||
toReturn := []Label{}
|
||||
for _, label := range labels {
|
||||
if m.labelIsAllowed(&label) {
|
||||
toReturn = append(toReturn, label)
|
||||
}
|
||||
}
|
||||
return toReturn
|
||||
}
|
||||
|
||||
// Returns whether the metric should be allowed based on configured prefix filters
|
||||
// Also return the applicable labels
|
||||
func (m *Metrics) allowMetric(key []string, labels []Label) (bool, []Label) {
|
||||
m.filterLock.RLock()
|
||||
defer m.filterLock.RUnlock()
|
||||
|
||||
if m.filter == nil || m.filter.Len() == 0 {
|
||||
return m.Config.FilterDefault, m.filterLabels(labels)
|
||||
}
|
||||
|
||||
_, allowed, ok := m.filter.Root().LongestPrefix([]byte(strings.Join(key, ".")))
|
||||
if !ok {
|
||||
return m.Config.FilterDefault, m.filterLabels(labels)
|
||||
}
|
||||
|
||||
return allowed.(bool), m.filterLabels(labels)
|
||||
}
|
||||
|
||||
// Periodically collects runtime stats to publish
|
||||
func (m *Metrics) collectStats() {
|
||||
for {
|
||||
time.Sleep(m.ProfileInterval)
|
||||
m.EmitRuntimeStats()
|
||||
}
|
||||
}
|
||||
|
||||
// Emits various runtime statsitics
|
||||
func (m *Metrics) EmitRuntimeStats() {
|
||||
// Export number of Goroutines
|
||||
numRoutines := runtime.NumGoroutine()
|
||||
m.SetGauge([]string{"runtime", "num_goroutines"}, float32(numRoutines))
|
||||
|
||||
// Export memory stats
|
||||
var stats runtime.MemStats
|
||||
runtime.ReadMemStats(&stats)
|
||||
m.SetGauge([]string{"runtime", "alloc_bytes"}, float32(stats.Alloc))
|
||||
m.SetGauge([]string{"runtime", "sys_bytes"}, float32(stats.Sys))
|
||||
m.SetGauge([]string{"runtime", "malloc_count"}, float32(stats.Mallocs))
|
||||
m.SetGauge([]string{"runtime", "free_count"}, float32(stats.Frees))
|
||||
m.SetGauge([]string{"runtime", "heap_objects"}, float32(stats.HeapObjects))
|
||||
m.SetGauge([]string{"runtime", "total_gc_pause_ns"}, float32(stats.PauseTotalNs))
|
||||
m.SetGauge([]string{"runtime", "total_gc_runs"}, float32(stats.NumGC))
|
||||
|
||||
// Export info about the last few GC runs
|
||||
num := stats.NumGC
|
||||
|
||||
// Handle wrap around
|
||||
if num < m.lastNumGC {
|
||||
m.lastNumGC = 0
|
||||
}
|
||||
|
||||
// Ensure we don't scan more than 256
|
||||
if num-m.lastNumGC >= 256 {
|
||||
m.lastNumGC = num - 255
|
||||
}
|
||||
|
||||
for i := m.lastNumGC; i < num; i++ {
|
||||
pause := stats.PauseNs[i%256]
|
||||
m.AddSample([]string{"runtime", "gc_pause_ns"}, float32(pause))
|
||||
}
|
||||
m.lastNumGC = num
|
||||
}
|
||||
|
||||
// Creates a new slice with the provided string value as the first element
|
||||
// and the provided slice values as the remaining values.
|
||||
// Ordering of the values in the provided input slice is kept in tact in the output slice.
|
||||
func insert(i int, v string, s []string) []string {
|
||||
// Allocate new slice to avoid modifying the input slice
|
||||
newS := make([]string, len(s)+1)
|
||||
|
||||
// Copy s[0, i-1] into newS
|
||||
for j := 0; j < i; j++ {
|
||||
newS[j] = s[j]
|
||||
}
|
||||
|
||||
// Insert provided element at index i
|
||||
newS[i] = v
|
||||
|
||||
// Copy s[i, len(s)-1] into newS starting at newS[i+1]
|
||||
for j := i; j < len(s); j++ {
|
||||
newS[j+1] = s[j]
|
||||
}
|
||||
|
||||
return newS
|
||||
}
|
||||
132
vendor/github.com/armon/go-metrics/sink.go
generated
vendored
132
vendor/github.com/armon/go-metrics/sink.go
generated
vendored
@@ -1,132 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// The MetricSink interface is used to transmit metrics information
|
||||
// to an external system
|
||||
type MetricSink interface {
|
||||
// A Gauge should retain the last value it is set to
|
||||
SetGauge(key []string, val float32)
|
||||
SetGaugeWithLabels(key []string, val float32, labels []Label)
|
||||
|
||||
// Should emit a Key/Value pair for each call
|
||||
EmitKey(key []string, val float32)
|
||||
|
||||
// Counters should accumulate values
|
||||
IncrCounter(key []string, val float32)
|
||||
IncrCounterWithLabels(key []string, val float32, labels []Label)
|
||||
|
||||
// Samples are for timing information, where quantiles are used
|
||||
AddSample(key []string, val float32)
|
||||
AddSampleWithLabels(key []string, val float32, labels []Label)
|
||||
}
|
||||
|
||||
type ShutdownSink interface {
|
||||
MetricSink
|
||||
|
||||
// Shutdown the metric sink, flush metrics to storage, and cleanup resources.
|
||||
// Called immediately prior to application exit. Implementations must block
|
||||
// until metrics are flushed to storage.
|
||||
Shutdown()
|
||||
}
|
||||
|
||||
// BlackholeSink is used to just blackhole messages
|
||||
type BlackholeSink struct{}
|
||||
|
||||
func (*BlackholeSink) SetGauge(key []string, val float32) {}
|
||||
func (*BlackholeSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {}
|
||||
func (*BlackholeSink) EmitKey(key []string, val float32) {}
|
||||
func (*BlackholeSink) IncrCounter(key []string, val float32) {}
|
||||
func (*BlackholeSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {}
|
||||
func (*BlackholeSink) AddSample(key []string, val float32) {}
|
||||
func (*BlackholeSink) AddSampleWithLabels(key []string, val float32, labels []Label) {}
|
||||
|
||||
// FanoutSink is used to sink to fanout values to multiple sinks
|
||||
type FanoutSink []MetricSink
|
||||
|
||||
func (fh FanoutSink) SetGauge(key []string, val float32) {
|
||||
fh.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (fh FanoutSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
for _, s := range fh {
|
||||
s.SetGaugeWithLabels(key, val, labels)
|
||||
}
|
||||
}
|
||||
|
||||
func (fh FanoutSink) EmitKey(key []string, val float32) {
|
||||
for _, s := range fh {
|
||||
s.EmitKey(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
func (fh FanoutSink) IncrCounter(key []string, val float32) {
|
||||
fh.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (fh FanoutSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
for _, s := range fh {
|
||||
s.IncrCounterWithLabels(key, val, labels)
|
||||
}
|
||||
}
|
||||
|
||||
func (fh FanoutSink) AddSample(key []string, val float32) {
|
||||
fh.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (fh FanoutSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
for _, s := range fh {
|
||||
s.AddSampleWithLabels(key, val, labels)
|
||||
}
|
||||
}
|
||||
|
||||
func (fh FanoutSink) Shutdown() {
|
||||
for _, s := range fh {
|
||||
if ss, ok := s.(ShutdownSink); ok {
|
||||
ss.Shutdown()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sinkURLFactoryFunc is an generic interface around the *SinkFromURL() function provided
|
||||
// by each sink type
|
||||
type sinkURLFactoryFunc func(*url.URL) (MetricSink, error)
|
||||
|
||||
// sinkRegistry supports the generic NewMetricSink function by mapping URL
|
||||
// schemes to metric sink factory functions
|
||||
var sinkRegistry = map[string]sinkURLFactoryFunc{
|
||||
"statsd": NewStatsdSinkFromURL,
|
||||
"statsite": NewStatsiteSinkFromURL,
|
||||
"inmem": NewInmemSinkFromURL,
|
||||
}
|
||||
|
||||
// NewMetricSinkFromURL allows a generic URL input to configure any of the
|
||||
// supported sinks. The scheme of the URL identifies the type of the sink, the
|
||||
// and query parameters are used to set options.
|
||||
//
|
||||
// "statsd://" - Initializes a StatsdSink. The host and port are passed through
|
||||
// as the "addr" of the sink
|
||||
//
|
||||
// "statsite://" - Initializes a StatsiteSink. The host and port become the
|
||||
// "addr" of the sink
|
||||
//
|
||||
// "inmem://" - Initializes an InmemSink. The host and port are ignored. The
|
||||
// "interval" and "duration" query parameters must be specified with valid
|
||||
// durations, see NewInmemSink for details.
|
||||
func NewMetricSinkFromURL(urlStr string) (MetricSink, error) {
|
||||
u, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sinkURLFactoryFunc := sinkRegistry[u.Scheme]
|
||||
if sinkURLFactoryFunc == nil {
|
||||
return nil, fmt.Errorf(
|
||||
"cannot create metric sink, unrecognized sink name: %q", u.Scheme)
|
||||
}
|
||||
|
||||
return sinkURLFactoryFunc(u)
|
||||
}
|
||||
158
vendor/github.com/armon/go-metrics/start.go
generated
vendored
158
vendor/github.com/armon/go-metrics/start.go
generated
vendored
@@ -1,158 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
iradix "github.com/hashicorp/go-immutable-radix"
|
||||
)
|
||||
|
||||
// Config is used to configure metrics settings
|
||||
type Config struct {
|
||||
ServiceName string // Prefixed with keys to separate services
|
||||
HostName string // Hostname to use. If not provided and EnableHostname, it will be os.Hostname
|
||||
EnableHostname bool // Enable prefixing gauge values with hostname
|
||||
EnableHostnameLabel bool // Enable adding hostname to labels
|
||||
EnableServiceLabel bool // Enable adding service to labels
|
||||
EnableRuntimeMetrics bool // Enables profiling of runtime metrics (GC, Goroutines, Memory)
|
||||
EnableTypePrefix bool // Prefixes key with a type ("counter", "gauge", "timer")
|
||||
TimerGranularity time.Duration // Granularity of timers.
|
||||
ProfileInterval time.Duration // Interval to profile runtime metrics
|
||||
|
||||
AllowedPrefixes []string // A list of metric prefixes to allow, with '.' as the separator
|
||||
BlockedPrefixes []string // A list of metric prefixes to block, with '.' as the separator
|
||||
AllowedLabels []string // A list of metric labels to allow, with '.' as the separator
|
||||
BlockedLabels []string // A list of metric labels to block, with '.' as the separator
|
||||
FilterDefault bool // Whether to allow metrics by default
|
||||
}
|
||||
|
||||
// Metrics represents an instance of a metrics sink that can
|
||||
// be used to emit
|
||||
type Metrics struct {
|
||||
Config
|
||||
lastNumGC uint32
|
||||
sink MetricSink
|
||||
filter *iradix.Tree
|
||||
allowedLabels map[string]bool
|
||||
blockedLabels map[string]bool
|
||||
filterLock sync.RWMutex // Lock filters and allowedLabels/blockedLabels access
|
||||
}
|
||||
|
||||
// Shared global metrics instance
|
||||
var globalMetrics atomic.Value // *Metrics
|
||||
|
||||
func init() {
|
||||
// Initialize to a blackhole sink to avoid errors
|
||||
globalMetrics.Store(&Metrics{sink: &BlackholeSink{}})
|
||||
}
|
||||
|
||||
// Default returns the shared global metrics instance.
|
||||
func Default() *Metrics {
|
||||
return globalMetrics.Load().(*Metrics)
|
||||
}
|
||||
|
||||
// DefaultConfig provides a sane default configuration
|
||||
func DefaultConfig(serviceName string) *Config {
|
||||
c := &Config{
|
||||
ServiceName: serviceName, // Use client provided service
|
||||
HostName: "",
|
||||
EnableHostname: true, // Enable hostname prefix
|
||||
EnableRuntimeMetrics: true, // Enable runtime profiling
|
||||
EnableTypePrefix: false, // Disable type prefix
|
||||
TimerGranularity: time.Millisecond, // Timers are in milliseconds
|
||||
ProfileInterval: time.Second, // Poll runtime every second
|
||||
FilterDefault: true, // Don't filter metrics by default
|
||||
}
|
||||
|
||||
// Try to get the hostname
|
||||
name, _ := os.Hostname()
|
||||
c.HostName = name
|
||||
return c
|
||||
}
|
||||
|
||||
// New is used to create a new instance of Metrics
|
||||
func New(conf *Config, sink MetricSink) (*Metrics, error) {
|
||||
met := &Metrics{}
|
||||
met.Config = *conf
|
||||
met.sink = sink
|
||||
met.UpdateFilterAndLabels(conf.AllowedPrefixes, conf.BlockedPrefixes, conf.AllowedLabels, conf.BlockedLabels)
|
||||
|
||||
// Start the runtime collector
|
||||
if conf.EnableRuntimeMetrics {
|
||||
go met.collectStats()
|
||||
}
|
||||
return met, nil
|
||||
}
|
||||
|
||||
// NewGlobal is the same as New, but it assigns the metrics object to be
|
||||
// used globally as well as returning it.
|
||||
func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) {
|
||||
metrics, err := New(conf, sink)
|
||||
if err == nil {
|
||||
globalMetrics.Store(metrics)
|
||||
}
|
||||
return metrics, err
|
||||
}
|
||||
|
||||
// Proxy all the methods to the globalMetrics instance
|
||||
func SetGauge(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).SetGauge(key, val)
|
||||
}
|
||||
|
||||
func SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).SetGaugeWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func EmitKey(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).EmitKey(key, val)
|
||||
}
|
||||
|
||||
func IncrCounter(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).IncrCounter(key, val)
|
||||
}
|
||||
|
||||
func IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).IncrCounterWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func AddSample(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).AddSample(key, val)
|
||||
}
|
||||
|
||||
func AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).AddSampleWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func MeasureSince(key []string, start time.Time) {
|
||||
globalMetrics.Load().(*Metrics).MeasureSince(key, start)
|
||||
}
|
||||
|
||||
func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).MeasureSinceWithLabels(key, start, labels)
|
||||
}
|
||||
|
||||
func UpdateFilter(allow, block []string) {
|
||||
globalMetrics.Load().(*Metrics).UpdateFilter(allow, block)
|
||||
}
|
||||
|
||||
// UpdateFilterAndLabels set allow/block prefixes of metrics while allowedLabels
|
||||
// and blockedLabels - when not nil - allow filtering of labels in order to
|
||||
// block/allow globally labels (especially useful when having large number of
|
||||
// values for a given label). See README.md for more information about usage.
|
||||
func UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) {
|
||||
globalMetrics.Load().(*Metrics).UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels)
|
||||
}
|
||||
|
||||
// Shutdown disables metric collection, then blocks while attempting to flush metrics to storage.
|
||||
// WARNING: Not all MetricSink backends support this functionality, and calling this will cause them to leak resources.
|
||||
// This is intended for use immediately prior to application exit.
|
||||
func Shutdown() {
|
||||
m := globalMetrics.Load().(*Metrics)
|
||||
// Swap whatever MetricSink is currently active with a BlackholeSink. Callers must not have a
|
||||
// reason to expect that calls to the library will successfully collect metrics after Shutdown
|
||||
// has been called.
|
||||
globalMetrics.Store(&Metrics{sink: &BlackholeSink{}})
|
||||
m.Shutdown()
|
||||
}
|
||||
184
vendor/github.com/armon/go-metrics/statsd.go
generated
vendored
184
vendor/github.com/armon/go-metrics/statsd.go
generated
vendored
@@ -1,184 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// statsdMaxLen is the maximum size of a packet
|
||||
// to send to statsd
|
||||
statsdMaxLen = 1400
|
||||
)
|
||||
|
||||
// StatsdSink provides a MetricSink that can be used
|
||||
// with a statsite or statsd metrics server. It uses
|
||||
// only UDP packets, while StatsiteSink uses TCP.
|
||||
type StatsdSink struct {
|
||||
addr string
|
||||
metricQueue chan string
|
||||
}
|
||||
|
||||
// NewStatsdSinkFromURL creates an StatsdSink from a URL. It is used
|
||||
// (and tested) from NewMetricSinkFromURL.
|
||||
func NewStatsdSinkFromURL(u *url.URL) (MetricSink, error) {
|
||||
return NewStatsdSink(u.Host)
|
||||
}
|
||||
|
||||
// NewStatsdSink is used to create a new StatsdSink
|
||||
func NewStatsdSink(addr string) (*StatsdSink, error) {
|
||||
s := &StatsdSink{
|
||||
addr: addr,
|
||||
metricQueue: make(chan string, 4096),
|
||||
}
|
||||
go s.flushMetrics()
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Close is used to stop flushing to statsd
|
||||
func (s *StatsdSink) Shutdown() {
|
||||
close(s.metricQueue)
|
||||
}
|
||||
|
||||
func (s *StatsdSink) SetGauge(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) EmitKey(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) IncrCounter(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) AddSample(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
// Flattens the key for formatting, removes spaces
|
||||
func (s *StatsdSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, ".")
|
||||
return strings.Map(func(r rune) rune {
|
||||
switch r {
|
||||
case ':':
|
||||
fallthrough
|
||||
case ' ':
|
||||
return '_'
|
||||
default:
|
||||
return r
|
||||
}
|
||||
}, joined)
|
||||
}
|
||||
|
||||
// Flattens the key along with labels for formatting, removes spaces
|
||||
func (s *StatsdSink) flattenKeyLabels(parts []string, labels []Label) string {
|
||||
for _, label := range labels {
|
||||
parts = append(parts, label.Value)
|
||||
}
|
||||
return s.flattenKey(parts)
|
||||
}
|
||||
|
||||
// Does a non-blocking push to the metrics queue
|
||||
func (s *StatsdSink) pushMetric(m string) {
|
||||
select {
|
||||
case s.metricQueue <- m:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// Flushes metrics
|
||||
func (s *StatsdSink) flushMetrics() {
|
||||
var sock net.Conn
|
||||
var err error
|
||||
var wait <-chan time.Time
|
||||
ticker := time.NewTicker(flushInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
CONNECT:
|
||||
// Create a buffer
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
// Attempt to connect
|
||||
sock, err = net.Dial("udp", s.addr)
|
||||
if err != nil {
|
||||
log.Printf("[ERR] Error connecting to statsd! Err: %s", err)
|
||||
goto WAIT
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case metric, ok := <-s.metricQueue:
|
||||
// Get a metric from the queue
|
||||
if !ok {
|
||||
goto QUIT
|
||||
}
|
||||
|
||||
// Check if this would overflow the packet size
|
||||
if len(metric)+buf.Len() > statsdMaxLen {
|
||||
_, err := sock.Write(buf.Bytes())
|
||||
buf.Reset()
|
||||
if err != nil {
|
||||
log.Printf("[ERR] Error writing to statsd! Err: %s", err)
|
||||
goto WAIT
|
||||
}
|
||||
}
|
||||
|
||||
// Append to the buffer
|
||||
buf.WriteString(metric)
|
||||
|
||||
case <-ticker.C:
|
||||
if buf.Len() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err := sock.Write(buf.Bytes())
|
||||
buf.Reset()
|
||||
if err != nil {
|
||||
log.Printf("[ERR] Error flushing to statsd! Err: %s", err)
|
||||
goto WAIT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WAIT:
|
||||
// Wait for a while
|
||||
wait = time.After(time.Duration(5) * time.Second)
|
||||
for {
|
||||
select {
|
||||
// Dequeue the messages to avoid backlog
|
||||
case _, ok := <-s.metricQueue:
|
||||
if !ok {
|
||||
goto QUIT
|
||||
}
|
||||
case <-wait:
|
||||
goto CONNECT
|
||||
}
|
||||
}
|
||||
QUIT:
|
||||
s.metricQueue = nil
|
||||
}
|
||||
172
vendor/github.com/armon/go-metrics/statsite.go
generated
vendored
172
vendor/github.com/armon/go-metrics/statsite.go
generated
vendored
@@ -1,172 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// We force flush the statsite metrics after this period of
|
||||
// inactivity. Prevents stats from getting stuck in a buffer
|
||||
// forever.
|
||||
flushInterval = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
// NewStatsiteSinkFromURL creates an StatsiteSink from a URL. It is used
|
||||
// (and tested) from NewMetricSinkFromURL.
|
||||
func NewStatsiteSinkFromURL(u *url.URL) (MetricSink, error) {
|
||||
return NewStatsiteSink(u.Host)
|
||||
}
|
||||
|
||||
// StatsiteSink provides a MetricSink that can be used with a
|
||||
// statsite metrics server
|
||||
type StatsiteSink struct {
|
||||
addr string
|
||||
metricQueue chan string
|
||||
}
|
||||
|
||||
// NewStatsiteSink is used to create a new StatsiteSink
|
||||
func NewStatsiteSink(addr string) (*StatsiteSink, error) {
|
||||
s := &StatsiteSink{
|
||||
addr: addr,
|
||||
metricQueue: make(chan string, 4096),
|
||||
}
|
||||
go s.flushMetrics()
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Close is used to stop flushing to statsite
|
||||
func (s *StatsiteSink) Shutdown() {
|
||||
close(s.metricQueue)
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) SetGauge(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) EmitKey(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) IncrCounter(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) AddSample(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
// Flattens the key for formatting, removes spaces
|
||||
func (s *StatsiteSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, ".")
|
||||
return strings.Map(func(r rune) rune {
|
||||
switch r {
|
||||
case ':':
|
||||
fallthrough
|
||||
case ' ':
|
||||
return '_'
|
||||
default:
|
||||
return r
|
||||
}
|
||||
}, joined)
|
||||
}
|
||||
|
||||
// Flattens the key along with labels for formatting, removes spaces
|
||||
func (s *StatsiteSink) flattenKeyLabels(parts []string, labels []Label) string {
|
||||
for _, label := range labels {
|
||||
parts = append(parts, label.Value)
|
||||
}
|
||||
return s.flattenKey(parts)
|
||||
}
|
||||
|
||||
// Does a non-blocking push to the metrics queue
|
||||
func (s *StatsiteSink) pushMetric(m string) {
|
||||
select {
|
||||
case s.metricQueue <- m:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// Flushes metrics
|
||||
func (s *StatsiteSink) flushMetrics() {
|
||||
var sock net.Conn
|
||||
var err error
|
||||
var wait <-chan time.Time
|
||||
var buffered *bufio.Writer
|
||||
ticker := time.NewTicker(flushInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
CONNECT:
|
||||
// Attempt to connect
|
||||
sock, err = net.Dial("tcp", s.addr)
|
||||
if err != nil {
|
||||
log.Printf("[ERR] Error connecting to statsite! Err: %s", err)
|
||||
goto WAIT
|
||||
}
|
||||
|
||||
// Create a buffered writer
|
||||
buffered = bufio.NewWriter(sock)
|
||||
|
||||
for {
|
||||
select {
|
||||
case metric, ok := <-s.metricQueue:
|
||||
// Get a metric from the queue
|
||||
if !ok {
|
||||
goto QUIT
|
||||
}
|
||||
|
||||
// Try to send to statsite
|
||||
_, err := buffered.Write([]byte(metric))
|
||||
if err != nil {
|
||||
log.Printf("[ERR] Error writing to statsite! Err: %s", err)
|
||||
goto WAIT
|
||||
}
|
||||
case <-ticker.C:
|
||||
if err := buffered.Flush(); err != nil {
|
||||
log.Printf("[ERR] Error flushing to statsite! Err: %s", err)
|
||||
goto WAIT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WAIT:
|
||||
// Wait for a while
|
||||
wait = time.After(time.Duration(5) * time.Second)
|
||||
for {
|
||||
select {
|
||||
// Dequeue the messages to avoid backlog
|
||||
case _, ok := <-s.metricQueue:
|
||||
if !ok {
|
||||
goto QUIT
|
||||
}
|
||||
case <-wait:
|
||||
goto CONNECT
|
||||
}
|
||||
}
|
||||
QUIT:
|
||||
s.metricQueue = nil
|
||||
}
|
||||
191
vendor/github.com/go-micro/plugins/v4/registry/consul/LICENSE
generated
vendored
191
vendor/github.com/go-micro/plugins/v4/registry/consul/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015 Asim Aslam.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
465
vendor/github.com/go-micro/plugins/v4/registry/consul/consul.go
generated
vendored
465
vendor/github.com/go-micro/plugins/v4/registry/consul/consul.go
generated
vendored
@@ -1,465 +0,0 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
hash "github.com/mitchellh/hashstructure"
|
||||
"go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/util/cmd"
|
||||
mnet "go-micro.dev/v4/util/net"
|
||||
)
|
||||
|
||||
type consulRegistry struct {
|
||||
Address []string
|
||||
opts registry.Options
|
||||
|
||||
client *consul.Client
|
||||
config *consul.Config
|
||||
|
||||
// connect enabled
|
||||
connect bool
|
||||
|
||||
queryOptions *consul.QueryOptions
|
||||
|
||||
sync.Mutex
|
||||
register map[string]uint64
|
||||
// lastChecked tracks when a node was last checked as existing in Consul
|
||||
lastChecked map[string]time.Time
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmd.DefaultRegistries["consul"] = NewRegistry
|
||||
}
|
||||
|
||||
func getDeregisterTTL(t time.Duration) time.Duration {
|
||||
// splay slightly for the watcher?
|
||||
splay := time.Second * 5
|
||||
deregTTL := t + splay
|
||||
|
||||
// consul has a minimum timeout on deregistration of 1 minute.
|
||||
if t < time.Minute {
|
||||
deregTTL = time.Minute + splay
|
||||
}
|
||||
|
||||
return deregTTL
|
||||
}
|
||||
|
||||
func newTransport(config *tls.Config) *http.Transport {
|
||||
if config == nil {
|
||||
config = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
}
|
||||
|
||||
t := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
TLSClientConfig: config,
|
||||
}
|
||||
runtime.SetFinalizer(&t, func(tr **http.Transport) {
|
||||
(*tr).CloseIdleConnections()
|
||||
})
|
||||
return t
|
||||
}
|
||||
|
||||
func configure(c *consulRegistry, opts ...registry.Option) {
|
||||
// set opts
|
||||
for _, o := range opts {
|
||||
o(&c.opts)
|
||||
}
|
||||
|
||||
// use default non pooled config
|
||||
config := consul.DefaultNonPooledConfig()
|
||||
|
||||
if c.opts.Context != nil {
|
||||
// Use the consul config passed in the options, if available
|
||||
if co, ok := c.opts.Context.Value("consul_config").(*consul.Config); ok {
|
||||
config = co
|
||||
}
|
||||
if cn, ok := c.opts.Context.Value("consul_connect").(bool); ok {
|
||||
c.connect = cn
|
||||
}
|
||||
|
||||
// Use the consul query options passed in the options, if available
|
||||
if qo, ok := c.opts.Context.Value("consul_query_options").(*consul.QueryOptions); ok && qo != nil {
|
||||
c.queryOptions = qo
|
||||
}
|
||||
if as, ok := c.opts.Context.Value("consul_allow_stale").(bool); ok {
|
||||
c.queryOptions.AllowStale = as
|
||||
}
|
||||
}
|
||||
|
||||
// check if there are any addrs
|
||||
var addrs []string
|
||||
|
||||
// iterate the options addresses
|
||||
for _, address := range c.opts.Addrs {
|
||||
// check we have a port
|
||||
addr, port, err := net.SplitHostPort(address)
|
||||
if ae, ok := err.(*net.AddrError); ok && ae.Err == "missing port in address" {
|
||||
port = "8500"
|
||||
addr = address
|
||||
addrs = append(addrs, net.JoinHostPort(addr, port))
|
||||
} else if err == nil {
|
||||
addrs = append(addrs, net.JoinHostPort(addr, port))
|
||||
}
|
||||
}
|
||||
|
||||
// set the addrs
|
||||
if len(addrs) > 0 {
|
||||
c.Address = addrs
|
||||
config.Address = c.Address[0]
|
||||
}
|
||||
|
||||
if config.HttpClient == nil {
|
||||
config.HttpClient = new(http.Client)
|
||||
}
|
||||
|
||||
// requires secure connection?
|
||||
if c.opts.Secure || c.opts.TLSConfig != nil {
|
||||
config.Scheme = "https"
|
||||
// We're going to support InsecureSkipVerify
|
||||
config.HttpClient.Transport = newTransport(c.opts.TLSConfig)
|
||||
}
|
||||
|
||||
// set timeout
|
||||
if c.opts.Timeout > 0 {
|
||||
config.HttpClient.Timeout = c.opts.Timeout
|
||||
}
|
||||
|
||||
// set the config
|
||||
c.config = config
|
||||
|
||||
// remove client
|
||||
c.client = nil
|
||||
|
||||
// setup the client
|
||||
c.Client()
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Init(opts ...registry.Option) error {
|
||||
configure(c, opts...)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Deregister(s *registry.Service, opts ...registry.DeregisterOption) error {
|
||||
if len(s.Nodes) == 0 {
|
||||
return errors.New("Require at least one node")
|
||||
}
|
||||
|
||||
// delete our hash and time check of the service
|
||||
c.Lock()
|
||||
delete(c.register, s.Name)
|
||||
delete(c.lastChecked, s.Name)
|
||||
c.Unlock()
|
||||
|
||||
node := s.Nodes[0]
|
||||
return c.Client().Agent().ServiceDeregister(node.Id)
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Register(s *registry.Service, opts ...registry.RegisterOption) error {
|
||||
if len(s.Nodes) == 0 {
|
||||
return errors.New("Require at least one node")
|
||||
}
|
||||
|
||||
var regTCPCheck bool
|
||||
var regInterval time.Duration
|
||||
var regHTTPCheck bool
|
||||
var httpCheckConfig consul.AgentServiceCheck
|
||||
|
||||
var options registry.RegisterOptions
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
if c.opts.Context != nil {
|
||||
if tcpCheckInterval, ok := c.opts.Context.Value("consul_tcp_check").(time.Duration); ok {
|
||||
regTCPCheck = true
|
||||
regInterval = tcpCheckInterval
|
||||
}
|
||||
var ok bool
|
||||
if httpCheckConfig, ok = c.opts.Context.Value("consul_http_check_config").(consul.AgentServiceCheck); ok {
|
||||
regHTTPCheck = true
|
||||
}
|
||||
}
|
||||
|
||||
// create hash of service; uint64
|
||||
h, err := hash.Hash(s, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// use first node
|
||||
node := s.Nodes[0]
|
||||
|
||||
// get existing hash and last checked time
|
||||
c.Lock()
|
||||
v, ok := c.register[s.Name]
|
||||
lastChecked := c.lastChecked[s.Name]
|
||||
c.Unlock()
|
||||
|
||||
// if it's already registered and matches then just pass the check
|
||||
if ok && v == h {
|
||||
if options.TTL == time.Duration(0) {
|
||||
// ensure that our service hasn't been deregistered by Consul
|
||||
if time.Since(lastChecked) <= getDeregisterTTL(regInterval) {
|
||||
return nil
|
||||
}
|
||||
services, _, err := c.Client().Health().Checks(s.Name, c.queryOptions)
|
||||
if err == nil {
|
||||
for _, v := range services {
|
||||
if v.ServiceID == node.Id {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if the err is nil we're all good, bail out
|
||||
// if not, we don't know what the state is, so full re-register
|
||||
if err := c.Client().Agent().PassTTL("service:"+node.Id, ""); err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// encode the tags
|
||||
tags := encodeMetadata(node.Metadata)
|
||||
tags = append(tags, encodeEndpoints(s.Endpoints)...)
|
||||
tags = append(tags, encodeVersion(s.Version)...)
|
||||
|
||||
var check *consul.AgentServiceCheck
|
||||
|
||||
if regTCPCheck {
|
||||
deregTTL := getDeregisterTTL(regInterval)
|
||||
|
||||
check = &consul.AgentServiceCheck{
|
||||
TCP: node.Address,
|
||||
Interval: fmt.Sprintf("%v", regInterval),
|
||||
DeregisterCriticalServiceAfter: fmt.Sprintf("%v", deregTTL),
|
||||
}
|
||||
|
||||
} else if regHTTPCheck {
|
||||
interval, _ := time.ParseDuration(httpCheckConfig.Interval)
|
||||
deregTTL := getDeregisterTTL(interval)
|
||||
|
||||
host, _, _ := net.SplitHostPort(node.Address)
|
||||
healthCheckURI := strings.Replace(httpCheckConfig.HTTP, "{host}", host, 1)
|
||||
|
||||
check = &consul.AgentServiceCheck{
|
||||
HTTP: healthCheckURI,
|
||||
Interval: httpCheckConfig.Interval,
|
||||
Timeout: httpCheckConfig.Timeout,
|
||||
DeregisterCriticalServiceAfter: fmt.Sprintf("%v", deregTTL),
|
||||
}
|
||||
|
||||
// if the TTL is greater than 0 create an associated check
|
||||
} else if options.TTL > time.Duration(0) {
|
||||
deregTTL := getDeregisterTTL(options.TTL)
|
||||
|
||||
check = &consul.AgentServiceCheck{
|
||||
TTL: fmt.Sprintf("%v", options.TTL),
|
||||
DeregisterCriticalServiceAfter: fmt.Sprintf("%v", deregTTL),
|
||||
}
|
||||
}
|
||||
|
||||
host, pt, _ := net.SplitHostPort(node.Address)
|
||||
if host == "" {
|
||||
host = node.Address
|
||||
}
|
||||
port, _ := strconv.Atoi(pt)
|
||||
|
||||
// register the service
|
||||
asr := &consul.AgentServiceRegistration{
|
||||
ID: node.Id,
|
||||
Name: s.Name,
|
||||
Tags: tags,
|
||||
Port: port,
|
||||
Address: host,
|
||||
Meta: node.Metadata,
|
||||
Check: check,
|
||||
}
|
||||
|
||||
// Specify consul connect
|
||||
if c.connect {
|
||||
asr.Connect = &consul.AgentServiceConnect{
|
||||
Native: true,
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.Client().Agent().ServiceRegister(asr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// save our hash and time check of the service
|
||||
c.Lock()
|
||||
c.register[s.Name] = h
|
||||
c.lastChecked[s.Name] = time.Now()
|
||||
c.Unlock()
|
||||
|
||||
// if the TTL is 0 we don't mess with the checks
|
||||
if options.TTL == time.Duration(0) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// pass the healthcheck
|
||||
return c.Client().Agent().PassTTL("service:"+node.Id, "")
|
||||
}
|
||||
|
||||
func (c *consulRegistry) GetService(name string, opts ...registry.GetOption) ([]*registry.Service, error) {
|
||||
var rsp []*consul.ServiceEntry
|
||||
var err error
|
||||
|
||||
// if we're connect enabled only get connect services
|
||||
if c.connect {
|
||||
rsp, _, err = c.Client().Health().Connect(name, "", false, c.queryOptions)
|
||||
} else {
|
||||
rsp, _, err = c.Client().Health().Service(name, "", false, c.queryOptions)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serviceMap := map[string]*registry.Service{}
|
||||
|
||||
for _, s := range rsp {
|
||||
if s.Service.Service != name {
|
||||
continue
|
||||
}
|
||||
|
||||
// version is now a tag
|
||||
version, _ := decodeVersion(s.Service.Tags)
|
||||
// service ID is now the node id
|
||||
id := s.Service.ID
|
||||
// key is always the version
|
||||
key := version
|
||||
|
||||
// address is service address
|
||||
address := s.Service.Address
|
||||
|
||||
// use node address
|
||||
if len(address) == 0 {
|
||||
address = s.Node.Address
|
||||
}
|
||||
|
||||
svc, ok := serviceMap[key]
|
||||
if !ok {
|
||||
svc = ®istry.Service{
|
||||
Endpoints: decodeEndpoints(s.Service.Tags),
|
||||
Name: s.Service.Service,
|
||||
Version: version,
|
||||
}
|
||||
serviceMap[key] = svc
|
||||
}
|
||||
|
||||
var del bool
|
||||
|
||||
for _, check := range s.Checks {
|
||||
// delete the node if the status is critical
|
||||
if check.Status == "critical" {
|
||||
del = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// if delete then skip the node
|
||||
if del {
|
||||
continue
|
||||
}
|
||||
|
||||
svc.Nodes = append(svc.Nodes, ®istry.Node{
|
||||
Id: id,
|
||||
Address: mnet.HostPort(address, s.Service.Port),
|
||||
Metadata: decodeMetadata(s.Service.Tags),
|
||||
})
|
||||
}
|
||||
|
||||
var services []*registry.Service
|
||||
for _, service := range serviceMap {
|
||||
services = append(services, service)
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (c *consulRegistry) ListServices(opts ...registry.ListOption) ([]*registry.Service, error) {
|
||||
rsp, _, err := c.Client().Catalog().Services(c.queryOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var services []*registry.Service
|
||||
|
||||
for service := range rsp {
|
||||
services = append(services, ®istry.Service{Name: service})
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Watch(opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
return newConsulWatcher(c, opts...)
|
||||
}
|
||||
|
||||
func (c *consulRegistry) String() string {
|
||||
return "consul"
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Options() registry.Options {
|
||||
return c.opts
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Client() *consul.Client {
|
||||
if c.client != nil {
|
||||
return c.client
|
||||
}
|
||||
|
||||
for _, addr := range c.Address {
|
||||
// set the address
|
||||
c.config.Address = addr
|
||||
|
||||
// create a new client
|
||||
tmpClient, _ := consul.NewClient(c.config)
|
||||
|
||||
// test the client
|
||||
_, err := tmpClient.Agent().Host()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// set the client
|
||||
c.client = tmpClient
|
||||
return c.client
|
||||
}
|
||||
|
||||
// set the default
|
||||
c.client, _ = consul.NewClient(c.config)
|
||||
|
||||
// return the client
|
||||
return c.client
|
||||
}
|
||||
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
cr := &consulRegistry{
|
||||
opts: registry.Options{},
|
||||
register: make(map[string]uint64),
|
||||
lastChecked: make(map[string]time.Time),
|
||||
queryOptions: &consul.QueryOptions{
|
||||
AllowStale: true,
|
||||
},
|
||||
}
|
||||
configure(cr, opts...)
|
||||
return cr
|
||||
}
|
||||
171
vendor/github.com/go-micro/plugins/v4/registry/consul/encoding.go
generated
vendored
171
vendor/github.com/go-micro/plugins/v4/registry/consul/encoding.go
generated
vendored
@@ -1,171 +0,0 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"go-micro.dev/v4/registry"
|
||||
)
|
||||
|
||||
func encode(buf []byte) string {
|
||||
var b bytes.Buffer
|
||||
defer b.Reset()
|
||||
|
||||
w := zlib.NewWriter(&b)
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
return ""
|
||||
}
|
||||
w.Close()
|
||||
|
||||
return hex.EncodeToString(b.Bytes())
|
||||
}
|
||||
|
||||
func decode(d string) []byte {
|
||||
hr, err := hex.DecodeString(d)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
br := bytes.NewReader(hr)
|
||||
zr, err := zlib.NewReader(br)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
rbuf, err := io.ReadAll(zr)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
zr.Close()
|
||||
|
||||
return rbuf
|
||||
}
|
||||
|
||||
func encodeEndpoints(en []*registry.Endpoint) []string {
|
||||
var tags []string
|
||||
for _, e := range en {
|
||||
if b, err := json.Marshal(e); err == nil {
|
||||
tags = append(tags, "e-"+encode(b))
|
||||
}
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
func decodeEndpoints(tags []string) []*registry.Endpoint {
|
||||
var en []*registry.Endpoint
|
||||
|
||||
// use the first format you find
|
||||
var ver byte
|
||||
|
||||
for _, tag := range tags {
|
||||
if len(tag) == 0 || tag[0] != 'e' {
|
||||
continue
|
||||
}
|
||||
|
||||
// check version
|
||||
if ver > 0 && tag[1] != ver {
|
||||
continue
|
||||
}
|
||||
|
||||
var e *registry.Endpoint
|
||||
var buf []byte
|
||||
|
||||
// Old encoding was plain
|
||||
if tag[1] == '=' {
|
||||
buf = []byte(tag[2:])
|
||||
}
|
||||
|
||||
// New encoding is hex
|
||||
if tag[1] == '-' {
|
||||
buf = decode(tag[2:])
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(buf, &e); err == nil {
|
||||
en = append(en, e)
|
||||
}
|
||||
|
||||
// set version
|
||||
ver = tag[1]
|
||||
}
|
||||
return en
|
||||
}
|
||||
|
||||
func encodeMetadata(md map[string]string) []string {
|
||||
var tags []string
|
||||
for k, v := range md {
|
||||
if b, err := json.Marshal(map[string]string{
|
||||
k: v,
|
||||
}); err == nil {
|
||||
// new encoding
|
||||
tags = append(tags, "t-"+encode(b))
|
||||
}
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
func decodeMetadata(tags []string) map[string]string {
|
||||
md := make(map[string]string)
|
||||
|
||||
var ver byte
|
||||
|
||||
for _, tag := range tags {
|
||||
if len(tag) == 0 || tag[0] != 't' {
|
||||
continue
|
||||
}
|
||||
|
||||
// check version
|
||||
if ver > 0 && tag[1] != ver {
|
||||
continue
|
||||
}
|
||||
|
||||
var kv map[string]string
|
||||
var buf []byte
|
||||
|
||||
// Old encoding was plain
|
||||
if tag[1] == '=' {
|
||||
buf = []byte(tag[2:])
|
||||
}
|
||||
|
||||
// New encoding is hex
|
||||
if tag[1] == '-' {
|
||||
buf = decode(tag[2:])
|
||||
}
|
||||
|
||||
// Now unmarshal
|
||||
if err := json.Unmarshal(buf, &kv); err == nil {
|
||||
for k, v := range kv {
|
||||
md[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// set version
|
||||
ver = tag[1]
|
||||
}
|
||||
return md
|
||||
}
|
||||
|
||||
func encodeVersion(v string) []string {
|
||||
return []string{"v-" + encode([]byte(v))}
|
||||
}
|
||||
|
||||
func decodeVersion(tags []string) (string, bool) {
|
||||
for _, tag := range tags {
|
||||
if len(tag) < 2 || tag[0] != 'v' {
|
||||
continue
|
||||
}
|
||||
|
||||
// Old encoding was plain
|
||||
if tag[1] == '=' {
|
||||
return tag[2:], true
|
||||
}
|
||||
|
||||
// New encoding is hex
|
||||
if tag[1] == '-' {
|
||||
return string(decode(tag[2:])), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
101
vendor/github.com/go-micro/plugins/v4/registry/consul/options.go
generated
vendored
101
vendor/github.com/go-micro/plugins/v4/registry/consul/options.go
generated
vendored
@@ -1,101 +0,0 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
"go-micro.dev/v4/registry"
|
||||
)
|
||||
|
||||
// Connect specifies services should be registered as Consul Connect services.
|
||||
func Connect() registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, "consul_connect", true)
|
||||
}
|
||||
}
|
||||
|
||||
func Config(c *consul.Config) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, "consul_config", c)
|
||||
}
|
||||
}
|
||||
|
||||
// AllowStale sets whether any Consul server (non-leader) can service
|
||||
// a read. This allows for lower latency and higher throughput
|
||||
// at the cost of potentially stale data.
|
||||
// Works similar to Consul DNS Config option [1].
|
||||
// Defaults to true.
|
||||
//
|
||||
// [1] https://www.consul.io/docs/agent/options.html#allow_stale
|
||||
func AllowStale(v bool) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, "consul_allow_stale", v)
|
||||
}
|
||||
}
|
||||
|
||||
// QueryOptions specifies the QueryOptions to be used when calling
|
||||
// Consul. See `Consul API` for more information [1].
|
||||
//
|
||||
// [1] https://godoc.org/github.com/hashicorp/consul/api#QueryOptions
|
||||
func QueryOptions(q *consul.QueryOptions) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if q == nil {
|
||||
return
|
||||
}
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, "consul_query_options", q)
|
||||
}
|
||||
}
|
||||
|
||||
// TCPCheck will tell the service provider to check the service address
|
||||
// and port every `t` interval. It will enabled only if `t` is greater than 0.
|
||||
// See `TCP + Interval` for more information [1].
|
||||
//
|
||||
// [1] https://www.consul.io/docs/agent/checks.html
|
||||
func TCPCheck(t time.Duration) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if t <= time.Duration(0) {
|
||||
return
|
||||
}
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, "consul_tcp_check", t)
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPCheck will tell the service provider to invoke the health check endpoint
|
||||
// with an interval and timeout. It will be enabled only if interval and
|
||||
// timeout are greater than 0.
|
||||
// See `HTTP + Interval` for more information [1].
|
||||
//
|
||||
// [1] https://www.consul.io/docs/agent/checks.html
|
||||
func HTTPCheck(protocol, port, httpEndpoint string, interval, timeout time.Duration) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if interval <= time.Duration(0) || timeout <= time.Duration(0) {
|
||||
return
|
||||
}
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
check := consul.AgentServiceCheck{
|
||||
HTTP: fmt.Sprintf("%s://{host}:%s%s", protocol, port, httpEndpoint),
|
||||
Interval: fmt.Sprintf("%v", interval),
|
||||
Timeout: fmt.Sprintf("%v", timeout),
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, "consul_http_check_config", check)
|
||||
}
|
||||
}
|
||||
299
vendor/github.com/go-micro/plugins/v4/registry/consul/watcher.go
generated
vendored
299
vendor/github.com/go-micro/plugins/v4/registry/consul/watcher.go
generated
vendored
@@ -1,299 +0,0 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/api/watch"
|
||||
"go-micro.dev/v4/registry"
|
||||
regutil "go-micro.dev/v4/util/registry"
|
||||
)
|
||||
|
||||
type consulWatcher struct {
|
||||
r *consulRegistry
|
||||
wo registry.WatchOptions
|
||||
wp *watch.Plan
|
||||
watchers map[string]*watch.Plan
|
||||
|
||||
next chan *registry.Result
|
||||
exit chan bool
|
||||
|
||||
sync.RWMutex
|
||||
services map[string][]*registry.Service
|
||||
}
|
||||
|
||||
func newConsulWatcher(cr *consulRegistry, opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
var wo registry.WatchOptions
|
||||
for _, o := range opts {
|
||||
o(&wo)
|
||||
}
|
||||
|
||||
cw := &consulWatcher{
|
||||
r: cr,
|
||||
wo: wo,
|
||||
exit: make(chan bool),
|
||||
next: make(chan *registry.Result, 10),
|
||||
watchers: make(map[string]*watch.Plan),
|
||||
services: make(map[string][]*registry.Service),
|
||||
}
|
||||
|
||||
wp, err := watch.Parse(map[string]interface{}{
|
||||
"service": wo.Service,
|
||||
"type": "service",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wp.Handler = cw.serviceHandler
|
||||
go wp.RunWithClientAndHclog(cr.Client(), wp.Logger)
|
||||
cw.wp = wp
|
||||
|
||||
return cw, nil
|
||||
}
|
||||
|
||||
func (cw *consulWatcher) serviceHandler(idx uint64, data interface{}) {
|
||||
entries, ok := data.([]*api.ServiceEntry)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
serviceMap := map[string]*registry.Service{}
|
||||
serviceName := ""
|
||||
|
||||
for _, e := range entries {
|
||||
serviceName = e.Service.Service
|
||||
// version is now a tag
|
||||
version, _ := decodeVersion(e.Service.Tags)
|
||||
// service ID is now the node id
|
||||
id := e.Service.ID
|
||||
// key is always the version
|
||||
key := version
|
||||
// address is service address
|
||||
address := e.Service.Address
|
||||
|
||||
// use node address
|
||||
if len(address) == 0 {
|
||||
address = e.Node.Address
|
||||
}
|
||||
|
||||
svc, ok := serviceMap[key]
|
||||
if !ok {
|
||||
svc = ®istry.Service{
|
||||
Endpoints: decodeEndpoints(e.Service.Tags),
|
||||
Name: e.Service.Service,
|
||||
Version: version,
|
||||
}
|
||||
serviceMap[key] = svc
|
||||
}
|
||||
|
||||
var del bool
|
||||
|
||||
for _, check := range e.Checks {
|
||||
// delete the node if the status is critical
|
||||
if check.Status == "critical" {
|
||||
del = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// if delete then skip the node
|
||||
if del {
|
||||
continue
|
||||
}
|
||||
|
||||
svc.Nodes = append(svc.Nodes, ®istry.Node{
|
||||
Id: id,
|
||||
Address: net.JoinHostPort(address, fmt.Sprint(e.Service.Port)),
|
||||
Metadata: decodeMetadata(e.Service.Tags),
|
||||
})
|
||||
}
|
||||
|
||||
cw.RLock()
|
||||
// make a copy
|
||||
rservices := make(map[string][]*registry.Service)
|
||||
for k, v := range cw.services {
|
||||
rservices[k] = v
|
||||
}
|
||||
cw.RUnlock()
|
||||
|
||||
var newServices []*registry.Service
|
||||
|
||||
// serviceMap is the new set of services keyed by name+version
|
||||
for _, newService := range serviceMap {
|
||||
// append to the new set of cached services
|
||||
newServices = append(newServices, newService)
|
||||
|
||||
// check if the service exists in the existing cache
|
||||
oldServices, ok := rservices[serviceName]
|
||||
if !ok {
|
||||
// does not exist? then we're creating brand new entries
|
||||
cw.next <- ®istry.Result{Action: "create", Service: newService}
|
||||
continue
|
||||
}
|
||||
|
||||
// service exists. ok let's figure out what to update and delete version wise
|
||||
action := "create"
|
||||
|
||||
for _, oldService := range oldServices {
|
||||
// does this version exist?
|
||||
// no? then default to create
|
||||
if oldService.Version != newService.Version {
|
||||
continue
|
||||
}
|
||||
|
||||
// yes? then it's an update
|
||||
action = "update"
|
||||
|
||||
var nodes []*registry.Node
|
||||
// check the old nodes to see if they've been deleted
|
||||
for _, oldNode := range oldService.Nodes {
|
||||
var seen bool
|
||||
for _, newNode := range newService.Nodes {
|
||||
if newNode.Id == oldNode.Id {
|
||||
seen = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// does the old node exist in the new set of nodes
|
||||
// no? then delete that shit
|
||||
if !seen {
|
||||
nodes = append(nodes, oldNode)
|
||||
}
|
||||
}
|
||||
|
||||
// it's an update rather than creation
|
||||
if len(nodes) > 0 {
|
||||
delService := regutil.CopyService(oldService)
|
||||
delService.Nodes = nodes
|
||||
cw.next <- ®istry.Result{Action: "delete", Service: delService}
|
||||
}
|
||||
}
|
||||
|
||||
cw.next <- ®istry.Result{Action: action, Service: newService}
|
||||
}
|
||||
|
||||
// Now check old versions that may not be in new services map
|
||||
for _, old := range rservices[serviceName] {
|
||||
// old version does not exist in new version map
|
||||
// kill it with fire!
|
||||
if _, ok := serviceMap[old.Version]; !ok {
|
||||
cw.next <- ®istry.Result{Action: "delete", Service: old}
|
||||
}
|
||||
}
|
||||
|
||||
// there are no services in the service, empty all services
|
||||
if len(rservices) != 0 && serviceName == "" {
|
||||
for _, services := range rservices {
|
||||
for _, service := range services {
|
||||
cw.next <- ®istry.Result{Action: "delete", Service: service}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cw.Lock()
|
||||
cw.services[serviceName] = newServices
|
||||
cw.Unlock()
|
||||
}
|
||||
|
||||
func (cw *consulWatcher) handle(idx uint64, data interface{}) {
|
||||
services, ok := data.(map[string][]string)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// add new watchers
|
||||
for service := range services {
|
||||
// Filter on watch options
|
||||
// wo.Service: Only watch services we care about
|
||||
if len(cw.wo.Service) > 0 && service != cw.wo.Service {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := cw.watchers[service]; ok {
|
||||
continue
|
||||
}
|
||||
wp, err := watch.Parse(map[string]interface{}{
|
||||
"type": "service",
|
||||
"service": service,
|
||||
})
|
||||
if err == nil {
|
||||
wp.Handler = cw.serviceHandler
|
||||
go wp.RunWithClientAndHclog(cw.r.Client(), wp.Logger)
|
||||
cw.watchers[service] = wp
|
||||
cw.next <- ®istry.Result{Action: "create", Service: ®istry.Service{Name: service}}
|
||||
}
|
||||
}
|
||||
|
||||
cw.RLock()
|
||||
// make a copy
|
||||
rservices := make(map[string][]*registry.Service)
|
||||
for k, v := range cw.services {
|
||||
rservices[k] = v
|
||||
}
|
||||
cw.RUnlock()
|
||||
|
||||
// remove unknown services from registry
|
||||
// save the things we want to delete
|
||||
deleted := make(map[string][]*registry.Service)
|
||||
|
||||
for service := range rservices {
|
||||
if _, ok := services[service]; !ok {
|
||||
cw.Lock()
|
||||
// save this before deleting
|
||||
deleted[service] = cw.services[service]
|
||||
delete(cw.services, service)
|
||||
cw.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// remove unknown services from watchers
|
||||
for service, w := range cw.watchers {
|
||||
if _, ok := services[service]; !ok {
|
||||
w.Stop()
|
||||
delete(cw.watchers, service)
|
||||
for _, oldService := range deleted[service] {
|
||||
// send a delete for the service nodes that we're removing
|
||||
cw.next <- ®istry.Result{Action: "delete", Service: oldService}
|
||||
}
|
||||
// sent the empty list as the last resort to indicate to delete the entire service
|
||||
cw.next <- ®istry.Result{Action: "delete", Service: ®istry.Service{Name: service}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cw *consulWatcher) Next() (*registry.Result, error) {
|
||||
select {
|
||||
case <-cw.exit:
|
||||
return nil, registry.ErrWatcherStopped
|
||||
case r, ok := <-cw.next:
|
||||
if !ok {
|
||||
return nil, registry.ErrWatcherStopped
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (cw *consulWatcher) Stop() {
|
||||
select {
|
||||
case <-cw.exit:
|
||||
return
|
||||
default:
|
||||
close(cw.exit)
|
||||
if cw.wp == nil {
|
||||
return
|
||||
}
|
||||
cw.wp.Stop()
|
||||
|
||||
// drain results
|
||||
for {
|
||||
select {
|
||||
case <-cw.next:
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
191
vendor/github.com/go-micro/plugins/v4/registry/etcd/LICENSE
generated
vendored
191
vendor/github.com/go-micro/plugins/v4/registry/etcd/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015 Asim Aslam.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
423
vendor/github.com/go-micro/plugins/v4/registry/etcd/etcd.go
generated
vendored
423
vendor/github.com/go-micro/plugins/v4/registry/etcd/etcd.go
generated
vendored
@@ -1,423 +0,0 @@
|
||||
// Package etcd provides an etcd service registry
|
||||
package etcd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
hash "github.com/mitchellh/hashstructure"
|
||||
"go-micro.dev/v4/logger"
|
||||
"go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/util/cmd"
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
prefix = "/micro/registry/"
|
||||
)
|
||||
|
||||
type etcdRegistry struct {
|
||||
client *clientv3.Client
|
||||
options registry.Options
|
||||
|
||||
sync.RWMutex
|
||||
register map[string]uint64
|
||||
leases map[string]clientv3.LeaseID
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmd.DefaultRegistries["etcd"] = NewRegistry
|
||||
}
|
||||
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
e := &etcdRegistry{
|
||||
options: registry.Options{},
|
||||
register: make(map[string]uint64),
|
||||
leases: make(map[string]clientv3.LeaseID),
|
||||
}
|
||||
username, password := os.Getenv("ETCD_USERNAME"), os.Getenv("ETCD_PASSWORD")
|
||||
if len(username) > 0 && len(password) > 0 {
|
||||
opts = append(opts, Auth(username, password))
|
||||
}
|
||||
address := os.Getenv("MICRO_REGISTRY_ADDRESS")
|
||||
if len(address) > 0 {
|
||||
opts = append(opts, registry.Addrs(address))
|
||||
}
|
||||
configure(e, opts...)
|
||||
return e
|
||||
}
|
||||
|
||||
func configure(e *etcdRegistry, opts ...registry.Option) error {
|
||||
config := clientv3.Config{
|
||||
Endpoints: []string{"127.0.0.1:2379"},
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&e.options)
|
||||
}
|
||||
|
||||
if e.options.Timeout == 0 {
|
||||
e.options.Timeout = 5 * time.Second
|
||||
}
|
||||
|
||||
if e.options.Logger == nil {
|
||||
e.options.Logger = logger.DefaultLogger
|
||||
}
|
||||
|
||||
config.DialTimeout = e.options.Timeout
|
||||
|
||||
if e.options.Secure || e.options.TLSConfig != nil {
|
||||
tlsConfig := e.options.TLSConfig
|
||||
if tlsConfig == nil {
|
||||
tlsConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
}
|
||||
|
||||
config.TLS = tlsConfig
|
||||
}
|
||||
|
||||
if e.options.Context != nil {
|
||||
u, ok := e.options.Context.Value(authKey{}).(*authCreds)
|
||||
if ok {
|
||||
config.Username = u.Username
|
||||
config.Password = u.Password
|
||||
}
|
||||
cfg, ok := e.options.Context.Value(logConfigKey{}).(*zap.Config)
|
||||
if ok && cfg != nil {
|
||||
config.LogConfig = cfg
|
||||
}
|
||||
}
|
||||
|
||||
var cAddrs []string
|
||||
|
||||
for _, address := range e.options.Addrs {
|
||||
if len(address) == 0 {
|
||||
continue
|
||||
}
|
||||
addr, port, err := net.SplitHostPort(address)
|
||||
if ae, ok := err.(*net.AddrError); ok && ae.Err == "missing port in address" {
|
||||
port = "2379"
|
||||
addr = address
|
||||
cAddrs = append(cAddrs, net.JoinHostPort(addr, port))
|
||||
} else if err == nil {
|
||||
cAddrs = append(cAddrs, net.JoinHostPort(addr, port))
|
||||
}
|
||||
}
|
||||
|
||||
// if we got addrs then we'll update
|
||||
if len(cAddrs) > 0 {
|
||||
config.Endpoints = cAddrs
|
||||
}
|
||||
|
||||
cli, err := clientv3.New(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.client = cli
|
||||
return nil
|
||||
}
|
||||
|
||||
func encode(s *registry.Service) string {
|
||||
b, _ := json.Marshal(s)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func decode(ds []byte) *registry.Service {
|
||||
var s *registry.Service
|
||||
json.Unmarshal(ds, &s)
|
||||
return s
|
||||
}
|
||||
|
||||
func nodePath(s, id string) string {
|
||||
service := strings.Replace(s, "/", "-", -1)
|
||||
node := strings.Replace(id, "/", "-", -1)
|
||||
return path.Join(prefix, service, node)
|
||||
}
|
||||
|
||||
func servicePath(s string) string {
|
||||
return path.Join(prefix, strings.Replace(s, "/", "-", -1))
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) Init(opts ...registry.Option) error {
|
||||
return configure(e, opts...)
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) Options() registry.Options {
|
||||
return e.options
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) registerNode(s *registry.Service, node *registry.Node, opts ...registry.RegisterOption) error {
|
||||
if len(s.Nodes) == 0 {
|
||||
return errors.New("Require at least one node")
|
||||
}
|
||||
|
||||
// check existing lease cache
|
||||
e.RLock()
|
||||
leaseID, ok := e.leases[s.Name+node.Id]
|
||||
e.RUnlock()
|
||||
|
||||
log := e.options.Logger
|
||||
|
||||
if !ok {
|
||||
// missing lease, check if the key exists
|
||||
ctx, cancel := context.WithTimeout(context.Background(), e.options.Timeout)
|
||||
defer cancel()
|
||||
|
||||
// look for the existing key
|
||||
rsp, err := e.client.Get(ctx, nodePath(s.Name, node.Id), clientv3.WithSerializable())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get the existing lease
|
||||
for _, kv := range rsp.Kvs {
|
||||
if kv.Lease > 0 {
|
||||
leaseID = clientv3.LeaseID(kv.Lease)
|
||||
|
||||
// decode the existing node
|
||||
srv := decode(kv.Value)
|
||||
if srv == nil || len(srv.Nodes) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// create hash of service; uint64
|
||||
h, err := hash.Hash(srv.Nodes[0], nil)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// save the info
|
||||
e.Lock()
|
||||
e.leases[s.Name+node.Id] = leaseID
|
||||
e.register[s.Name+node.Id] = h
|
||||
e.Unlock()
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var leaseNotFound bool
|
||||
|
||||
// renew the lease if it exists
|
||||
if leaseID > 0 {
|
||||
log.Logf(logger.TraceLevel, "Renewing existing lease for %s %d", s.Name, leaseID)
|
||||
if _, err := e.client.KeepAliveOnce(context.TODO(), leaseID); err != nil {
|
||||
if err != rpctypes.ErrLeaseNotFound {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Logf(logger.TraceLevel, "Lease not found for %s %d", s.Name, leaseID)
|
||||
// lease not found do register
|
||||
leaseNotFound = true
|
||||
}
|
||||
}
|
||||
|
||||
// create hash of service; uint64
|
||||
h, err := hash.Hash(node, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get existing hash for the service node
|
||||
e.Lock()
|
||||
v, ok := e.register[s.Name+node.Id]
|
||||
e.Unlock()
|
||||
|
||||
// the service is unchanged, skip registering
|
||||
if ok && v == h && !leaseNotFound {
|
||||
log.Logf(logger.TraceLevel, "Service %s node %s unchanged skipping registration", s.Name, node.Id)
|
||||
return nil
|
||||
}
|
||||
|
||||
service := ®istry.Service{
|
||||
Name: s.Name,
|
||||
Version: s.Version,
|
||||
Metadata: s.Metadata,
|
||||
Endpoints: s.Endpoints,
|
||||
Nodes: []*registry.Node{node},
|
||||
}
|
||||
|
||||
var options registry.RegisterOptions
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), e.options.Timeout)
|
||||
defer cancel()
|
||||
|
||||
var lgr *clientv3.LeaseGrantResponse
|
||||
if options.TTL.Seconds() > 0 {
|
||||
// get a lease used to expire keys since we have a ttl
|
||||
lgr, err = e.client.Grant(ctx, int64(options.TTL.Seconds()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Logf(logger.TraceLevel, "Registering %s id %s with lease %v and leaseID %v and ttl %v", service.Name, node.Id, lgr, lgr.ID, options.TTL)
|
||||
// create an entry for the node
|
||||
if lgr != nil {
|
||||
_, err = e.client.Put(ctx, nodePath(service.Name, node.Id), encode(service), clientv3.WithLease(lgr.ID))
|
||||
} else {
|
||||
_, err = e.client.Put(ctx, nodePath(service.Name, node.Id), encode(service))
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.Lock()
|
||||
// save our hash of the service
|
||||
e.register[s.Name+node.Id] = h
|
||||
// save our leaseID of the service
|
||||
if lgr != nil {
|
||||
e.leases[s.Name+node.Id] = lgr.ID
|
||||
}
|
||||
e.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) Deregister(s *registry.Service, opts ...registry.DeregisterOption) error {
|
||||
if len(s.Nodes) == 0 {
|
||||
return errors.New("Require at least one node")
|
||||
}
|
||||
|
||||
for _, node := range s.Nodes {
|
||||
e.Lock()
|
||||
// delete our hash of the service
|
||||
delete(e.register, s.Name+node.Id)
|
||||
// delete our lease of the service
|
||||
delete(e.leases, s.Name+node.Id)
|
||||
e.Unlock()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), e.options.Timeout)
|
||||
defer cancel()
|
||||
|
||||
e.options.Logger.Logf(logger.TraceLevel, "Deregistering %s id %s", s.Name, node.Id)
|
||||
_, err := e.client.Delete(ctx, nodePath(s.Name, node.Id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) Register(s *registry.Service, opts ...registry.RegisterOption) error {
|
||||
if len(s.Nodes) == 0 {
|
||||
return errors.New("Require at least one node")
|
||||
}
|
||||
|
||||
var gerr error
|
||||
|
||||
// register each node individually
|
||||
for _, node := range s.Nodes {
|
||||
err := e.registerNode(s, node, opts...)
|
||||
if err != nil {
|
||||
gerr = err
|
||||
}
|
||||
}
|
||||
|
||||
return gerr
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) GetService(name string, opts ...registry.GetOption) ([]*registry.Service, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), e.options.Timeout)
|
||||
defer cancel()
|
||||
|
||||
rsp, err := e.client.Get(ctx, servicePath(name)+"/", clientv3.WithPrefix(), clientv3.WithSerializable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(rsp.Kvs) == 0 {
|
||||
return nil, registry.ErrNotFound
|
||||
}
|
||||
|
||||
serviceMap := map[string]*registry.Service{}
|
||||
|
||||
for _, n := range rsp.Kvs {
|
||||
if sn := decode(n.Value); sn != nil {
|
||||
s, ok := serviceMap[sn.Version]
|
||||
if !ok {
|
||||
s = ®istry.Service{
|
||||
Name: sn.Name,
|
||||
Version: sn.Version,
|
||||
Metadata: sn.Metadata,
|
||||
Endpoints: sn.Endpoints,
|
||||
}
|
||||
serviceMap[s.Version] = s
|
||||
}
|
||||
|
||||
s.Nodes = append(s.Nodes, sn.Nodes...)
|
||||
}
|
||||
}
|
||||
|
||||
services := make([]*registry.Service, 0, len(serviceMap))
|
||||
for _, service := range serviceMap {
|
||||
services = append(services, service)
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) ListServices(opts ...registry.ListOption) ([]*registry.Service, error) {
|
||||
versions := make(map[string]*registry.Service)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), e.options.Timeout)
|
||||
defer cancel()
|
||||
|
||||
rsp, err := e.client.Get(ctx, prefix, clientv3.WithPrefix(), clientv3.WithSerializable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(rsp.Kvs) == 0 {
|
||||
return []*registry.Service{}, nil
|
||||
}
|
||||
|
||||
for _, n := range rsp.Kvs {
|
||||
sn := decode(n.Value)
|
||||
if sn == nil {
|
||||
continue
|
||||
}
|
||||
v, ok := versions[sn.Name+sn.Version]
|
||||
if !ok {
|
||||
versions[sn.Name+sn.Version] = sn
|
||||
continue
|
||||
}
|
||||
// append to service:version nodes
|
||||
v.Nodes = append(v.Nodes, sn.Nodes...)
|
||||
}
|
||||
|
||||
services := make([]*registry.Service, 0, len(versions))
|
||||
for _, service := range versions {
|
||||
services = append(services, service)
|
||||
}
|
||||
|
||||
// sort the services
|
||||
sort.Slice(services, func(i, j int) bool { return services[i].Name < services[j].Name })
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) Watch(opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
return newEtcdWatcher(e, e.options.Timeout, opts...)
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) String() string {
|
||||
return "etcd"
|
||||
}
|
||||
37
vendor/github.com/go-micro/plugins/v4/registry/etcd/options.go
generated
vendored
37
vendor/github.com/go-micro/plugins/v4/registry/etcd/options.go
generated
vendored
@@ -1,37 +0,0 @@
|
||||
package etcd
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-micro.dev/v4/registry"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type authKey struct{}
|
||||
|
||||
type logConfigKey struct{}
|
||||
|
||||
type authCreds struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// Auth allows you to specify username/password.
|
||||
func Auth(username, password string) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, authKey{}, &authCreds{Username: username, Password: password})
|
||||
}
|
||||
}
|
||||
|
||||
// LogConfig allows you to set etcd log config.
|
||||
func LogConfig(config *zap.Config) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, logConfigKey{}, config)
|
||||
}
|
||||
}
|
||||
91
vendor/github.com/go-micro/plugins/v4/registry/etcd/watcher.go
generated
vendored
91
vendor/github.com/go-micro/plugins/v4/registry/etcd/watcher.go
generated
vendored
@@ -1,91 +0,0 @@
|
||||
package etcd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"go-micro.dev/v4/registry"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type etcdWatcher struct {
|
||||
stop chan bool
|
||||
w clientv3.WatchChan
|
||||
client *clientv3.Client
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func newEtcdWatcher(r *etcdRegistry, timeout time.Duration, opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
var wo registry.WatchOptions
|
||||
for _, o := range opts {
|
||||
o(&wo)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
stop := make(chan bool, 1)
|
||||
|
||||
go func() {
|
||||
<-stop
|
||||
cancel()
|
||||
}()
|
||||
|
||||
watchPath := prefix
|
||||
if len(wo.Service) > 0 {
|
||||
watchPath = servicePath(wo.Service) + "/"
|
||||
}
|
||||
|
||||
return &etcdWatcher{
|
||||
stop: stop,
|
||||
w: r.client.Watch(ctx, watchPath, clientv3.WithPrefix(), clientv3.WithPrevKV()),
|
||||
client: r.client,
|
||||
timeout: timeout,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ew *etcdWatcher) Next() (*registry.Result, error) {
|
||||
for wresp := range ew.w {
|
||||
if wresp.Err() != nil {
|
||||
return nil, wresp.Err()
|
||||
}
|
||||
if wresp.Canceled {
|
||||
return nil, errors.New("could not get next")
|
||||
}
|
||||
for _, ev := range wresp.Events {
|
||||
service := decode(ev.Kv.Value)
|
||||
var action string
|
||||
|
||||
switch ev.Type {
|
||||
case clientv3.EventTypePut:
|
||||
if ev.IsCreate() {
|
||||
action = "create"
|
||||
} else if ev.IsModify() {
|
||||
action = "update"
|
||||
}
|
||||
case clientv3.EventTypeDelete:
|
||||
action = "delete"
|
||||
|
||||
// get service from prevKv
|
||||
service = decode(ev.PrevKv.Value)
|
||||
}
|
||||
|
||||
if service == nil {
|
||||
continue
|
||||
}
|
||||
return ®istry.Result{
|
||||
Action: action,
|
||||
Service: service,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("could not get next")
|
||||
}
|
||||
|
||||
func (ew *etcdWatcher) Stop() {
|
||||
select {
|
||||
case <-ew.stop:
|
||||
return
|
||||
default:
|
||||
close(ew.stop)
|
||||
}
|
||||
}
|
||||
191
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/LICENSE
generated
vendored
191
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015 Asim Aslam.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
66
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/README.md
generated
vendored
66
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/README.md
generated
vendored
@@ -1,66 +0,0 @@
|
||||
# Kubernetes Registry Plugin for micro
|
||||
This is a plugin for go-micro that allows you to use Kubernetes as a registry.
|
||||
|
||||
|
||||
## Overview
|
||||
This registry plugin makes use of Annotations and Labels on a Kubernetes pod
|
||||
to build a service discovery mechanism.
|
||||
|
||||
|
||||
## RBAC
|
||||
If your Kubernetes cluster has RBAC enabled, a role and role binding
|
||||
will need to be created to allow this plugin to `list` and `patch` pods.
|
||||
|
||||
A cluster role can be used to specify the `list` and `patch`
|
||||
requirements, while a role binding per namespace can be used to apply
|
||||
the cluster role. The example RBAC configs below assume your Micro-based
|
||||
services are running in the `test` namespace, and the pods that contain
|
||||
the services are using the `micro-services` service account.
|
||||
|
||||
```
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: micro-registry
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
```
|
||||
|
||||
```
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: micro-registry
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: micro-registry
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: micro-services
|
||||
namespace: test
|
||||
```
|
||||
|
||||
|
||||
## Gotchas
|
||||
* Registering/Deregistering relies on the HOSTNAME Environment Variable, which inside a pod
|
||||
is the place where it can be retrieved from. (This needs improving)
|
||||
|
||||
|
||||
## Connecting to the Kubernetes API
|
||||
### Within a pod
|
||||
If the `--registry_address` flag is omitted, the plugin will securely connect to
|
||||
the Kubernetes API using the pods "Service Account". No extra configuration is necessary.
|
||||
|
||||
Find out more about service accounts here. http://kubernetes.io/docs/user-guide/accessing-the-cluster/
|
||||
|
||||
### Outside of Kubernetes
|
||||
Some functions of the plugin should work, but its not been heavily tested.
|
||||
Currently no TLS support.
|
||||
220
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/api/request.go
generated
vendored
220
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/api/request.go
generated
vendored
@@ -1,220 +0,0 @@
|
||||
// Package api ...
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-micro/plugins/v4/registry/kubernetes/client/watch"
|
||||
)
|
||||
|
||||
// Request is used to construct a http request for the k8s API.
|
||||
type Request struct {
|
||||
client *http.Client
|
||||
header http.Header
|
||||
params url.Values
|
||||
method string
|
||||
host string
|
||||
namespace string
|
||||
|
||||
resource string
|
||||
resourceName *string
|
||||
body io.Reader
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
// Params is the object to pass in to set parameters
|
||||
// on a request.
|
||||
type Params struct {
|
||||
LabelSelector map[string]string
|
||||
Watch bool
|
||||
}
|
||||
|
||||
// Options ...
|
||||
type Options struct {
|
||||
Host string
|
||||
Namespace string
|
||||
BearerToken *string
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
// NewRequest creates a k8s api request.
|
||||
func NewRequest(opts *Options) *Request {
|
||||
req := Request{
|
||||
header: make(http.Header),
|
||||
params: make(url.Values),
|
||||
client: opts.Client,
|
||||
namespace: opts.Namespace,
|
||||
host: opts.Host,
|
||||
}
|
||||
|
||||
if opts.BearerToken != nil {
|
||||
req.SetHeader("Authorization", "Bearer "+*opts.BearerToken)
|
||||
}
|
||||
|
||||
return &req
|
||||
}
|
||||
|
||||
// verb sets method.
|
||||
func (r *Request) verb(method string) *Request {
|
||||
r.method = method
|
||||
return r
|
||||
}
|
||||
|
||||
// Get request.
|
||||
func (r *Request) Get() *Request {
|
||||
return r.verb("GET")
|
||||
}
|
||||
|
||||
// Post request.
|
||||
func (r *Request) Post() *Request {
|
||||
return r.verb("POST")
|
||||
}
|
||||
|
||||
// Put request.
|
||||
func (r *Request) Put() *Request {
|
||||
return r.verb("PUT")
|
||||
}
|
||||
|
||||
// Patch request
|
||||
// https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api-conventions.md#patch-operations
|
||||
func (r *Request) Patch() *Request {
|
||||
return r.verb("PATCH").SetHeader("Content-Type", "application/strategic-merge-patch+json")
|
||||
}
|
||||
|
||||
// Delete request.
|
||||
func (r *Request) Delete() *Request {
|
||||
return r.verb("DELETE")
|
||||
}
|
||||
|
||||
// Namespace is to set the namespace to operate on.
|
||||
func (r *Request) Namespace(s string) *Request {
|
||||
r.namespace = s
|
||||
return r
|
||||
}
|
||||
|
||||
// Resource is the type of resource the operation is
|
||||
// for, such as "services", "endpoints" or "pods".
|
||||
func (r *Request) Resource(s string) *Request {
|
||||
r.resource = s
|
||||
return r
|
||||
}
|
||||
|
||||
// Name is for targeting a specific resource by id.
|
||||
func (r *Request) Name(s string) *Request {
|
||||
r.resourceName = &s
|
||||
return r
|
||||
}
|
||||
|
||||
// Body pass in a body to set, this is for POST, PUT
|
||||
// and PATCH requests.
|
||||
func (r *Request) Body(in interface{}) *Request {
|
||||
b := new(bytes.Buffer)
|
||||
if err := json.NewEncoder(b).Encode(&in); err != nil {
|
||||
r.err = err
|
||||
return r
|
||||
}
|
||||
|
||||
r.body = b
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// Params isused to set parameters on a request.
|
||||
func (r *Request) Params(p *Params) *Request {
|
||||
for k, v := range p.LabelSelector {
|
||||
// create new key=value pair
|
||||
value := fmt.Sprintf("%s=%s", k, v)
|
||||
// check if there's an existing value
|
||||
if label := r.params.Get("labelSelector"); len(label) > 0 {
|
||||
value = fmt.Sprintf("%s,%s", label, value)
|
||||
}
|
||||
// set and overwrite the value
|
||||
r.params.Set("labelSelector", value)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// SetHeader sets a header on a request with
|
||||
// a `key` and `value`.
|
||||
func (r *Request) SetHeader(key, value string) *Request {
|
||||
r.header.Add(key, value)
|
||||
return r
|
||||
}
|
||||
|
||||
// request builds the http.Request from the options.
|
||||
func (r *Request) request() (*http.Request, error) {
|
||||
url := fmt.Sprintf("%s/api/v1/namespaces/%s/%s/", r.host, r.namespace, r.resource)
|
||||
|
||||
// append resourceName if it is present
|
||||
if r.resourceName != nil {
|
||||
url += *r.resourceName
|
||||
}
|
||||
|
||||
// append any query params
|
||||
if len(r.params) > 0 {
|
||||
url += "?" + r.params.Encode()
|
||||
}
|
||||
|
||||
// build request
|
||||
req, err := http.NewRequest(r.method, url, r.body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// set headers on request
|
||||
req.Header = r.header
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Do builds and triggers the request.
|
||||
func (r *Request) Do() *Response {
|
||||
if r.err != nil {
|
||||
return &Response{
|
||||
err: r.err,
|
||||
}
|
||||
}
|
||||
|
||||
req, err := r.request()
|
||||
if err != nil {
|
||||
return &Response{
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
res, err := r.client.Do(req)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
// return res, err
|
||||
return newResponse(res, err)
|
||||
}
|
||||
|
||||
// Watch builds and triggers the request, but will watch instead of return
|
||||
// an object.
|
||||
func (r *Request) Watch() (watch.Watch, error) {
|
||||
if r.err != nil {
|
||||
return nil, r.err
|
||||
}
|
||||
|
||||
r.params.Set("watch", "true")
|
||||
|
||||
req, err := r.request()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
w, err := watch.NewBodyWatcher(req, r.client)
|
||||
|
||||
return w, err
|
||||
}
|
||||
90
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/api/response.go
generated
vendored
90
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/api/response.go
generated
vendored
@@ -1,90 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
log "go-micro.dev/v4/logger"
|
||||
)
|
||||
|
||||
// Errors ...
|
||||
var (
|
||||
ErrNoPodName = errors.New("no pod name provided")
|
||||
ErrNotFound = errors.New("pod not found")
|
||||
ErrDecode = errors.New("error decoding")
|
||||
ErrOther = errors.New("unspecified error occurred in k8s registry")
|
||||
)
|
||||
|
||||
// Response ...
|
||||
type Response struct {
|
||||
res *http.Response
|
||||
err error
|
||||
}
|
||||
|
||||
// Error returns an error.
|
||||
func (r *Response) Error() error {
|
||||
return r.err
|
||||
}
|
||||
|
||||
// StatusCode returns status code for response.
|
||||
func (r *Response) StatusCode() int {
|
||||
return r.res.StatusCode
|
||||
}
|
||||
|
||||
// Decode decodes body into `data`.
|
||||
func (r *Response) Decode(data interface{}) error {
|
||||
if r.err != nil {
|
||||
return r.err
|
||||
}
|
||||
|
||||
var err error
|
||||
defer func() {
|
||||
nerr := r.res.Body.Close()
|
||||
if err != nil {
|
||||
err = nerr
|
||||
}
|
||||
}()
|
||||
|
||||
decoder := json.NewDecoder(r.res.Body)
|
||||
|
||||
if err := decoder.Decode(&data); err != nil {
|
||||
return errors.Wrap(ErrDecode, err.Error())
|
||||
}
|
||||
|
||||
return r.err
|
||||
}
|
||||
|
||||
func newResponse(r *http.Response, err error) *Response {
|
||||
resp := &Response{
|
||||
res: r,
|
||||
err: err,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return resp
|
||||
}
|
||||
|
||||
// Check if request is successful.
|
||||
s := resp.res.StatusCode
|
||||
if s == http.StatusOK || s == http.StatusCreated || s == http.StatusNoContent {
|
||||
return resp
|
||||
}
|
||||
|
||||
if resp.res.StatusCode == http.StatusNotFound {
|
||||
resp.err = ErrNotFound
|
||||
return resp
|
||||
}
|
||||
|
||||
log.Errorf("K8s: request failed with code %v", resp.res.StatusCode)
|
||||
|
||||
b, err := io.ReadAll(resp.res.Body)
|
||||
if err == nil {
|
||||
log.Errorf("K8s: request failed with body: %s", string(b))
|
||||
}
|
||||
|
||||
resp.err = ErrOther
|
||||
|
||||
return resp
|
||||
}
|
||||
142
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/client.go
generated
vendored
142
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/client.go
generated
vendored
@@ -1,142 +0,0 @@
|
||||
// Package client is the kubernetes registry client.
|
||||
package client
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"go-micro.dev/v4/logger"
|
||||
|
||||
"github.com/go-micro/plugins/v4/registry/kubernetes/client/api"
|
||||
"github.com/go-micro/plugins/v4/registry/kubernetes/client/watch"
|
||||
)
|
||||
|
||||
var (
|
||||
serviceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount"
|
||||
|
||||
// ErrReadNamespace error when failed to read namespace.
|
||||
ErrReadNamespace = errors.New("could not read namespace from service account secret")
|
||||
)
|
||||
|
||||
// Client ...
|
||||
type client struct {
|
||||
opts *api.Options
|
||||
}
|
||||
|
||||
// NewClientByHost sets up a client by host.
|
||||
func NewClientByHost(host string) Kubernetes {
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
//nolint:gosec
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
DisableCompression: true,
|
||||
}
|
||||
|
||||
c := &http.Client{
|
||||
Transport: tr,
|
||||
}
|
||||
|
||||
return &client{
|
||||
opts: &api.Options{
|
||||
Client: c,
|
||||
Host: host,
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewClientInCluster should work similarly to the official api
|
||||
// NewInClient by setting up a client configuration for use within
|
||||
// a k8s pod.
|
||||
func NewClientInCluster() Kubernetes {
|
||||
host := "https://" + os.Getenv("KUBERNETES_SERVICE_HOST") + ":" + os.Getenv("KUBERNETES_SERVICE_PORT")
|
||||
|
||||
s, err := os.Stat(serviceAccountPath)
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
|
||||
if s == nil || !s.IsDir() {
|
||||
logger.Fatal(errors.New("no k8s service account found"))
|
||||
}
|
||||
|
||||
t, err := os.ReadFile(path.Join(serviceAccountPath, "token"))
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
|
||||
token := string(t)
|
||||
|
||||
ns, err := detectNamespace()
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
|
||||
crt, err := CertPoolFromFile(path.Join(serviceAccountPath, "ca.crt"))
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
|
||||
c := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: crt,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
},
|
||||
DisableCompression: true,
|
||||
},
|
||||
}
|
||||
|
||||
return &client{
|
||||
opts: &api.Options{
|
||||
Client: c,
|
||||
Host: host,
|
||||
Namespace: ns,
|
||||
BearerToken: &token,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ListPods ...
|
||||
func (c *client) ListPods(labels map[string]string) (*PodList, error) {
|
||||
var pods PodList
|
||||
err := api.NewRequest(c.opts).Get().Resource("pods").Params(&api.Params{LabelSelector: labels}).Do().Decode(&pods)
|
||||
|
||||
return &pods, err
|
||||
}
|
||||
|
||||
// UpdatePod ...
|
||||
func (c *client) UpdatePod(name string, p *Pod) (*Pod, error) {
|
||||
var pod Pod
|
||||
err := api.NewRequest(c.opts).Patch().Resource("pods").Name(name).Body(p).Do().Decode(&pod)
|
||||
|
||||
return &pod, err
|
||||
}
|
||||
|
||||
// WatchPods ...
|
||||
func (c *client) WatchPods(labels map[string]string) (watch.Watch, error) {
|
||||
return api.NewRequest(c.opts).Get().Resource("pods").Params(&api.Params{LabelSelector: labels}).Watch()
|
||||
}
|
||||
|
||||
func detectNamespace() (string, error) {
|
||||
nsPath := path.Join(serviceAccountPath, "namespace")
|
||||
|
||||
// Make sure it's a file and we can read it
|
||||
if s, err := os.Stat(nsPath); err != nil {
|
||||
return "", err
|
||||
} else if s.IsDir() {
|
||||
return "", ErrReadNamespace
|
||||
}
|
||||
|
||||
// Read the file, and cast to a string
|
||||
ns, err := os.ReadFile(path.Clean(nsPath))
|
||||
if err != nil {
|
||||
return string(ns), err
|
||||
}
|
||||
|
||||
return string(ns), nil
|
||||
}
|
||||
35
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/kubernetes.go
generated
vendored
35
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/kubernetes.go
generated
vendored
@@ -1,35 +0,0 @@
|
||||
package client
|
||||
|
||||
import "github.com/go-micro/plugins/v4/registry/kubernetes/client/watch"
|
||||
|
||||
// Kubernetes ...
|
||||
type Kubernetes interface {
|
||||
ListPods(labels map[string]string) (*PodList, error)
|
||||
UpdatePod(podName string, pod *Pod) (*Pod, error)
|
||||
WatchPods(labels map[string]string) (watch.Watch, error)
|
||||
}
|
||||
|
||||
// PodList ...
|
||||
type PodList struct {
|
||||
Items []Pod `json:"items"`
|
||||
}
|
||||
|
||||
// Pod is the top level item for a pod.
|
||||
type Pod struct {
|
||||
Metadata *Meta `json:"metadata"`
|
||||
Status *Status `json:"status"`
|
||||
}
|
||||
|
||||
// Meta ...
|
||||
type Meta struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Labels map[string]*string `json:"labels,omitempty"`
|
||||
Annotations map[string]*string `json:"annotations,omitempty"`
|
||||
DeletionTimestamp string `json:"deletionTimestamp,omitempty"`
|
||||
}
|
||||
|
||||
// Status ...
|
||||
type Status struct {
|
||||
PodIP string `json:"podIP"`
|
||||
Phase string `json:"phase"`
|
||||
}
|
||||
87
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/utils.go
generated
vendored
87
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/utils.go
generated
vendored
@@ -1,87 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// COPIED FROM
|
||||
// https://github.com/kubernetes/kubernetes/blob/7a725418af4661067b56506faabc2d44c6d7703a/pkg/util/crypto/crypto.go
|
||||
|
||||
// CertPoolFromFile returns an x509.CertPool containing the certificates in
|
||||
// the given PEM-encoded file. Returns an error if the file could not be read,
|
||||
// a certificate could not be parsed, or if the file does not contain any certificates.
|
||||
func CertPoolFromFile(filename string) (*x509.CertPool, error) {
|
||||
certs, err := certificatesFromFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pool := x509.NewCertPool()
|
||||
for _, cert := range certs {
|
||||
pool.AddCert(cert)
|
||||
}
|
||||
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
// certificatesFromFile returns the x509.Certificates contained in the given
|
||||
// PEM-encoded file. Returns an error if the file could not be read, a
|
||||
// certificate could not be parsed, or if the file does not contain any certificates.
|
||||
func certificatesFromFile(file string) ([]*x509.Certificate, error) {
|
||||
if len(file) == 0 {
|
||||
return nil, errors.New("error reading certificates from an empty filename")
|
||||
}
|
||||
|
||||
pemBlock, err := os.ReadFile(filepath.Clean(file))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certs, err := CertsFromPEM(pemBlock)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", file)
|
||||
}
|
||||
|
||||
return certs, nil
|
||||
}
|
||||
|
||||
// CertsFromPEM returns the x509.Certificates contained in the given PEM-encoded
|
||||
// byte array. Returns an error if a certificate could not be parsed, or if the
|
||||
// data does not contain any certificates.
|
||||
func CertsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
|
||||
ok := false
|
||||
certs := []*x509.Certificate{}
|
||||
|
||||
for len(pemCerts) > 0 {
|
||||
var block *pem.Block
|
||||
block, pemCerts = pem.Decode(pemCerts)
|
||||
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// Only use PEM "CERTIFICATE" blocks without extra headers
|
||||
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return certs, err
|
||||
}
|
||||
|
||||
certs = append(certs, cert)
|
||||
ok = true
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return certs, errors.New("could not read any certificates")
|
||||
}
|
||||
|
||||
return certs, nil
|
||||
}
|
||||
109
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/watch/body.go
generated
vendored
109
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/watch/body.go
generated
vendored
@@ -1,109 +0,0 @@
|
||||
package watch
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// bodyWatcher scans the body of a request for chunks.
|
||||
type bodyWatcher struct {
|
||||
ctx context.Context
|
||||
stop context.CancelFunc
|
||||
results chan Event
|
||||
res *http.Response
|
||||
req *http.Request
|
||||
}
|
||||
|
||||
// Changes returns the results channel.
|
||||
func (wr *bodyWatcher) ResultChan() <-chan Event {
|
||||
return wr.results
|
||||
}
|
||||
|
||||
// Stop cancels the request.
|
||||
func (wr *bodyWatcher) Stop() {
|
||||
select {
|
||||
case <-wr.ctx.Done():
|
||||
return
|
||||
default:
|
||||
wr.stop()
|
||||
}
|
||||
}
|
||||
|
||||
func (wr *bodyWatcher) stream() {
|
||||
reader := bufio.NewReader(wr.res.Body)
|
||||
|
||||
// ignore first few messages from stream,
|
||||
// as they are usually old.
|
||||
var ignore atomic.Bool
|
||||
|
||||
go func() {
|
||||
<-time.After(time.Second)
|
||||
ignore.Store(false)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
//nolint:errcheck
|
||||
defer wr.res.Body.Close()
|
||||
out:
|
||||
for {
|
||||
// Read a line
|
||||
b, err := reader.ReadBytes('\n')
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
// Ignore for the first second
|
||||
if ignore.Load() {
|
||||
continue
|
||||
}
|
||||
|
||||
// Send the event
|
||||
var event Event
|
||||
if err := json.Unmarshal(b, &event); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
select {
|
||||
case <-wr.ctx.Done():
|
||||
break out
|
||||
case wr.results <- event:
|
||||
}
|
||||
}
|
||||
|
||||
close(wr.results)
|
||||
// stop the watcher
|
||||
wr.Stop()
|
||||
}()
|
||||
}
|
||||
|
||||
// NewBodyWatcher creates a k8s body watcher for a given http request.
|
||||
func NewBodyWatcher(req *http.Request, client *http.Client) (Watch, error) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
//nolint:bodyclose
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, errors.Wrap(err, "body watcher failed to make http request")
|
||||
}
|
||||
|
||||
wr := &bodyWatcher{
|
||||
ctx: ctx,
|
||||
results: make(chan Event),
|
||||
stop: cancel,
|
||||
req: req,
|
||||
res: res,
|
||||
}
|
||||
|
||||
go wr.stream()
|
||||
|
||||
return wr, nil
|
||||
}
|
||||
27
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/watch/watch.go
generated
vendored
27
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/client/watch/watch.go
generated
vendored
@@ -1,27 +0,0 @@
|
||||
// Package watch implements the k8s watcher.
|
||||
package watch
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Watch ...
|
||||
type Watch interface {
|
||||
Stop()
|
||||
ResultChan() <-chan Event
|
||||
}
|
||||
|
||||
// EventType defines the possible types of events.
|
||||
type EventType string
|
||||
|
||||
// EventTypes used.
|
||||
const (
|
||||
Added EventType = "ADDED"
|
||||
Modified EventType = "MODIFIED"
|
||||
Deleted EventType = "DELETED"
|
||||
Error EventType = "ERROR"
|
||||
)
|
||||
|
||||
// Event represents a single event to a watched resource.
|
||||
type Event struct {
|
||||
Type EventType `json:"type"`
|
||||
Object json.RawMessage `json:"object"`
|
||||
}
|
||||
321
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/kubernetes.go
generated
vendored
321
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/kubernetes.go
generated
vendored
@@ -1,321 +0,0 @@
|
||||
// Package kubernetes provides a kubernetes registry
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/util/cmd"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-micro/plugins/v4/registry/kubernetes/client"
|
||||
)
|
||||
|
||||
type kregistry struct {
|
||||
client client.Kubernetes
|
||||
timeout time.Duration
|
||||
options registry.Options
|
||||
}
|
||||
|
||||
var (
|
||||
// used on pods as labels & services to select
|
||||
// eg: svcSelectorPrefix+"svc.name"
|
||||
svcSelectorPrefix = "micro.mu/selector-"
|
||||
svcSelectorValue = "service"
|
||||
|
||||
labelTypeKey = "micro.mu/type"
|
||||
labelTypeValueService = "service"
|
||||
|
||||
// used on k8s services to scope a serialized
|
||||
// micro service by pod name.
|
||||
annotationServiceKeyPrefix = "micro.mu/service-"
|
||||
|
||||
// Pod status.
|
||||
podRunning = "Running"
|
||||
|
||||
// label name regex.
|
||||
labelRe = regexp.MustCompilePOSIX("[-A-Za-z0-9_.]")
|
||||
)
|
||||
|
||||
// Err are all package errors.
|
||||
var (
|
||||
ErrNoHostname = errors.New("failed to get podname from HOSTNAME variable")
|
||||
ErrNoNodesFound = errors.New("you must provide at least one node")
|
||||
)
|
||||
|
||||
// podSelector.
|
||||
var podSelector = map[string]string{
|
||||
labelTypeKey: labelTypeValueService,
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmd.DefaultRegistries["kubernetes"] = NewRegistry
|
||||
}
|
||||
|
||||
func configure(k *kregistry, opts ...registry.Option) error {
|
||||
for _, o := range opts {
|
||||
o(&k.options)
|
||||
}
|
||||
|
||||
// get first host
|
||||
var host string
|
||||
if len(k.options.Addrs) > 0 && len(k.options.Addrs[0]) > 0 {
|
||||
host = k.options.Addrs[0]
|
||||
}
|
||||
|
||||
if k.options.Timeout == 0 {
|
||||
k.options.Timeout = time.Second * 1
|
||||
}
|
||||
|
||||
// if no hosts setup, assume InCluster
|
||||
var c client.Kubernetes
|
||||
if len(host) == 0 {
|
||||
c = client.NewClientInCluster()
|
||||
} else {
|
||||
c = client.NewClientByHost(host)
|
||||
}
|
||||
|
||||
k.client = c
|
||||
k.timeout = k.options.Timeout
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// serviceName generates a valid service name for k8s labels.
|
||||
func serviceName(name string) string {
|
||||
aname := make([]byte, len(name))
|
||||
|
||||
for i, r := range []byte(name) {
|
||||
if !labelRe.Match([]byte{r}) {
|
||||
aname[i] = '_'
|
||||
continue
|
||||
}
|
||||
|
||||
aname[i] = r
|
||||
}
|
||||
|
||||
return string(aname)
|
||||
}
|
||||
|
||||
// Init allows reconfig of options.
|
||||
func (c *kregistry) Init(opts ...registry.Option) error {
|
||||
return configure(c, opts...)
|
||||
}
|
||||
|
||||
// Options returns the registry Options.
|
||||
func (c *kregistry) Options() registry.Options {
|
||||
return c.options
|
||||
}
|
||||
|
||||
// Register sets a service selector label and an annotation with a
|
||||
// serialized version of the service passed in.
|
||||
func (c *kregistry) Register(s *registry.Service, opts ...registry.RegisterOption) error {
|
||||
if len(s.Nodes) == 0 {
|
||||
return ErrNoNodesFound
|
||||
}
|
||||
|
||||
svcName := s.Name
|
||||
|
||||
// TODO: grab podname from somewhere better than this.
|
||||
podName, err := getPodName()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to register")
|
||||
}
|
||||
|
||||
// encode micro service
|
||||
b, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svc := string(b)
|
||||
|
||||
pod := &client.Pod{
|
||||
Metadata: &client.Meta{
|
||||
Labels: map[string]*string{
|
||||
labelTypeKey: &labelTypeValueService,
|
||||
svcSelectorPrefix + serviceName(svcName): &svcSelectorValue,
|
||||
},
|
||||
Annotations: map[string]*string{
|
||||
annotationServiceKeyPrefix + serviceName(svcName): &svc,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := c.client.UpdatePod(podName, pod); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deregister nils out any things set in Register.
|
||||
func (c *kregistry) Deregister(s *registry.Service, opts ...registry.DeregisterOption) error {
|
||||
if len(s.Nodes) == 0 {
|
||||
return ErrNoNodesFound
|
||||
}
|
||||
|
||||
svcName := s.Name
|
||||
|
||||
// TODO: grab podname from somewhere better than env var.
|
||||
podName, err := getPodName()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to deregister")
|
||||
}
|
||||
|
||||
pod := &client.Pod{
|
||||
Metadata: &client.Meta{
|
||||
Labels: map[string]*string{
|
||||
svcSelectorPrefix + serviceName(svcName): nil,
|
||||
},
|
||||
Annotations: map[string]*string{
|
||||
annotationServiceKeyPrefix + serviceName(svcName): nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := c.client.UpdatePod(podName, pod); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetService will get all the pods with the given service selector,
|
||||
// and build services from the annotations.
|
||||
func (c *kregistry) GetService(name string, opts ...registry.GetOption) ([]*registry.Service, error) {
|
||||
pods, err := c.client.ListPods(map[string]string{
|
||||
svcSelectorPrefix + serviceName(name): svcSelectorValue,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(pods.Items) == 0 {
|
||||
return nil, registry.ErrNotFound
|
||||
}
|
||||
|
||||
// svcs mapped by version
|
||||
svcs := make(map[string]*registry.Service)
|
||||
|
||||
// loop through items
|
||||
for _, pod := range pods.Items {
|
||||
if pod.Status.Phase != podRunning || pod.Metadata.DeletionTimestamp != "" {
|
||||
continue
|
||||
}
|
||||
// get serialized service from annotation
|
||||
svcStr, ok := pod.Metadata.Annotations[annotationServiceKeyPrefix+serviceName(name)]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
var svc registry.Service
|
||||
|
||||
// unmarshal service string
|
||||
err := json.Unmarshal([]byte(*svcStr), &svc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not unmarshal service '%s' from pod annotation", name)
|
||||
}
|
||||
|
||||
// merge up pod service & ip with versioned service.
|
||||
vs, ok := svcs[svc.Version]
|
||||
if !ok {
|
||||
svcs[svc.Version] = &svc
|
||||
continue
|
||||
}
|
||||
|
||||
vs.Nodes = append(vs.Nodes, svc.Nodes...)
|
||||
}
|
||||
|
||||
list := make([]*registry.Service, 0, len(svcs))
|
||||
for _, val := range svcs {
|
||||
list = append(list, val)
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// ListServices will list all the service names.
|
||||
func (c *kregistry) ListServices(opts ...registry.ListOption) ([]*registry.Service, error) {
|
||||
pods, err := c.client.ListPods(podSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// svcs mapped by name+version
|
||||
svcs := make(map[string]*registry.Service)
|
||||
|
||||
for _, pod := range pods.Items {
|
||||
if pod.Status.Phase != podRunning || pod.Metadata.DeletionTimestamp != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
for k, v := range pod.Metadata.Annotations {
|
||||
if !strings.HasPrefix(k, annotationServiceKeyPrefix) {
|
||||
continue
|
||||
}
|
||||
|
||||
// we have to unmarshal the annotation itself since the
|
||||
// key is encoded to match the regex restriction.
|
||||
var svc registry.Service
|
||||
if err := json.Unmarshal([]byte(*v), &svc); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
s, ok := svcs[svc.Name+svc.Version]
|
||||
if !ok {
|
||||
svcs[svc.Name+svc.Version] = &svc
|
||||
continue
|
||||
}
|
||||
|
||||
// append to service:version nodes
|
||||
s.Nodes = append(s.Nodes, svc.Nodes...)
|
||||
}
|
||||
}
|
||||
|
||||
i := 0
|
||||
list := make([]*registry.Service, len(svcs))
|
||||
|
||||
for _, s := range svcs {
|
||||
list[i] = s
|
||||
i++
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// Watch returns a kubernetes watcher.
|
||||
func (c *kregistry) Watch(opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
return newWatcher(c, opts...)
|
||||
}
|
||||
|
||||
func (c *kregistry) String() string {
|
||||
return "kubernetes"
|
||||
}
|
||||
|
||||
// NewRegistry creates a kubernetes registry.
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
k := &kregistry{
|
||||
options: registry.Options{},
|
||||
}
|
||||
|
||||
//nolint:errcheck,gosec
|
||||
configure(k, opts...)
|
||||
|
||||
return k
|
||||
}
|
||||
|
||||
func getPodName() (string, error) {
|
||||
podName := os.Getenv("HOSTNAME")
|
||||
if len(podName) == 0 {
|
||||
return "", ErrNoHostname
|
||||
}
|
||||
|
||||
return podName, nil
|
||||
}
|
||||
267
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/watcher.go
generated
vendored
267
vendor/github.com/go-micro/plugins/v4/registry/kubernetes/watcher.go
generated
vendored
@@ -1,267 +0,0 @@
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"go-micro.dev/v4/logger"
|
||||
"go-micro.dev/v4/registry"
|
||||
|
||||
"github.com/go-micro/plugins/v4/registry/kubernetes/client"
|
||||
"github.com/go-micro/plugins/v4/registry/kubernetes/client/watch"
|
||||
)
|
||||
|
||||
var (
|
||||
deleteAction = "delete"
|
||||
)
|
||||
|
||||
type k8sWatcher struct {
|
||||
registry *kregistry
|
||||
watcher watch.Watch
|
||||
next chan *registry.Result
|
||||
|
||||
sync.RWMutex
|
||||
pods map[string]*client.Pod
|
||||
sync.Once
|
||||
}
|
||||
|
||||
// build a cache of pods when the watcher starts.
|
||||
func (k *k8sWatcher) updateCache() ([]*registry.Result, error) {
|
||||
podList, err := k.registry.client.ListPods(podSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var results []*registry.Result
|
||||
|
||||
for _, p := range podList.Items {
|
||||
// Copy to new var as p gets overwritten by the loop
|
||||
pod := p
|
||||
rslts := k.buildPodResults(&pod, nil)
|
||||
results = append(results, rslts...)
|
||||
|
||||
k.Lock()
|
||||
k.pods[pod.Metadata.Name] = &pod
|
||||
k.Unlock()
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// look through pod annotations, compare against cache if present
|
||||
// and return a list of results to send down the wire.
|
||||
func (k *k8sWatcher) buildPodResults(pod *client.Pod, cache *client.Pod) []*registry.Result {
|
||||
var results []*registry.Result
|
||||
|
||||
ignore := make(map[string]bool)
|
||||
|
||||
if pod.Metadata != nil {
|
||||
results, ignore = podBuildResult(pod, cache)
|
||||
}
|
||||
|
||||
// loop through cache annotations to find services
|
||||
// not accounted for above, and "delete" them.
|
||||
if cache != nil && cache.Metadata != nil {
|
||||
for annKey, annVal := range cache.Metadata.Annotations {
|
||||
if ignore[annKey] {
|
||||
continue
|
||||
}
|
||||
|
||||
// check this annotation kv is a service notation
|
||||
if !strings.HasPrefix(annKey, annotationServiceKeyPrefix) {
|
||||
continue
|
||||
}
|
||||
|
||||
rslt := ®istry.Result{Action: deleteAction}
|
||||
|
||||
// unmarshal service notation from annotation value
|
||||
if err := json.Unmarshal([]byte(*annVal), &rslt.Service); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, rslt)
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
// handleEvent will taken an event from the k8s pods API and do the correct
|
||||
// things with the result, based on the local cache.
|
||||
func (k *k8sWatcher) handleEvent(event watch.Event) {
|
||||
var pod client.Pod
|
||||
if err := json.Unmarshal([]byte(event.Object), &pod); err != nil {
|
||||
logger.Error("K8s Watcher: Couldnt unmarshal event object from pod")
|
||||
return
|
||||
}
|
||||
|
||||
//nolint:exhaustive
|
||||
switch event.Type {
|
||||
// Pod was modified
|
||||
case watch.Modified:
|
||||
k.RLock()
|
||||
cache := k.pods[pod.Metadata.Name]
|
||||
k.RUnlock()
|
||||
|
||||
// service could have been added, edited or removed.
|
||||
var results []*registry.Result
|
||||
|
||||
if pod.Status.Phase == podRunning {
|
||||
results = k.buildPodResults(&pod, cache)
|
||||
} else {
|
||||
// passing in cache might not return all results
|
||||
results = k.buildPodResults(&pod, nil)
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
// pod isnt running
|
||||
if pod.Status.Phase != podRunning || pod.Metadata.DeletionTimestamp != "" {
|
||||
result.Action = deleteAction
|
||||
}
|
||||
k.next <- result
|
||||
}
|
||||
|
||||
k.Lock()
|
||||
k.pods[pod.Metadata.Name] = &pod
|
||||
k.Unlock()
|
||||
|
||||
return
|
||||
|
||||
// Pod was deleted
|
||||
// passing in cache might not return all results
|
||||
case watch.Deleted:
|
||||
results := k.buildPodResults(&pod, nil)
|
||||
|
||||
for _, result := range results {
|
||||
result.Action = deleteAction
|
||||
k.next <- result
|
||||
}
|
||||
|
||||
k.Lock()
|
||||
delete(k.pods, pod.Metadata.Name)
|
||||
k.Unlock()
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Next will block until a new result comes in.
|
||||
func (k *k8sWatcher) Next() (*registry.Result, error) {
|
||||
r, ok := <-k.next
|
||||
if !ok {
|
||||
return nil, errors.New("result chan closed")
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Stop will cancel any requests, and close channels.
|
||||
func (k *k8sWatcher) Stop() {
|
||||
k.watcher.Stop()
|
||||
|
||||
select {
|
||||
case <-k.next:
|
||||
return
|
||||
default:
|
||||
k.Do(func() {
|
||||
close(k.next)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newWatcher(kr *kregistry, opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
var wo registry.WatchOptions
|
||||
for _, o := range opts {
|
||||
o(&wo)
|
||||
}
|
||||
|
||||
selector := podSelector
|
||||
if len(wo.Service) > 0 {
|
||||
selector = map[string]string{
|
||||
svcSelectorPrefix + serviceName(wo.Service): svcSelectorValue,
|
||||
}
|
||||
}
|
||||
|
||||
// Create watch request
|
||||
watcher, err := kr.client.WatchPods(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &k8sWatcher{
|
||||
registry: kr,
|
||||
watcher: watcher,
|
||||
next: make(chan *registry.Result),
|
||||
pods: make(map[string]*client.Pod),
|
||||
}
|
||||
|
||||
// update cache, but dont emit changes
|
||||
if _, err := k.updateCache(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// range over watch request changes, and invoke
|
||||
// the update event
|
||||
go func() {
|
||||
for event := range watcher.ResultChan() {
|
||||
k.handleEvent(event)
|
||||
}
|
||||
|
||||
k.Stop()
|
||||
}()
|
||||
|
||||
return k, nil
|
||||
}
|
||||
|
||||
func podBuildResult(pod *client.Pod, cache *client.Pod) ([]*registry.Result, map[string]bool) {
|
||||
results := make([]*registry.Result, 0, len(pod.Metadata.Annotations))
|
||||
ignore := make(map[string]bool)
|
||||
|
||||
for annKey, annVal := range pod.Metadata.Annotations {
|
||||
// check this annotation kv is a service notation
|
||||
if !strings.HasPrefix(annKey, annotationServiceKeyPrefix) {
|
||||
continue
|
||||
}
|
||||
|
||||
if annVal == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// ignore when we check the cached annotations
|
||||
// as we take care of it here
|
||||
ignore[annKey] = true
|
||||
|
||||
// compare against cache.
|
||||
var (
|
||||
cacheExists bool
|
||||
cav *string
|
||||
)
|
||||
|
||||
if cache != nil && cache.Metadata != nil {
|
||||
cav, cacheExists = cache.Metadata.Annotations[annKey]
|
||||
if cacheExists && cav != nil && cav == annVal {
|
||||
// service notation exists and is identical -
|
||||
// no change result required.
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
rslt := ®istry.Result{}
|
||||
if cacheExists {
|
||||
rslt.Action = "update"
|
||||
} else {
|
||||
rslt.Action = "create"
|
||||
}
|
||||
|
||||
// unmarshal service notation from annotation value
|
||||
if err := json.Unmarshal([]byte(*annVal), &rslt.Service); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, rslt)
|
||||
}
|
||||
|
||||
return results, ignore
|
||||
}
|
||||
191
vendor/github.com/go-micro/plugins/v4/registry/mdns/LICENSE
generated
vendored
191
vendor/github.com/go-micro/plugins/v4/registry/mdns/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015 Asim Aslam.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
16
vendor/github.com/go-micro/plugins/v4/registry/mdns/mdns.go
generated
vendored
16
vendor/github.com/go-micro/plugins/v4/registry/mdns/mdns.go
generated
vendored
@@ -1,16 +0,0 @@
|
||||
// Package mdns provides a multicast dns registry
|
||||
package mdns
|
||||
|
||||
import (
|
||||
"go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/util/cmd"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd.DefaultRegistries["mdns"] = NewRegistry
|
||||
}
|
||||
|
||||
// NewRegistry returns a new mdns registry.
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
return registry.NewRegistry(opts...)
|
||||
}
|
||||
191
vendor/github.com/go-micro/plugins/v4/registry/nats/LICENSE
generated
vendored
191
vendor/github.com/go-micro/plugins/v4/registry/nats/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015 Asim Aslam.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
422
vendor/github.com/go-micro/plugins/v4/registry/nats/nats.go
generated
vendored
422
vendor/github.com/go-micro/plugins/v4/registry/nats/nats.go
generated
vendored
@@ -1,422 +0,0 @@
|
||||
// Package nats provides a NATS registry using broadcast queries
|
||||
package nats
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/util/cmd"
|
||||
)
|
||||
|
||||
type natsRegistry struct {
|
||||
addrs []string
|
||||
opts registry.Options
|
||||
nopts nats.Options
|
||||
queryTopic string
|
||||
watchTopic string
|
||||
registerAction string
|
||||
|
||||
sync.RWMutex
|
||||
conn *nats.Conn
|
||||
services map[string][]*registry.Service
|
||||
listeners map[string]chan bool
|
||||
}
|
||||
|
||||
var (
|
||||
defaultQueryTopic = "micro.registry.nats.query"
|
||||
defaultWatchTopic = "micro.registry.nats.watch"
|
||||
defaultRegisterAction = "create"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd.DefaultRegistries["nats"] = NewRegistry
|
||||
}
|
||||
|
||||
func configure(n *natsRegistry, opts ...registry.Option) error {
|
||||
for _, o := range opts {
|
||||
o(&n.opts)
|
||||
}
|
||||
|
||||
natsOptions := nats.GetDefaultOptions()
|
||||
if n, ok := n.opts.Context.Value(optionsKey{}).(nats.Options); ok {
|
||||
natsOptions = n
|
||||
}
|
||||
|
||||
queryTopic := defaultQueryTopic
|
||||
if qt, ok := n.opts.Context.Value(queryTopicKey{}).(string); ok {
|
||||
queryTopic = qt
|
||||
}
|
||||
|
||||
watchTopic := defaultWatchTopic
|
||||
if wt, ok := n.opts.Context.Value(watchTopicKey{}).(string); ok {
|
||||
watchTopic = wt
|
||||
}
|
||||
|
||||
registerAction := defaultRegisterAction
|
||||
if ra, ok := n.opts.Context.Value(registerActionKey{}).(string); ok {
|
||||
registerAction = ra
|
||||
}
|
||||
|
||||
// registry.Options have higher priority than nats.Options
|
||||
// only if Addrs, Secure or TLSConfig were not set through a registry.Option
|
||||
// we read them from nats.Option
|
||||
if len(n.opts.Addrs) == 0 {
|
||||
n.opts.Addrs = natsOptions.Servers
|
||||
}
|
||||
|
||||
if !n.opts.Secure {
|
||||
n.opts.Secure = natsOptions.Secure
|
||||
}
|
||||
|
||||
if n.opts.TLSConfig == nil {
|
||||
n.opts.TLSConfig = natsOptions.TLSConfig
|
||||
}
|
||||
|
||||
// check & add nats:// prefix (this makes also sure that the addresses
|
||||
// stored in natsRegistry.addrs and n.opts.Addrs are identical)
|
||||
n.opts.Addrs = setAddrs(n.opts.Addrs)
|
||||
|
||||
n.addrs = n.opts.Addrs
|
||||
n.nopts = natsOptions
|
||||
n.queryTopic = queryTopic
|
||||
n.watchTopic = watchTopic
|
||||
n.registerAction = registerAction
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setAddrs(addrs []string) []string {
|
||||
var cAddrs []string
|
||||
for _, addr := range addrs {
|
||||
if len(addr) == 0 {
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(addr, "nats://") {
|
||||
addr = "nats://" + addr
|
||||
}
|
||||
cAddrs = append(cAddrs, addr)
|
||||
}
|
||||
if len(cAddrs) == 0 {
|
||||
cAddrs = []string{nats.DefaultURL}
|
||||
}
|
||||
return cAddrs
|
||||
}
|
||||
|
||||
func (n *natsRegistry) newConn() (*nats.Conn, error) {
|
||||
opts := n.nopts
|
||||
opts.Servers = n.addrs
|
||||
opts.Secure = n.opts.Secure
|
||||
opts.TLSConfig = n.opts.TLSConfig
|
||||
|
||||
// secure might not be set
|
||||
if opts.TLSConfig != nil {
|
||||
opts.Secure = true
|
||||
}
|
||||
|
||||
return opts.Connect()
|
||||
}
|
||||
|
||||
func (n *natsRegistry) getConn() (*nats.Conn, error) {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
|
||||
if n.conn != nil {
|
||||
return n.conn, nil
|
||||
}
|
||||
|
||||
c, err := n.newConn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.conn = c
|
||||
|
||||
return n.conn, nil
|
||||
}
|
||||
|
||||
func (n *natsRegistry) register(s *registry.Service) error {
|
||||
conn, err := n.getConn()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
|
||||
// cache service
|
||||
n.services[s.Name] = addServices(n.services[s.Name], cp([]*registry.Service{s}))
|
||||
|
||||
// create query listener
|
||||
if n.listeners[s.Name] == nil {
|
||||
listener := make(chan bool)
|
||||
|
||||
// create a subscriber that responds to queries
|
||||
sub, err := conn.Subscribe(n.queryTopic, func(m *nats.Msg) {
|
||||
var result *registry.Result
|
||||
|
||||
if err := json.Unmarshal(m.Data, &result); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var services []*registry.Service
|
||||
|
||||
switch result.Action {
|
||||
// is this a get query and we own the service?
|
||||
case "get":
|
||||
if result.Service.Name != s.Name {
|
||||
return
|
||||
}
|
||||
n.RLock()
|
||||
services = cp(n.services[s.Name])
|
||||
n.RUnlock()
|
||||
// it's a list request, but we're still only a
|
||||
// subscriber for this service... so just get this service
|
||||
// totally suboptimal
|
||||
case "list":
|
||||
n.RLock()
|
||||
services = cp(n.services[s.Name])
|
||||
n.RUnlock()
|
||||
default:
|
||||
// does not match
|
||||
return
|
||||
}
|
||||
|
||||
// respond to query
|
||||
for _, service := range services {
|
||||
b, err := json.Marshal(service)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
conn.Publish(m.Reply, b)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Unsubscribe if we're told to do so
|
||||
go func() {
|
||||
<-listener
|
||||
sub.Unsubscribe()
|
||||
}()
|
||||
|
||||
n.listeners[s.Name] = listener
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *natsRegistry) deregister(s *registry.Service) error {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
|
||||
services := delServices(n.services[s.Name], cp([]*registry.Service{s}))
|
||||
if len(services) > 0 {
|
||||
n.services[s.Name] = services
|
||||
return nil
|
||||
}
|
||||
|
||||
// delete cached service
|
||||
delete(n.services, s.Name)
|
||||
|
||||
// delete query listener
|
||||
if listener, lexists := n.listeners[s.Name]; lexists {
|
||||
close(listener)
|
||||
delete(n.listeners, s.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *natsRegistry) query(s string, quorum int) ([]*registry.Service, error) {
|
||||
conn, err := n.getConn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var action string
|
||||
var service *registry.Service
|
||||
|
||||
if len(s) > 0 {
|
||||
action = "get"
|
||||
service = ®istry.Service{Name: s}
|
||||
} else {
|
||||
action = "list"
|
||||
}
|
||||
|
||||
inbox := nats.NewInbox()
|
||||
|
||||
response := make(chan *registry.Service, 10)
|
||||
|
||||
sub, err := conn.Subscribe(inbox, func(m *nats.Msg) {
|
||||
var service *registry.Service
|
||||
if err := json.Unmarshal(m.Data, &service); err != nil {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case response <- service:
|
||||
case <-time.After(n.opts.Timeout):
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
b, err := json.Marshal(®istry.Result{Action: action, Service: service})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := conn.PublishMsg(&nats.Msg{
|
||||
Subject: n.queryTopic,
|
||||
Reply: inbox,
|
||||
Data: b,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
timeoutChan := time.After(n.opts.Timeout)
|
||||
|
||||
serviceMap := make(map[string]*registry.Service)
|
||||
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case service := <-response:
|
||||
key := service.Name + "-" + service.Version
|
||||
srv, ok := serviceMap[key]
|
||||
if ok {
|
||||
srv.Nodes = append(srv.Nodes, service.Nodes...)
|
||||
serviceMap[key] = srv
|
||||
} else {
|
||||
serviceMap[key] = service
|
||||
}
|
||||
|
||||
if quorum > 0 && len(serviceMap[key].Nodes) >= quorum {
|
||||
break loop
|
||||
}
|
||||
case <-timeoutChan:
|
||||
break loop
|
||||
}
|
||||
}
|
||||
|
||||
var services []*registry.Service
|
||||
for _, service := range serviceMap {
|
||||
services = append(services, service)
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (n *natsRegistry) Init(opts ...registry.Option) error {
|
||||
return configure(n, opts...)
|
||||
}
|
||||
|
||||
func (n *natsRegistry) Options() registry.Options {
|
||||
return n.opts
|
||||
}
|
||||
|
||||
func (n *natsRegistry) Register(s *registry.Service, opts ...registry.RegisterOption) error {
|
||||
if err := n.register(s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := n.getConn()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := json.Marshal(®istry.Result{Action: n.registerAction, Service: s})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return conn.Publish(n.watchTopic, b)
|
||||
}
|
||||
|
||||
func (n *natsRegistry) Deregister(s *registry.Service, opts ...registry.DeregisterOption) error {
|
||||
if err := n.deregister(s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := n.getConn()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := json.Marshal(®istry.Result{Action: "delete", Service: s})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return conn.Publish(n.watchTopic, b)
|
||||
}
|
||||
|
||||
func (n *natsRegistry) GetService(s string, opts ...registry.GetOption) ([]*registry.Service, error) {
|
||||
services, err := n.query(s, getQuorum(n.opts))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (n *natsRegistry) ListServices(opts ...registry.ListOption) ([]*registry.Service, error) {
|
||||
s, err := n.query("", 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var services []*registry.Service
|
||||
serviceMap := make(map[string]*registry.Service)
|
||||
|
||||
for _, v := range s {
|
||||
serviceMap[v.Name] = ®istry.Service{Name: v.Name, Version: v.Version}
|
||||
}
|
||||
|
||||
for _, v := range serviceMap {
|
||||
services = append(services, v)
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (n *natsRegistry) Watch(opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
conn, err := n.getConn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sub, err := conn.SubscribeSync(n.watchTopic)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var wo registry.WatchOptions
|
||||
for _, o := range opts {
|
||||
o(&wo)
|
||||
}
|
||||
|
||||
return &natsWatcher{sub, wo}, nil
|
||||
}
|
||||
|
||||
func (n *natsRegistry) String() string {
|
||||
return "nats"
|
||||
}
|
||||
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
options := registry.Options{
|
||||
Timeout: time.Millisecond * 100,
|
||||
Context: context.Background(),
|
||||
}
|
||||
|
||||
n := &natsRegistry{
|
||||
opts: options,
|
||||
services: make(map[string][]*registry.Service),
|
||||
listeners: make(map[string]chan bool),
|
||||
}
|
||||
configure(n, opts...)
|
||||
return n
|
||||
}
|
||||
87
vendor/github.com/go-micro/plugins/v4/registry/nats/options.go
generated
vendored
87
vendor/github.com/go-micro/plugins/v4/registry/nats/options.go
generated
vendored
@@ -1,87 +0,0 @@
|
||||
package nats
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"go-micro.dev/v4/registry"
|
||||
)
|
||||
|
||||
type contextQuorumKey struct{}
|
||||
type optionsKey struct{}
|
||||
type watchTopicKey struct{}
|
||||
type queryTopicKey struct{}
|
||||
type registerActionKey struct{}
|
||||
|
||||
var (
|
||||
DefaultQuorum = 0
|
||||
)
|
||||
|
||||
func getQuorum(o registry.Options) int {
|
||||
if o.Context == nil {
|
||||
return DefaultQuorum
|
||||
}
|
||||
|
||||
value := o.Context.Value(contextQuorumKey{})
|
||||
if v, ok := value.(int); ok {
|
||||
return v
|
||||
} else {
|
||||
return DefaultQuorum
|
||||
}
|
||||
}
|
||||
|
||||
func Quorum(n int) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
o.Context = context.WithValue(o.Context, contextQuorumKey{}, n)
|
||||
}
|
||||
}
|
||||
|
||||
// Options allow to inject a nats.Options struct for configuring
|
||||
// the nats connection.
|
||||
func Options(nopts nats.Options) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, optionsKey{}, nopts)
|
||||
}
|
||||
}
|
||||
|
||||
// QueryTopic allows to set a custom nats topic on which service registries
|
||||
// query (survey) other services. All registries listen on this topic and
|
||||
// then respond to the query message.
|
||||
func QueryTopic(s string) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, queryTopicKey{}, s)
|
||||
}
|
||||
}
|
||||
|
||||
// WatchTopic allows to set a custom nats topic on which registries broadcast
|
||||
// changes (e.g. when services are added, updated or removed). Since we don't
|
||||
// have a central registry service, each service typically broadcasts in a
|
||||
// determined frequency on this topic.
|
||||
func WatchTopic(s string) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, watchTopicKey{}, s)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterAction allows to set the action to use when registering to nats.
|
||||
// As of now there are three different options:
|
||||
// - "create" (default) only registers if there is noone already registered under the same key.
|
||||
// - "update" only updates the registration if it already exists.
|
||||
// - "put" creates or updates a registration
|
||||
func RegisterAction(s string) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, registerActionKey{}, s)
|
||||
}
|
||||
}
|
||||
109
vendor/github.com/go-micro/plugins/v4/registry/nats/util.go
generated
vendored
109
vendor/github.com/go-micro/plugins/v4/registry/nats/util.go
generated
vendored
@@ -1,109 +0,0 @@
|
||||
package nats
|
||||
|
||||
import (
|
||||
"go-micro.dev/v4/registry"
|
||||
)
|
||||
|
||||
func cp(current []*registry.Service) []*registry.Service {
|
||||
var services []*registry.Service
|
||||
|
||||
for _, service := range current {
|
||||
// copy service
|
||||
s := new(registry.Service)
|
||||
*s = *service
|
||||
|
||||
// copy nodes
|
||||
var nodes []*registry.Node
|
||||
for _, node := range service.Nodes {
|
||||
n := new(registry.Node)
|
||||
*n = *node
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
s.Nodes = nodes
|
||||
|
||||
// copy endpoints
|
||||
var eps []*registry.Endpoint
|
||||
for _, ep := range service.Endpoints {
|
||||
e := new(registry.Endpoint)
|
||||
*e = *ep
|
||||
eps = append(eps, e)
|
||||
}
|
||||
s.Endpoints = eps
|
||||
|
||||
// append service
|
||||
services = append(services, s)
|
||||
}
|
||||
|
||||
return services
|
||||
}
|
||||
|
||||
func addNodes(old, neu []*registry.Node) []*registry.Node {
|
||||
for _, n := range neu {
|
||||
var seen bool
|
||||
for i, o := range old {
|
||||
if o.Id == n.Id {
|
||||
seen = true
|
||||
old[i] = n
|
||||
break
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
old = append(old, n)
|
||||
}
|
||||
}
|
||||
return old
|
||||
}
|
||||
|
||||
func addServices(old, neu []*registry.Service) []*registry.Service {
|
||||
for _, s := range neu {
|
||||
var seen bool
|
||||
for i, o := range old {
|
||||
if o.Version == s.Version {
|
||||
s.Nodes = addNodes(o.Nodes, s.Nodes)
|
||||
seen = true
|
||||
old[i] = s
|
||||
break
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
old = append(old, s)
|
||||
}
|
||||
}
|
||||
return old
|
||||
}
|
||||
|
||||
func delNodes(old, del []*registry.Node) []*registry.Node {
|
||||
var nodes []*registry.Node
|
||||
for _, o := range old {
|
||||
var rem bool
|
||||
for _, n := range del {
|
||||
if o.Id == n.Id {
|
||||
rem = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !rem {
|
||||
nodes = append(nodes, o)
|
||||
}
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
func delServices(old, del []*registry.Service) []*registry.Service {
|
||||
var services []*registry.Service
|
||||
for i, o := range old {
|
||||
var rem bool
|
||||
for _, s := range del {
|
||||
if o.Version == s.Version {
|
||||
old[i].Nodes = delNodes(o.Nodes, s.Nodes)
|
||||
if len(old[i].Nodes) == 0 {
|
||||
rem = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !rem {
|
||||
services = append(services, o)
|
||||
}
|
||||
}
|
||||
return services
|
||||
}
|
||||
39
vendor/github.com/go-micro/plugins/v4/registry/nats/watcher.go
generated
vendored
39
vendor/github.com/go-micro/plugins/v4/registry/nats/watcher.go
generated
vendored
@@ -1,39 +0,0 @@
|
||||
package nats
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"go-micro.dev/v4/registry"
|
||||
)
|
||||
|
||||
type natsWatcher struct {
|
||||
sub *nats.Subscription
|
||||
wo registry.WatchOptions
|
||||
}
|
||||
|
||||
func (n *natsWatcher) Next() (*registry.Result, error) {
|
||||
var result *registry.Result
|
||||
for {
|
||||
m, err := n.sub.NextMsg(time.Minute)
|
||||
if err != nil && err == nats.ErrTimeout {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(m.Data, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(n.wo.Service) > 0 && result.Service.Name != n.wo.Service {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (n *natsWatcher) Stop() {
|
||||
n.sub.Unsubscribe()
|
||||
}
|
||||
356
vendor/github.com/hashicorp/consul/api/LICENSE
generated
vendored
356
vendor/github.com/hashicorp/consul/api/LICENSE
generated
vendored
@@ -1,356 +0,0 @@
|
||||
Copyright (c) 2013 HashiCorp, Inc.
|
||||
|
||||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. “Contributor”
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. “Contributor Version”
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor’s Contribution.
|
||||
|
||||
1.3. “Contribution”
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. “Covered Software”
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. “Incompatible With Secondary Licenses”
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of version
|
||||
1.1 or earlier of the License, but not also under the terms of a
|
||||
Secondary License.
|
||||
|
||||
1.6. “Executable Form”
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. “Larger Work”
|
||||
|
||||
means a work that combines Covered Software with other material, in a separate
|
||||
file or files, that is not Covered Software.
|
||||
|
||||
1.8. “License”
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. “Licensable”
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether at the
|
||||
time of the initial grant or subsequently, any and all of the rights conveyed by
|
||||
this License.
|
||||
|
||||
1.10. “Modifications”
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to, deletion
|
||||
from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. “Patent Claims” of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method, process,
|
||||
and apparatus claims, in any patent Licensable by such Contributor that
|
||||
would be infringed, but for the grant of the License, by the making,
|
||||
using, selling, offering for sale, having made, import, or transfer of
|
||||
either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. “Secondary License”
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. “Source Code Form”
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. “You” (or “Your”)
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, “You” includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, “control” means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or as
|
||||
part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its Contributions
|
||||
or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||
effective for each Contribution on the date the Contributor first distributes
|
||||
such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under this
|
||||
License. No additional rights or licenses will be implied from the distribution
|
||||
or licensing of Covered Software under this License. Notwithstanding Section
|
||||
2.1(b) above, no patent license is granted by a Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party’s
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of its
|
||||
Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks, or
|
||||
logos of any Contributor (except as may be necessary to comply with the
|
||||
notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this License
|
||||
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
||||
under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its Contributions
|
||||
are its original creation(s) or it has sufficient rights to grant the
|
||||
rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under applicable
|
||||
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under the
|
||||
terms of this License. You must inform recipients that the Source Code Form
|
||||
of the Covered Software is governed by the terms of this License, and how
|
||||
they can obtain a copy of this License. You may not attempt to alter or
|
||||
restrict the recipients’ rights in the Source Code Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this License,
|
||||
or sublicense it under different terms, provided that the license for
|
||||
the Executable Form does not attempt to limit or alter the recipients’
|
||||
rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for the
|
||||
Covered Software. If the Larger Work is a combination of Covered Software
|
||||
with a work governed by one or more Secondary Licenses, and the Covered
|
||||
Software is not Incompatible With Secondary Licenses, this License permits
|
||||
You to additionally distribute such Covered Software under the terms of
|
||||
such Secondary License(s), so that the recipient of the Larger Work may, at
|
||||
their option, further distribute the Covered Software under the terms of
|
||||
either this License or such Secondary License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices (including
|
||||
copyright notices, patent notices, disclaimers of warranty, or limitations
|
||||
of liability) contained within the Source Code Form of the Covered
|
||||
Software, except that You may alter any license notices to the extent
|
||||
required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on behalf
|
||||
of any Contributor. You must make it absolutely clear that any such
|
||||
warranty, support, indemnity, or liability obligation is offered by You
|
||||
alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute, judicial
|
||||
order, or regulation then You must: (a) comply with the terms of this License
|
||||
to the maximum extent possible; and (b) describe the limitations and the code
|
||||
they affect. Such description must be placed in a text file included with all
|
||||
distributions of the Covered Software under this License. Except to the
|
||||
extent prohibited by statute or regulation, such description must be
|
||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||
understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
||||
if such Contributor fails to notify You of the non-compliance by some
|
||||
reasonable means prior to 60 days after You have come back into compliance.
|
||||
Moreover, Your grants from a particular Contributor are reinstated on an
|
||||
ongoing basis if such Contributor notifies You of the non-compliance by
|
||||
some reasonable means, this is the first time You have received notice of
|
||||
non-compliance with this License from such Contributor, and You become
|
||||
compliant prior to 30 days after Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions, counter-claims,
|
||||
and cross-claims) alleging that a Contributor Version directly or
|
||||
indirectly infringes any patent, then the rights granted to You by any and
|
||||
all Contributors for the Covered Software under Section 2.1 of this License
|
||||
shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an “as is” basis, without
|
||||
warranty of any kind, either expressed, implied, or statutory, including,
|
||||
without limitation, warranties that the Covered Software is free of defects,
|
||||
merchantable, fit for a particular purpose or non-infringing. The entire
|
||||
risk as to the quality and performance of the Covered Software is with You.
|
||||
Should any Covered Software prove defective in any respect, You (not any
|
||||
Contributor) assume the cost of any necessary servicing, repair, or
|
||||
correction. This disclaimer of warranty constitutes an essential part of this
|
||||
License. No use of any Covered Software is authorized under this License
|
||||
except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from such
|
||||
party’s negligence to the extent applicable law prohibits such limitation.
|
||||
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||
consequential damages, so this exclusion and limitation may not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts of
|
||||
a jurisdiction where the defendant maintains its principal place of business
|
||||
and such litigation shall be governed by laws of that jurisdiction, without
|
||||
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||
prevent a party’s ability to bring cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject matter
|
||||
hereof. If any provision of this License is held to be unenforceable, such
|
||||
provision shall be reformed only to the extent necessary to make it
|
||||
enforceable. Any law or regulation which provides that the language of a
|
||||
contract shall be construed against the drafter shall not be used to construe
|
||||
this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version of
|
||||
the License under which You originally received the Covered Software, or
|
||||
under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a modified
|
||||
version of this License if you rename the license and remove any
|
||||
references to the name of the license steward (except to note that such
|
||||
modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||
directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
||||
|
||||
This Source Code Form is “Incompatible
|
||||
With Secondary Licenses”, as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
||||
77
vendor/github.com/hashicorp/consul/api/README.md
generated
vendored
77
vendor/github.com/hashicorp/consul/api/README.md
generated
vendored
@@ -1,77 +0,0 @@
|
||||
# Consul API Client
|
||||
|
||||
This package provides the `api` package which provides programmatic access to the full Consul API.
|
||||
|
||||
The full documentation is available on [Godoc](https://godoc.org/github.com/hashicorp/consul/api).
|
||||
|
||||
## Usage
|
||||
|
||||
Below is an example of using the Consul client. To run the example, you must first
|
||||
[install Consul](https://developer.hashicorp.com/consul/downloads) and
|
||||
[Go](https://go.dev/doc/install).
|
||||
|
||||
To run the client API, create a new Go module.
|
||||
|
||||
```shell
|
||||
go mod init consul-demo
|
||||
```
|
||||
|
||||
Copy the example code into a file called `main.go` in the directory where the module is defined.
|
||||
As seen in the example, the Consul API is often imported with the alias `capi`.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
capi "github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Get a new client
|
||||
client, err := capi.NewClient(capi.DefaultConfig())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Get a handle to the KV API
|
||||
kv := client.KV()
|
||||
|
||||
// PUT a new KV pair
|
||||
p := &capi.KVPair{Key: "REDIS_MAXCLIENTS", Value: []byte("1000")}
|
||||
_, err = kv.Put(p, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Lookup the pair
|
||||
pair, _, err := kv.Get("REDIS_MAXCLIENTS", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("KV: %v %s\n", pair.Key, pair.Value)
|
||||
}
|
||||
```
|
||||
|
||||
Install the Consul API dependency with `go mod tidy`.
|
||||
|
||||
In a separate terminal window, start a local Consul server.
|
||||
|
||||
```shell
|
||||
consul agent -dev -node machine
|
||||
```
|
||||
|
||||
Run the example.
|
||||
|
||||
```shell
|
||||
go run .
|
||||
```
|
||||
|
||||
You should get the following result printed to the terminal.
|
||||
|
||||
```shell
|
||||
KV: REDIS_MAXCLIENTS 1000
|
||||
```
|
||||
|
||||
After running the code, you can also view the values in the Consul UI on your local machine at http://localhost:8500/ui/dc1/kv
|
||||
1625
vendor/github.com/hashicorp/consul/api/acl.go
generated
vendored
1625
vendor/github.com/hashicorp/consul/api/acl.go
generated
vendored
File diff suppressed because it is too large
Load Diff
1428
vendor/github.com/hashicorp/consul/api/agent.go
generated
vendored
1428
vendor/github.com/hashicorp/consul/api/agent.go
generated
vendored
File diff suppressed because it is too large
Load Diff
1277
vendor/github.com/hashicorp/consul/api/api.go
generated
vendored
1277
vendor/github.com/hashicorp/consul/api/api.go
generated
vendored
File diff suppressed because it is too large
Load Diff
377
vendor/github.com/hashicorp/consul/api/catalog.go
generated
vendored
377
vendor/github.com/hashicorp/consul/api/catalog.go
generated
vendored
@@ -1,377 +0,0 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Weights struct {
|
||||
Passing int
|
||||
Warning int
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
ID string
|
||||
Node string
|
||||
Address string
|
||||
Datacenter string
|
||||
TaggedAddresses map[string]string
|
||||
Meta map[string]string
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
Partition string `json:",omitempty"`
|
||||
PeerName string `json:",omitempty"`
|
||||
Locality *Locality `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceAddress struct {
|
||||
Address string
|
||||
Port int
|
||||
}
|
||||
|
||||
type CatalogService struct {
|
||||
ID string
|
||||
Node string
|
||||
Address string
|
||||
Datacenter string
|
||||
TaggedAddresses map[string]string
|
||||
NodeMeta map[string]string
|
||||
ServiceID string
|
||||
ServiceName string
|
||||
ServiceAddress string
|
||||
ServiceTaggedAddresses map[string]ServiceAddress
|
||||
ServiceTags []string
|
||||
ServiceMeta map[string]string
|
||||
ServicePort int
|
||||
ServiceWeights Weights
|
||||
ServiceEnableTagOverride bool
|
||||
ServiceProxy *AgentServiceConnectProxyConfig
|
||||
ServiceLocality *Locality `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
Checks HealthChecks
|
||||
ModifyIndex uint64
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type CatalogNode struct {
|
||||
Node *Node
|
||||
Services map[string]*AgentService
|
||||
}
|
||||
|
||||
type CatalogNodeServiceList struct {
|
||||
Node *Node
|
||||
Services []*AgentService
|
||||
}
|
||||
|
||||
type CatalogRegistration struct {
|
||||
ID string
|
||||
Node string
|
||||
Address string
|
||||
TaggedAddresses map[string]string
|
||||
NodeMeta map[string]string
|
||||
Datacenter string
|
||||
Service *AgentService
|
||||
Check *AgentCheck
|
||||
Checks HealthChecks
|
||||
SkipNodeUpdate bool
|
||||
Partition string `json:",omitempty"`
|
||||
Locality *Locality `json:",omitempty"`
|
||||
}
|
||||
|
||||
type CatalogDeregistration struct {
|
||||
Node string
|
||||
Address string `json:",omitempty"` // Obsolete.
|
||||
Datacenter string
|
||||
ServiceID string
|
||||
CheckID string
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type CompoundServiceName struct {
|
||||
Name string
|
||||
|
||||
// Namespacing is a Consul Enterprise feature.
|
||||
Namespace string `json:",omitempty"`
|
||||
// Partitions are a Consul Enterprise feature.
|
||||
Partition string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// GatewayService associates a gateway with a linked service.
|
||||
// It also contains service-specific gateway configuration like ingress listener port and protocol.
|
||||
type GatewayService struct {
|
||||
Gateway CompoundServiceName
|
||||
Service CompoundServiceName
|
||||
GatewayKind ServiceKind
|
||||
Port int `json:",omitempty"`
|
||||
Protocol string `json:",omitempty"`
|
||||
Hosts []string `json:",omitempty"`
|
||||
CAFile string `json:",omitempty"`
|
||||
CertFile string `json:",omitempty"`
|
||||
KeyFile string `json:",omitempty"`
|
||||
SNI string `json:",omitempty"`
|
||||
FromWildcard bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Catalog can be used to query the Catalog endpoints
|
||||
type Catalog struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// Catalog returns a handle to the catalog endpoints
|
||||
func (c *Client) Catalog() *Catalog {
|
||||
return &Catalog{c}
|
||||
}
|
||||
|
||||
func (c *Catalog) Register(reg *CatalogRegistration, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := c.c.newRequest("PUT", "/v1/catalog/register")
|
||||
r.setWriteOptions(q)
|
||||
r.obj = reg
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wm := &WriteMeta{}
|
||||
wm.RequestTime = rtt
|
||||
|
||||
return wm, nil
|
||||
}
|
||||
|
||||
func (c *Catalog) Deregister(dereg *CatalogDeregistration, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := c.c.newRequest("PUT", "/v1/catalog/deregister")
|
||||
r.setWriteOptions(q)
|
||||
r.obj = dereg
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wm := &WriteMeta{}
|
||||
wm.RequestTime = rtt
|
||||
|
||||
return wm, nil
|
||||
}
|
||||
|
||||
// Datacenters is used to query for all the known datacenters
|
||||
func (c *Catalog) Datacenters() ([]string, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/datacenters")
|
||||
_, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out []string
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Nodes is used to query all the known nodes
|
||||
func (c *Catalog) Nodes(q *QueryOptions) ([]*Node, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/nodes")
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out []*Node
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return out, qm, nil
|
||||
}
|
||||
|
||||
// Services is used to query for all known services
|
||||
func (c *Catalog) Services(q *QueryOptions) (map[string][]string, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/services")
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out map[string][]string
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return out, qm, nil
|
||||
}
|
||||
|
||||
// Service is used to query catalog entries for a given service
|
||||
func (c *Catalog) Service(service, tag string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) {
|
||||
var tags []string
|
||||
if tag != "" {
|
||||
tags = []string{tag}
|
||||
}
|
||||
return c.service(service, tags, q, false)
|
||||
}
|
||||
|
||||
// Supports multiple tags for filtering
|
||||
func (c *Catalog) ServiceMultipleTags(service string, tags []string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) {
|
||||
return c.service(service, tags, q, false)
|
||||
}
|
||||
|
||||
// Connect is used to query catalog entries for a given Connect-enabled service
|
||||
func (c *Catalog) Connect(service, tag string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) {
|
||||
var tags []string
|
||||
if tag != "" {
|
||||
tags = []string{tag}
|
||||
}
|
||||
return c.service(service, tags, q, true)
|
||||
}
|
||||
|
||||
// Supports multiple tags for filtering
|
||||
func (c *Catalog) ConnectMultipleTags(service string, tags []string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) {
|
||||
return c.service(service, tags, q, true)
|
||||
}
|
||||
|
||||
func (c *Catalog) service(service string, tags []string, q *QueryOptions, connect bool) ([]*CatalogService, *QueryMeta, error) {
|
||||
path := "/v1/catalog/service/" + service
|
||||
if connect {
|
||||
path = "/v1/catalog/connect/" + service
|
||||
}
|
||||
r := c.c.newRequest("GET", path)
|
||||
r.setQueryOptions(q)
|
||||
if len(tags) > 0 {
|
||||
for _, tag := range tags {
|
||||
r.params.Add("tag", tag)
|
||||
}
|
||||
}
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out []*CatalogService
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return out, qm, nil
|
||||
}
|
||||
|
||||
// Node is used to query for service information about a single node
|
||||
func (c *Catalog) Node(node string, q *QueryOptions) (*CatalogNode, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/node/"+node)
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out *CatalogNode
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return out, qm, nil
|
||||
}
|
||||
|
||||
// NodeServiceList is used to query for service information about a single node. It differs from
|
||||
// the Node function only in its return type which will contain a list of services as opposed to
|
||||
// a map of service ids to services. This different structure allows for using the wildcard specifier
|
||||
// '*' for the Namespace in the QueryOptions.
|
||||
func (c *Catalog) NodeServiceList(node string, q *QueryOptions) (*CatalogNodeServiceList, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/node-services/"+node)
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out *CatalogNodeServiceList
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return out, qm, nil
|
||||
}
|
||||
|
||||
// GatewayServices is used to query the services associated with an ingress gateway or terminating gateway.
|
||||
func (c *Catalog) GatewayServices(gateway string, q *QueryOptions) ([]*GatewayService, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/gateway-services/"+gateway)
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out []*GatewayService
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return out, qm, nil
|
||||
}
|
||||
|
||||
func ParseServiceAddr(addrPort string) (ServiceAddress, error) {
|
||||
port := 0
|
||||
host, portStr, err := net.SplitHostPort(addrPort)
|
||||
if err == nil {
|
||||
port, err = strconv.Atoi(portStr)
|
||||
}
|
||||
return ServiceAddress{Address: host, Port: port}, err
|
||||
}
|
||||
644
vendor/github.com/hashicorp/consul/api/config_entry.go
generated
vendored
644
vendor/github.com/hashicorp/consul/api/config_entry.go
generated
vendored
@@ -1,644 +0,0 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
const (
|
||||
ServiceDefaults string = "service-defaults"
|
||||
ProxyDefaults string = "proxy-defaults"
|
||||
ServiceRouter string = "service-router"
|
||||
ServiceSplitter string = "service-splitter"
|
||||
ServiceResolver string = "service-resolver"
|
||||
IngressGateway string = "ingress-gateway"
|
||||
TerminatingGateway string = "terminating-gateway"
|
||||
ServiceIntentions string = "service-intentions"
|
||||
MeshConfig string = "mesh"
|
||||
ExportedServices string = "exported-services"
|
||||
SamenessGroup string = "sameness-group"
|
||||
RateLimitIPConfig string = "control-plane-request-limit"
|
||||
|
||||
ProxyConfigGlobal string = "global"
|
||||
MeshConfigMesh string = "mesh"
|
||||
APIGateway string = "api-gateway"
|
||||
TCPRoute string = "tcp-route"
|
||||
InlineCertificate string = "inline-certificate"
|
||||
HTTPRoute string = "http-route"
|
||||
JWTProvider string = "jwt-provider"
|
||||
)
|
||||
|
||||
const (
|
||||
BuiltinAWSLambdaExtension string = "builtin/aws/lambda"
|
||||
BuiltinExtAuthzExtension string = "builtin/ext-authz"
|
||||
BuiltinLuaExtension string = "builtin/lua"
|
||||
BuiltinPropertyOverrideExtension string = "builtin/property-override"
|
||||
BuiltinWasmExtension string = "builtin/wasm"
|
||||
// BuiltinValidateExtension should not be exposed directly or accepted as a valid configured
|
||||
// extension type, as it is only used indirectly via troubleshooting tools. It is included here
|
||||
// for common reference alongside other builtin extensions.
|
||||
BuiltinValidateExtension string = "builtin/proxy/validate"
|
||||
)
|
||||
|
||||
type ConfigEntry interface {
|
||||
GetKind() string
|
||||
GetName() string
|
||||
GetPartition() string
|
||||
GetNamespace() string
|
||||
GetMeta() map[string]string
|
||||
GetCreateIndex() uint64
|
||||
GetModifyIndex() uint64
|
||||
}
|
||||
|
||||
type MeshGatewayMode string
|
||||
|
||||
const (
|
||||
// MeshGatewayModeDefault represents no specific mode and should
|
||||
// be used to indicate that a different layer of the configuration
|
||||
// chain should take precedence
|
||||
MeshGatewayModeDefault MeshGatewayMode = ""
|
||||
|
||||
// MeshGatewayModeNone represents that the Upstream Connect connections
|
||||
// should be direct and not flow through a mesh gateway.
|
||||
MeshGatewayModeNone MeshGatewayMode = "none"
|
||||
|
||||
// MeshGatewayModeLocal represents that the Upstream Connect connections
|
||||
// should be made to a mesh gateway in the local datacenter.
|
||||
MeshGatewayModeLocal MeshGatewayMode = "local"
|
||||
|
||||
// MeshGatewayModeRemote represents that the Upstream Connect connections
|
||||
// should be made to a mesh gateway in a remote datacenter.
|
||||
MeshGatewayModeRemote MeshGatewayMode = "remote"
|
||||
)
|
||||
|
||||
// MeshGatewayConfig controls how Mesh Gateways are used for upstream Connect
|
||||
// services
|
||||
type MeshGatewayConfig struct {
|
||||
// Mode is the mode that should be used for the upstream connection.
|
||||
Mode MeshGatewayMode `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ProxyMode string
|
||||
|
||||
const (
|
||||
// ProxyModeDefault represents no specific mode and should
|
||||
// be used to indicate that a different layer of the configuration
|
||||
// chain should take precedence
|
||||
ProxyModeDefault ProxyMode = ""
|
||||
|
||||
// ProxyModeTransparent represents that inbound and outbound application
|
||||
// traffic is being captured and redirected through the proxy.
|
||||
ProxyModeTransparent ProxyMode = "transparent"
|
||||
|
||||
// ProxyModeDirect represents that the proxy's listeners must be dialed directly
|
||||
// by the local application and other proxies.
|
||||
ProxyModeDirect ProxyMode = "direct"
|
||||
)
|
||||
|
||||
type TransparentProxyConfig struct {
|
||||
// The port of the listener where outbound application traffic is being redirected to.
|
||||
OutboundListenerPort int `json:",omitempty" alias:"outbound_listener_port"`
|
||||
|
||||
// DialedDirectly indicates whether transparent proxies can dial this proxy instance directly.
|
||||
// The discovery chain is not considered when dialing a service instance directly.
|
||||
// This setting is useful when addressing stateful services, such as a database cluster with a leader node.
|
||||
DialedDirectly bool `json:",omitempty" alias:"dialed_directly"`
|
||||
}
|
||||
|
||||
type MutualTLSMode string
|
||||
|
||||
const (
|
||||
// MutualTLSModeDefault represents no specific mode and should
|
||||
// be used to indicate that a different layer of the configuration
|
||||
// chain should take precedence.
|
||||
MutualTLSModeDefault MutualTLSMode = ""
|
||||
|
||||
// MutualTLSModeStrict requires mTLS for incoming traffic.
|
||||
MutualTLSModeStrict MutualTLSMode = "strict"
|
||||
|
||||
// MutualTLSModePermissive allows incoming non-mTLS traffic.
|
||||
MutualTLSModePermissive MutualTLSMode = "permissive"
|
||||
)
|
||||
|
||||
// ExposeConfig describes HTTP paths to expose through Envoy outside of Connect.
|
||||
// Users can expose individual paths and/or all HTTP/GRPC paths for checks.
|
||||
type ExposeConfig struct {
|
||||
// Checks defines whether paths associated with Consul checks will be exposed.
|
||||
// This flag triggers exposing all HTTP and GRPC check paths registered for the service.
|
||||
Checks bool `json:",omitempty"`
|
||||
|
||||
// Paths is the list of paths exposed through the proxy.
|
||||
Paths []ExposePath `json:",omitempty"`
|
||||
}
|
||||
|
||||
// EnvoyExtension has configuration for an extension that patches Envoy resources.
|
||||
type EnvoyExtension struct {
|
||||
Name string
|
||||
Required bool
|
||||
Arguments map[string]interface{} `bexpr:"-"`
|
||||
ConsulVersion string
|
||||
EnvoyVersion string
|
||||
}
|
||||
|
||||
type ExposePath struct {
|
||||
// ListenerPort defines the port of the proxy's listener for exposed paths.
|
||||
ListenerPort int `json:",omitempty" alias:"listener_port"`
|
||||
|
||||
// Path is the path to expose through the proxy, ie. "/metrics."
|
||||
Path string `json:",omitempty"`
|
||||
|
||||
// LocalPathPort is the port that the service is listening on for the given path.
|
||||
LocalPathPort int `json:",omitempty" alias:"local_path_port"`
|
||||
|
||||
// Protocol describes the upstream's service protocol.
|
||||
// Valid values are "http" and "http2", defaults to "http"
|
||||
Protocol string `json:",omitempty"`
|
||||
|
||||
// ParsedFromCheck is set if this path was parsed from a registered check
|
||||
ParsedFromCheck bool
|
||||
}
|
||||
|
||||
type LogSinkType string
|
||||
|
||||
const (
|
||||
DefaultLogSinkType LogSinkType = ""
|
||||
FileLogSinkType LogSinkType = "file"
|
||||
StdErrLogSinkType LogSinkType = "stderr"
|
||||
StdOutLogSinkType LogSinkType = "stdout"
|
||||
)
|
||||
|
||||
// AccessLogsConfig contains the associated default settings for all Envoy instances within the datacenter or partition
|
||||
type AccessLogsConfig struct {
|
||||
// Enabled turns off all access logging
|
||||
Enabled bool `json:",omitempty" alias:"enabled"`
|
||||
|
||||
// DisableListenerLogs turns off just listener logs for connections rejected by Envoy because they don't
|
||||
// have a matching listener filter.
|
||||
DisableListenerLogs bool `json:",omitempty" alias:"disable_listener_logs"`
|
||||
|
||||
// Type selects the output for logs: "file", "stderr". "stdout"
|
||||
Type LogSinkType `json:",omitempty" alias:"type"`
|
||||
|
||||
// Path is the output file to write logs
|
||||
Path string `json:",omitempty" alias:"path"`
|
||||
|
||||
// The presence of one format string or the other implies the access log string encoding.
|
||||
// Defining Both is invalid.
|
||||
JSONFormat string `json:",omitempty" alias:"json_format"`
|
||||
TextFormat string `json:",omitempty" alias:"text_format"`
|
||||
}
|
||||
|
||||
type UpstreamConfiguration struct {
|
||||
// Overrides is a slice of per-service configuration. The name field is
|
||||
// required.
|
||||
Overrides []*UpstreamConfig `json:",omitempty"`
|
||||
|
||||
// Defaults contains default configuration for all upstreams of a given
|
||||
// service. The name field must be empty.
|
||||
Defaults *UpstreamConfig `json:",omitempty"`
|
||||
}
|
||||
|
||||
type UpstreamConfig struct {
|
||||
// Name is only accepted within service-defaults.upstreamConfig.overrides .
|
||||
Name string `json:",omitempty"`
|
||||
|
||||
// Partition is only accepted within service-defaults.upstreamConfig.overrides .
|
||||
Partition string `json:",omitempty"`
|
||||
|
||||
// Namespace is only accepted within service-defaults.upstreamConfig.overrides .
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
// Peer is only accepted within service-defaults.upstreamConfig.overrides .
|
||||
Peer string `json:",omitempty"`
|
||||
|
||||
// EnvoyListenerJSON is a complete override ("escape hatch") for the upstream's
|
||||
// listener.
|
||||
//
|
||||
// Note: This escape hatch is NOT compatible with the discovery chain and
|
||||
// will be ignored if a discovery chain is active.
|
||||
EnvoyListenerJSON string `json:",omitempty" alias:"envoy_listener_json"`
|
||||
|
||||
// EnvoyClusterJSON is a complete override ("escape hatch") for the upstream's
|
||||
// cluster. The Connect client TLS certificate and context will be injected
|
||||
// overriding any TLS settings present.
|
||||
//
|
||||
// Note: This escape hatch is NOT compatible with the discovery chain and
|
||||
// will be ignored if a discovery chain is active.
|
||||
EnvoyClusterJSON string `json:",omitempty" alias:"envoy_cluster_json"`
|
||||
|
||||
// Protocol describes the upstream's service protocol. Valid values are "tcp",
|
||||
// "http" and "grpc". Anything else is treated as tcp. The enables protocol
|
||||
// aware features like per-request metrics and connection pooling, tracing,
|
||||
// routing etc.
|
||||
Protocol string `json:",omitempty"`
|
||||
|
||||
// ConnectTimeoutMs is the number of milliseconds to timeout making a new
|
||||
// connection to this upstream. Defaults to 5000 (5 seconds) if not set.
|
||||
ConnectTimeoutMs int `json:",omitempty" alias:"connect_timeout_ms"`
|
||||
|
||||
// Limits are the set of limits that are applied to the proxy for a specific upstream of a
|
||||
// service instance.
|
||||
Limits *UpstreamLimits `json:",omitempty"`
|
||||
|
||||
// PassiveHealthCheck configuration determines how upstream proxy instances will
|
||||
// be monitored for removal from the load balancing pool.
|
||||
PassiveHealthCheck *PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"`
|
||||
|
||||
// MeshGatewayConfig controls how Mesh Gateways are configured and used
|
||||
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway" `
|
||||
|
||||
// BalanceOutboundConnections indicates that the proxy should attempt to evenly distribute
|
||||
// outbound connections across worker threads. Only used by envoy proxies.
|
||||
BalanceOutboundConnections string `json:",omitempty" alias:"balance_outbound_connections"`
|
||||
}
|
||||
|
||||
// DestinationConfig represents a virtual service, i.e. one that is external to Consul
|
||||
type DestinationConfig struct {
|
||||
// Addresses of the endpoint; hostname or IP
|
||||
Addresses []string `json:",omitempty"`
|
||||
|
||||
// Port allowed within this endpoint
|
||||
Port int `json:",omitempty"`
|
||||
}
|
||||
|
||||
type PassiveHealthCheck struct {
|
||||
// Interval between health check analysis sweeps. Each sweep may remove
|
||||
// hosts or return hosts to the pool.
|
||||
Interval time.Duration `json:",omitempty"`
|
||||
|
||||
// MaxFailures is the count of consecutive failures that results in a host
|
||||
// being removed from the pool.
|
||||
MaxFailures uint32 `alias:"max_failures"`
|
||||
|
||||
// EnforcingConsecutive5xx is the % chance that a host will be actually ejected
|
||||
// when an outlier status is detected through consecutive 5xx.
|
||||
// This setting can be used to disable ejection or to ramp it up slowly.
|
||||
EnforcingConsecutive5xx *uint32 `json:",omitempty" alias:"enforcing_consecutive_5xx"`
|
||||
|
||||
// The maximum % of an upstream cluster that can be ejected due to outlier detection.
|
||||
// Defaults to 10% but will eject at least one host regardless of the value.
|
||||
MaxEjectionPercent *uint32 `json:",omitempty" alias:"max_ejection_percent"`
|
||||
|
||||
// The base time that a host is ejected for. The real time is equal to the base time
|
||||
// multiplied by the number of times the host has been ejected and is capped by
|
||||
// max_ejection_time (Default 300s). Defaults to 30000ms or 30s.
|
||||
BaseEjectionTime *time.Duration `json:",omitempty" alias:"base_ejection_time"`
|
||||
}
|
||||
|
||||
// UpstreamLimits describes the limits that are associated with a specific
|
||||
// upstream of a service instance.
|
||||
type UpstreamLimits struct {
|
||||
// MaxConnections is the maximum number of connections the local proxy can
|
||||
// make to the upstream service.
|
||||
MaxConnections *int `alias:"max_connections"`
|
||||
|
||||
// MaxPendingRequests is the maximum number of requests that will be queued
|
||||
// waiting for an available connection. This is mostly applicable to HTTP/1.1
|
||||
// clusters since all HTTP/2 requests are streamed over a single
|
||||
// connection.
|
||||
MaxPendingRequests *int `alias:"max_pending_requests"`
|
||||
|
||||
// MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed
|
||||
// to the upstream cluster at a point in time. This is mostly applicable to HTTP/2
|
||||
// clusters since all HTTP/1.1 requests are limited by MaxConnections.
|
||||
MaxConcurrentRequests *int `alias:"max_concurrent_requests"`
|
||||
}
|
||||
|
||||
type ServiceConfigEntry struct {
|
||||
Kind string
|
||||
Name string
|
||||
Partition string `json:",omitempty"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Protocol string `json:",omitempty"`
|
||||
Mode ProxyMode `json:",omitempty"`
|
||||
TransparentProxy *TransparentProxyConfig `json:",omitempty" alias:"transparent_proxy"`
|
||||
MutualTLSMode MutualTLSMode `json:",omitempty" alias:"mutual_tls_mode"`
|
||||
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"`
|
||||
Expose ExposeConfig `json:",omitempty"`
|
||||
ExternalSNI string `json:",omitempty" alias:"external_sni"`
|
||||
UpstreamConfig *UpstreamConfiguration `json:",omitempty" alias:"upstream_config"`
|
||||
Destination *DestinationConfig `json:",omitempty"`
|
||||
MaxInboundConnections int `json:",omitempty" alias:"max_inbound_connections"`
|
||||
LocalConnectTimeoutMs int `json:",omitempty" alias:"local_connect_timeout_ms"`
|
||||
LocalRequestTimeoutMs int `json:",omitempty" alias:"local_request_timeout_ms"`
|
||||
BalanceInboundConnections string `json:",omitempty" alias:"balance_inbound_connections"`
|
||||
EnvoyExtensions []EnvoyExtension `json:",omitempty" alias:"envoy_extensions"`
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
func (s *ServiceConfigEntry) GetKind() string { return s.Kind }
|
||||
func (s *ServiceConfigEntry) GetName() string { return s.Name }
|
||||
func (s *ServiceConfigEntry) GetPartition() string { return s.Partition }
|
||||
func (s *ServiceConfigEntry) GetNamespace() string { return s.Namespace }
|
||||
func (s *ServiceConfigEntry) GetMeta() map[string]string { return s.Meta }
|
||||
func (s *ServiceConfigEntry) GetCreateIndex() uint64 { return s.CreateIndex }
|
||||
func (s *ServiceConfigEntry) GetModifyIndex() uint64 { return s.ModifyIndex }
|
||||
|
||||
type ProxyConfigEntry struct {
|
||||
Kind string
|
||||
Name string
|
||||
Partition string `json:",omitempty"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Mode ProxyMode `json:",omitempty"`
|
||||
TransparentProxy *TransparentProxyConfig `json:",omitempty" alias:"transparent_proxy"`
|
||||
MutualTLSMode MutualTLSMode `json:",omitempty" alias:"mutual_tls_mode"`
|
||||
Config map[string]interface{} `json:",omitempty"`
|
||||
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"`
|
||||
Expose ExposeConfig `json:",omitempty"`
|
||||
AccessLogs *AccessLogsConfig `json:",omitempty" alias:"access_logs"`
|
||||
EnvoyExtensions []EnvoyExtension `json:",omitempty" alias:"envoy_extensions"`
|
||||
FailoverPolicy *ServiceResolverFailoverPolicy `json:",omitempty" alias:"failover_policy"`
|
||||
PrioritizeByLocality *ServiceResolverPrioritizeByLocality `json:",omitempty" alias:"prioritize_by_locality"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
func (p *ProxyConfigEntry) GetKind() string { return p.Kind }
|
||||
func (p *ProxyConfigEntry) GetName() string { return ProxyConfigGlobal }
|
||||
func (p *ProxyConfigEntry) GetPartition() string { return p.Partition }
|
||||
func (p *ProxyConfigEntry) GetNamespace() string { return p.Namespace }
|
||||
func (p *ProxyConfigEntry) GetMeta() map[string]string { return p.Meta }
|
||||
func (p *ProxyConfigEntry) GetCreateIndex() uint64 { return p.CreateIndex }
|
||||
func (p *ProxyConfigEntry) GetModifyIndex() uint64 { return p.ModifyIndex }
|
||||
|
||||
func makeConfigEntry(kind, name string) (ConfigEntry, error) {
|
||||
switch kind {
|
||||
case ServiceDefaults:
|
||||
return &ServiceConfigEntry{Kind: kind, Name: name}, nil
|
||||
case ProxyDefaults:
|
||||
return &ProxyConfigEntry{Kind: kind, Name: name}, nil
|
||||
case ServiceRouter:
|
||||
return &ServiceRouterConfigEntry{Kind: kind, Name: name}, nil
|
||||
case ServiceSplitter:
|
||||
return &ServiceSplitterConfigEntry{Kind: kind, Name: name}, nil
|
||||
case ServiceResolver:
|
||||
return &ServiceResolverConfigEntry{Kind: kind, Name: name}, nil
|
||||
case IngressGateway:
|
||||
return &IngressGatewayConfigEntry{Kind: kind, Name: name}, nil
|
||||
case TerminatingGateway:
|
||||
return &TerminatingGatewayConfigEntry{Kind: kind, Name: name}, nil
|
||||
case ServiceIntentions:
|
||||
return &ServiceIntentionsConfigEntry{Kind: kind, Name: name}, nil
|
||||
case MeshConfig:
|
||||
return &MeshConfigEntry{}, nil
|
||||
case ExportedServices:
|
||||
return &ExportedServicesConfigEntry{Name: name}, nil
|
||||
case SamenessGroup:
|
||||
return &SamenessGroupConfigEntry{Kind: kind, Name: name}, nil
|
||||
case APIGateway:
|
||||
return &APIGatewayConfigEntry{Kind: kind, Name: name}, nil
|
||||
case TCPRoute:
|
||||
return &TCPRouteConfigEntry{Kind: kind, Name: name}, nil
|
||||
case InlineCertificate:
|
||||
return &InlineCertificateConfigEntry{Kind: kind, Name: name}, nil
|
||||
case HTTPRoute:
|
||||
return &HTTPRouteConfigEntry{Kind: kind, Name: name}, nil
|
||||
case RateLimitIPConfig:
|
||||
return &RateLimitIPConfigEntry{Kind: kind, Name: name}, nil
|
||||
case JWTProvider:
|
||||
return &JWTProviderConfigEntry{Kind: kind, Name: name}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid config entry kind: %s", kind)
|
||||
}
|
||||
}
|
||||
|
||||
func MakeConfigEntry(kind, name string) (ConfigEntry, error) {
|
||||
return makeConfigEntry(kind, name)
|
||||
}
|
||||
|
||||
// DecodeConfigEntry will decode the result of using json.Unmarshal of a config
|
||||
// entry into a map[string]interface{}.
|
||||
//
|
||||
// Important caveats:
|
||||
//
|
||||
// - This will NOT work if the map[string]interface{} was produced using HCL
|
||||
// decoding as that requires more extensive parsing to work around the issues
|
||||
// with map[string][]interface{} that arise.
|
||||
//
|
||||
// - This will only decode fields using their camel case json field
|
||||
// representations.
|
||||
func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) {
|
||||
var entry ConfigEntry
|
||||
|
||||
kindVal, ok := raw["Kind"]
|
||||
if !ok {
|
||||
kindVal, ok = raw["kind"]
|
||||
}
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Payload does not contain a kind/Kind key at the top level")
|
||||
}
|
||||
|
||||
if kindStr, ok := kindVal.(string); ok {
|
||||
newEntry, err := makeConfigEntry(kindStr, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry = newEntry
|
||||
} else {
|
||||
return nil, fmt.Errorf("Kind value in payload is not a string")
|
||||
}
|
||||
|
||||
decodeConf := &mapstructure.DecoderConfig{
|
||||
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||
mapstructure.StringToTimeDurationHookFunc(),
|
||||
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
||||
),
|
||||
Result: &entry,
|
||||
WeaklyTypedInput: true,
|
||||
}
|
||||
|
||||
decoder, err := mapstructure.NewDecoder(decodeConf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entry, decoder.Decode(raw)
|
||||
}
|
||||
|
||||
func DecodeConfigEntryFromJSON(data []byte) (ConfigEntry, error) {
|
||||
var raw map[string]interface{}
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return DecodeConfigEntry(raw)
|
||||
}
|
||||
|
||||
func decodeConfigEntrySlice(raw []map[string]interface{}) ([]ConfigEntry, error) {
|
||||
var entries []ConfigEntry
|
||||
for _, rawEntry := range raw {
|
||||
entry, err := DecodeConfigEntry(rawEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
// ConfigEntries can be used to query the Config endpoints
|
||||
type ConfigEntries struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// Config returns a handle to the Config endpoints
|
||||
func (c *Client) ConfigEntries() *ConfigEntries {
|
||||
return &ConfigEntries{c}
|
||||
}
|
||||
|
||||
func (conf *ConfigEntries) Get(kind string, name string, q *QueryOptions) (ConfigEntry, *QueryMeta, error) {
|
||||
if kind == "" || name == "" {
|
||||
return nil, nil, fmt.Errorf("Both kind and name parameters must not be empty")
|
||||
}
|
||||
|
||||
entry, err := makeConfigEntry(kind, name)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s/%s", kind, name))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := conf.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
if err := decodeBody(resp, entry); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return entry, qm, nil
|
||||
}
|
||||
|
||||
func (conf *ConfigEntries) List(kind string, q *QueryOptions) ([]ConfigEntry, *QueryMeta, error) {
|
||||
if kind == "" {
|
||||
return nil, nil, fmt.Errorf("The kind parameter must not be empty")
|
||||
}
|
||||
|
||||
r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s", kind))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := conf.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var raw []map[string]interface{}
|
||||
if err := decodeBody(resp, &raw); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
entries, err := decodeConfigEntrySlice(raw)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return entries, qm, nil
|
||||
}
|
||||
|
||||
func (conf *ConfigEntries) Set(entry ConfigEntry, w *WriteOptions) (bool, *WriteMeta, error) {
|
||||
return conf.set(entry, nil, w)
|
||||
}
|
||||
|
||||
func (conf *ConfigEntries) CAS(entry ConfigEntry, index uint64, w *WriteOptions) (bool, *WriteMeta, error) {
|
||||
return conf.set(entry, map[string]string{"cas": strconv.FormatUint(index, 10)}, w)
|
||||
}
|
||||
|
||||
func (conf *ConfigEntries) set(entry ConfigEntry, params map[string]string, w *WriteOptions) (bool, *WriteMeta, error) {
|
||||
r := conf.c.newRequest("PUT", "/v1/config")
|
||||
r.setWriteOptions(w)
|
||||
for param, value := range params {
|
||||
r.params.Set(param, value)
|
||||
}
|
||||
r.obj = entry
|
||||
rtt, resp, err := conf.c.doRequest(r)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
if err := requireOK(resp); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if _, err := io.Copy(&buf, resp.Body); err != nil {
|
||||
return false, nil, fmt.Errorf("Failed to read response: %v", err)
|
||||
}
|
||||
res := strings.Contains(buf.String(), "true")
|
||||
|
||||
wm := &WriteMeta{RequestTime: rtt}
|
||||
return res, wm, nil
|
||||
}
|
||||
|
||||
func (conf *ConfigEntries) Delete(kind string, name string, w *WriteOptions) (*WriteMeta, error) {
|
||||
_, wm, err := conf.delete(kind, name, nil, w)
|
||||
return wm, err
|
||||
}
|
||||
|
||||
// DeleteCAS performs a Check-And-Set deletion of the given config entry, and
|
||||
// returns true if it was successful. If the provided index no longer matches
|
||||
// the entry's ModifyIndex (i.e. it was modified by another process) then the
|
||||
// operation will fail and return false.
|
||||
func (conf *ConfigEntries) DeleteCAS(kind, name string, index uint64, w *WriteOptions) (bool, *WriteMeta, error) {
|
||||
return conf.delete(kind, name, map[string]string{"cas": strconv.FormatUint(index, 10)}, w)
|
||||
}
|
||||
|
||||
func (conf *ConfigEntries) delete(kind, name string, params map[string]string, w *WriteOptions) (bool, *WriteMeta, error) {
|
||||
if kind == "" || name == "" {
|
||||
return false, nil, fmt.Errorf("Both kind and name parameters must not be empty")
|
||||
}
|
||||
|
||||
r := conf.c.newRequest("DELETE", fmt.Sprintf("/v1/config/%s/%s", kind, name))
|
||||
r.setWriteOptions(w)
|
||||
for param, value := range params {
|
||||
r.params.Set(param, value)
|
||||
}
|
||||
|
||||
rtt, resp, err := conf.c.doRequest(r)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
defer closeResponseBody(resp)
|
||||
|
||||
if err := requireOK(resp); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if _, err := io.Copy(&buf, resp.Body); err != nil {
|
||||
return false, nil, fmt.Errorf("Failed to read response: %v", err)
|
||||
}
|
||||
|
||||
res := strings.Contains(buf.String(), "true")
|
||||
wm := &WriteMeta{RequestTime: rtt}
|
||||
return res, wm, nil
|
||||
}
|
||||
370
vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go
generated
vendored
370
vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go
generated
vendored
@@ -1,370 +0,0 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ServiceRouterConfigEntry struct {
|
||||
Kind string
|
||||
Name string
|
||||
Partition string `json:",omitempty"`
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
Routes []ServiceRoute `json:",omitempty"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
func (e *ServiceRouterConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceRouterConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceRouterConfigEntry) GetPartition() string { return e.Partition }
|
||||
func (e *ServiceRouterConfigEntry) GetNamespace() string { return e.Namespace }
|
||||
func (e *ServiceRouterConfigEntry) GetMeta() map[string]string { return e.Meta }
|
||||
func (e *ServiceRouterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceRouterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
|
||||
type ServiceRoute struct {
|
||||
Match *ServiceRouteMatch `json:",omitempty"`
|
||||
Destination *ServiceRouteDestination `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceRouteMatch struct {
|
||||
HTTP *ServiceRouteHTTPMatch `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceRouteHTTPMatch struct {
|
||||
PathExact string `json:",omitempty" alias:"path_exact"`
|
||||
PathPrefix string `json:",omitempty" alias:"path_prefix"`
|
||||
PathRegex string `json:",omitempty" alias:"path_regex"`
|
||||
|
||||
Header []ServiceRouteHTTPMatchHeader `json:",omitempty"`
|
||||
QueryParam []ServiceRouteHTTPMatchQueryParam `json:",omitempty" alias:"query_param"`
|
||||
Methods []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceRouteHTTPMatchHeader struct {
|
||||
Name string
|
||||
Present bool `json:",omitempty"`
|
||||
Exact string `json:",omitempty"`
|
||||
Prefix string `json:",omitempty"`
|
||||
Suffix string `json:",omitempty"`
|
||||
Regex string `json:",omitempty"`
|
||||
Invert bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceRouteHTTPMatchQueryParam struct {
|
||||
Name string
|
||||
Present bool `json:",omitempty"`
|
||||
Exact string `json:",omitempty"`
|
||||
Regex string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceRouteDestination struct {
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
PrefixRewrite string `json:",omitempty" alias:"prefix_rewrite"`
|
||||
RequestTimeout time.Duration `json:",omitempty" alias:"request_timeout"`
|
||||
IdleTimeout time.Duration `json:",omitempty" alias:"idle_timeout"`
|
||||
NumRetries uint32 `json:",omitempty" alias:"num_retries"`
|
||||
RetryOnConnectFailure bool `json:",omitempty" alias:"retry_on_connect_failure"`
|
||||
RetryOnStatusCodes []uint32 `json:",omitempty" alias:"retry_on_status_codes"`
|
||||
RetryOn []string `json:",omitempty" alias:"retry_on"`
|
||||
RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"`
|
||||
ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"`
|
||||
}
|
||||
|
||||
func (e *ServiceRouteDestination) MarshalJSON() ([]byte, error) {
|
||||
type Alias ServiceRouteDestination
|
||||
exported := &struct {
|
||||
RequestTimeout string `json:",omitempty"`
|
||||
IdleTimeout string `json:",omitempty"`
|
||||
*Alias
|
||||
}{
|
||||
RequestTimeout: e.RequestTimeout.String(),
|
||||
IdleTimeout: e.IdleTimeout.String(),
|
||||
Alias: (*Alias)(e),
|
||||
}
|
||||
if e.RequestTimeout == 0 {
|
||||
exported.RequestTimeout = ""
|
||||
}
|
||||
if e.IdleTimeout == 0 {
|
||||
exported.IdleTimeout = ""
|
||||
}
|
||||
|
||||
return json.Marshal(exported)
|
||||
}
|
||||
|
||||
func (e *ServiceRouteDestination) UnmarshalJSON(data []byte) error {
|
||||
type Alias ServiceRouteDestination
|
||||
aux := &struct {
|
||||
RequestTimeout string
|
||||
IdleTimeout string
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(e),
|
||||
}
|
||||
if err := json.Unmarshal(data, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
if aux.RequestTimeout != "" {
|
||||
if e.RequestTimeout, err = time.ParseDuration(aux.RequestTimeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if aux.IdleTimeout != "" {
|
||||
if e.IdleTimeout, err = time.ParseDuration(aux.IdleTimeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ServiceSplitterConfigEntry struct {
|
||||
Kind string
|
||||
Name string
|
||||
Partition string `json:",omitempty"`
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
Splits []ServiceSplit `json:",omitempty"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
func (e *ServiceSplitterConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceSplitterConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceSplitterConfigEntry) GetPartition() string { return e.Partition }
|
||||
func (e *ServiceSplitterConfigEntry) GetNamespace() string { return e.Namespace }
|
||||
func (e *ServiceSplitterConfigEntry) GetMeta() map[string]string { return e.Meta }
|
||||
func (e *ServiceSplitterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceSplitterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
|
||||
type ServiceSplit struct {
|
||||
Weight float32
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"`
|
||||
ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"`
|
||||
}
|
||||
|
||||
type ServiceResolverConfigEntry struct {
|
||||
Kind string
|
||||
Name string
|
||||
Partition string `json:",omitempty"`
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
DefaultSubset string `json:",omitempty" alias:"default_subset"`
|
||||
Subsets map[string]ServiceResolverSubset `json:",omitempty"`
|
||||
Redirect *ServiceResolverRedirect `json:",omitempty"`
|
||||
Failover map[string]ServiceResolverFailover `json:",omitempty"`
|
||||
ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"`
|
||||
RequestTimeout time.Duration `json:",omitempty" alias:"request_timeout"`
|
||||
|
||||
// PrioritizeByLocality controls whether the locality of services within the
|
||||
// local partition will be used to prioritize connectivity.
|
||||
PrioritizeByLocality *ServiceResolverPrioritizeByLocality `json:",omitempty" alias:"prioritize_by_locality"`
|
||||
|
||||
// LoadBalancer determines the load balancing policy and configuration for services
|
||||
// issuing requests to this upstream service.
|
||||
LoadBalancer *LoadBalancer `json:",omitempty" alias:"load_balancer"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
func (e *ServiceResolverConfigEntry) MarshalJSON() ([]byte, error) {
|
||||
type Alias ServiceResolverConfigEntry
|
||||
exported := &struct {
|
||||
ConnectTimeout string `json:",omitempty"`
|
||||
*Alias
|
||||
}{
|
||||
ConnectTimeout: e.ConnectTimeout.String(),
|
||||
Alias: (*Alias)(e),
|
||||
}
|
||||
if e.ConnectTimeout == 0 {
|
||||
exported.ConnectTimeout = ""
|
||||
}
|
||||
|
||||
return json.Marshal(exported)
|
||||
}
|
||||
|
||||
func (e *ServiceResolverConfigEntry) UnmarshalJSON(data []byte) error {
|
||||
type Alias ServiceResolverConfigEntry
|
||||
aux := &struct {
|
||||
ConnectTimeout string
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(e),
|
||||
}
|
||||
if err := json.Unmarshal(data, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
if aux.ConnectTimeout != "" {
|
||||
if e.ConnectTimeout, err = time.ParseDuration(aux.ConnectTimeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *ServiceResolverConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceResolverConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceResolverConfigEntry) GetPartition() string { return e.Partition }
|
||||
func (e *ServiceResolverConfigEntry) GetNamespace() string { return e.Namespace }
|
||||
func (e *ServiceResolverConfigEntry) GetMeta() map[string]string { return e.Meta }
|
||||
func (e *ServiceResolverConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceResolverConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
|
||||
type ServiceResolverSubset struct {
|
||||
Filter string `json:",omitempty"`
|
||||
OnlyPassing bool `json:",omitempty" alias:"only_passing"`
|
||||
}
|
||||
|
||||
type ServiceResolverRedirect struct {
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
Datacenter string `json:",omitempty"`
|
||||
Peer string `json:",omitempty"`
|
||||
SamenessGroup string `json:",omitempty" alias:"sameness_group"`
|
||||
}
|
||||
|
||||
type ServiceResolverFailover struct {
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
// Referencing other partitions is not supported.
|
||||
Namespace string `json:",omitempty"`
|
||||
Datacenters []string `json:",omitempty"`
|
||||
Targets []ServiceResolverFailoverTarget `json:",omitempty"`
|
||||
Policy *ServiceResolverFailoverPolicy `json:",omitempty"`
|
||||
SamenessGroup string `json:",omitempty" alias:"sameness_group"`
|
||||
}
|
||||
|
||||
type ServiceResolverFailoverTarget struct {
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
Partition string `json:",omitempty"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Datacenter string `json:",omitempty"`
|
||||
Peer string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceResolverFailoverPolicy struct {
|
||||
// Mode specifies the type of failover that will be performed. Valid values are
|
||||
// "sequential", "" (equivalent to "sequential") and "order-by-locality".
|
||||
Mode string `json:",omitempty"`
|
||||
Regions []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceResolverPrioritizeByLocality struct {
|
||||
// Mode specifies the type of prioritization that will be performed
|
||||
// when selecting nodes in the local partition.
|
||||
// Valid values are: "" (default "none"), "none", and "failover".
|
||||
Mode string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// LoadBalancer determines the load balancing policy and configuration for services
|
||||
// issuing requests to this upstream service.
|
||||
type LoadBalancer struct {
|
||||
// Policy is the load balancing policy used to select a host
|
||||
Policy string `json:",omitempty"`
|
||||
|
||||
// RingHashConfig contains configuration for the "ring_hash" policy type
|
||||
RingHashConfig *RingHashConfig `json:",omitempty" alias:"ring_hash_config"`
|
||||
|
||||
// LeastRequestConfig contains configuration for the "least_request" policy type
|
||||
LeastRequestConfig *LeastRequestConfig `json:",omitempty" alias:"least_request_config"`
|
||||
|
||||
// HashPolicies is a list of hash policies to use for hashing load balancing algorithms.
|
||||
// Hash policies are evaluated individually and combined such that identical lists
|
||||
// result in the same hash.
|
||||
// If no hash policies are present, or none are successfully evaluated,
|
||||
// then a random backend host will be selected.
|
||||
HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"`
|
||||
}
|
||||
|
||||
// RingHashConfig contains configuration for the "ring_hash" policy type
|
||||
type RingHashConfig struct {
|
||||
// MinimumRingSize determines the minimum number of entries in the hash ring
|
||||
MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"`
|
||||
|
||||
// MaximumRingSize determines the maximum number of entries in the hash ring
|
||||
MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"`
|
||||
}
|
||||
|
||||
// LeastRequestConfig contains configuration for the "least_request" policy type
|
||||
type LeastRequestConfig struct {
|
||||
// ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests.
|
||||
ChoiceCount uint32 `json:",omitempty" alias:"choice_count"`
|
||||
}
|
||||
|
||||
// HashPolicy defines which attributes will be hashed by hash-based LB algorithms
|
||||
type HashPolicy struct {
|
||||
// Field is the attribute type to hash on.
|
||||
// Must be one of "header","cookie", or "query_parameter".
|
||||
// Cannot be specified along with SourceIP.
|
||||
Field string `json:",omitempty"`
|
||||
|
||||
// FieldValue is the value to hash.
|
||||
// ie. header name, cookie name, URL query parameter name
|
||||
// Cannot be specified along with SourceIP.
|
||||
FieldValue string `json:",omitempty" alias:"field_value"`
|
||||
|
||||
// CookieConfig contains configuration for the "cookie" hash policy type.
|
||||
CookieConfig *CookieConfig `json:",omitempty" alias:"cookie_config"`
|
||||
|
||||
// SourceIP determines whether the hash should be of the source IP rather than of a field and field value.
|
||||
// Cannot be specified along with Field or FieldValue.
|
||||
SourceIP bool `json:",omitempty" alias:"source_ip"`
|
||||
|
||||
// Terminal will short circuit the computation of the hash when multiple hash policies are present.
|
||||
// If a hash is computed when a Terminal policy is evaluated,
|
||||
// then that hash will be used and subsequent hash policies will be ignored.
|
||||
Terminal bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
// CookieConfig contains configuration for the "cookie" hash policy type.
|
||||
// This is specified to have Envoy generate a cookie for a client on its first request.
|
||||
type CookieConfig struct {
|
||||
// Generates a session cookie with no expiration.
|
||||
Session bool `json:",omitempty"`
|
||||
|
||||
// TTL for generated cookies. Cannot be specified for session cookies.
|
||||
TTL time.Duration `json:",omitempty"`
|
||||
|
||||
// The path to set for the cookie
|
||||
Path string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// HTTPHeaderModifiers is a set of rules for HTTP header modification that
|
||||
// should be performed by proxies as the request passes through them. It can
|
||||
// operate on either request or response headers depending on the context in
|
||||
// which it is used.
|
||||
type HTTPHeaderModifiers struct {
|
||||
// Add is a set of name -> value pairs that should be appended to the request
|
||||
// or response (i.e. allowing duplicates if the same header already exists).
|
||||
Add map[string]string `json:",omitempty"`
|
||||
|
||||
// Set is a set of name -> value pairs that should be added to the request or
|
||||
// response, overwriting any existing header values of the same name.
|
||||
Set map[string]string `json:",omitempty"`
|
||||
|
||||
// Remove is the set of header names that should be stripped from the request
|
||||
// or response.
|
||||
Remove []string `json:",omitempty"`
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user