Giter Site home page Giter Site logo

node-consul's Introduction

Consul

This is a Consul client.

Documentation

See the official HTTP API docs for more information.

Consul([options])

Initialize a new Consul client.

Options

  • host (String, default: 127.0.0.1): agent address
  • port (Integer, default: 8500): agent HTTP(S) port
  • secure (Boolean, default: false): enable HTTPS
  • defaults (Object, optional): common method call options that will be included with every call (ex: set default token), these options can be override on a per call basis

Advanced options

  • agent (http.Agent|https.Agent, optionals): if not set uses the global agent
  • baseUrl, headers, tags, socketPath, and timeout (see Papi for details)
  • tls options: ca, cert, ciphers, clientCertEngine, crl, dhparam, ecdhCurve, honorCipherOrder, key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, and sessionIdContext (see Node.js docs for details)

Usage

import Consul from "consul";

const consul = new Consul();

Common Method Call Options

These options can be included with any method call, although only certain endpoints support them. See the HTTP API for more information.

  • dc (String, optional): datacenter (defaults to local for agent)
  • wan (Boolean, default: false): return WAN members instead of LAN members
  • consistent (Boolean, default: false): require strong consistency
  • stale (Boolean, default: false): use whatever is available, can be arbitrarily stale
  • index (String, optional): used with ModifyIndex to block and wait for changes
  • wait (String, optional): limit how long to wait for changes (ex: 5m), used with index
  • token (String, optional): ACL token
  • near (String, optional): used to sort the node list in ascending order based on the estimated round trip time from that node
  • node-meta (String[], optional): used to specify a desired node metadata key/value pair of the form key:value
  • filter (String, optional): used to refine a data query for some API listing endpoints

These options work for all methods.

  • ctx (EventEmitter, optional): emit cancel to abort request
  • timeout (Number|String, optional): number of milliseconds before request is aborted (ex: 1000 or 1s)

consul.acl

consul.acl.bootstrap()

Creates one-time management token if not configured.

Usage

await consul.acl.bootstrap();

Result

{
  "ID": "adf4238a-882b-9ddc-4a9d-5b6758e4159e"
}

consul.acl.replication([options])

Get the status of the ACL replication process in the datacenter.

Usage

await consul.acl.replication();

Result

{
  "Enabled": true,
  "Running": true,
  "SourceDatacenter": "dc1",
  "ReplicatedIndex": 1976,
  "LastSuccess": "2016-08-05T06:28:58Z",
  "LastError": "2016-08-05T06:28:28Z"
}

consul.acl.legacy

consul.acl.legacy.create([options])

Creates a new token with policy.

Options

  • name (String, optional): human readable name for the token
  • type (String, enum: client, management; default: client): type of token
  • rules (String, optional): string encoded HCL or JSON

Usage

await consul.acl.legacy.create();

Result

{
  "ID": "b1f4c10e-b61b-e1de-de95-218c9fefdd3e"
}

consul.acl.legacy.update(options)

Update the policy of a token.

Options

  • id (String): token ID
  • name (String, optional): human readable name for the token
  • type (String, enum: client, management; default: client): type of token
  • rules (String, optional): string encoded HCL or JSON

Usage

await consul.acl.legacy.update({
  id: "63e1d82e-f718-eb92-3b7d-61f0c71d45b4",
  name: "test",
});

consul.acl.legacy.destroy(options)

Destroys a given token.

Options

  • id (String): token ID

Usage

await consul.acl.legacy.destroy("b1f4c10e-b61b-e1de-de95-218c9fefdd3e");

consul.acl.legacy.get(options)

Queries the policy of a given token.

Options

  • id (String): token ID

Usage

await consul.acl.legacy.get("63e1d82e-f718-eb92-3b7d-61f0c71d45b4");

Result

{
  "CreateIndex": 7,
  "ModifyIndex": 7,
  "ID": "63e1d82e-f718-eb92-3b7d-61f0c71d45b4",
  "Name": "Read only",
  "Type": "client",
  "Rules": "{\"key\":{\"\":{\"policy\":\"read\"}}}"
}

consul.acl.legacy.clone(options)

Creates a new token by cloning an existing token.

Options

  • id (String): token ID

Usage

await consul.acl.legacy.clone("63e1d82e-f718-eb92-3b7d-61f0c71d45b4");

Result

{
  "ID": "9fb8b20b-2636-adbb-9b99-d879df3305ec"
}

consul.acl.legacy.list([options])

Lists all the active tokens.

Usage

await consul.acl.legacy.list();

Result

[
  {
    "CreateIndex": 2,
    "ModifyIndex": 2,
    "ID": "anonymous",
    "Name": "Anonymous Token",
    "Type": "client",
    "Rules": ""
  }
  {
    "CreateIndex": 3,
    "ModifyIndex": 3,
    "ID": "root",
    "Name": "Master Token",
    "Type": "management",
    "Rules": ""
  }
]

consul.agent

consul.agent.members([options])

Returns the members as seen by the consul agent.

Options

  • wan (Boolean, default: false): return WAN members instead of LAN members

Usage

await consul.agent.members();

Result

[
  {
    "Name": "node1",
    "Addr": "127.0.0.1",
    "Port": 8301,
    "Tags": {
      "bootstrap": "1",
      "build": "0.3.0:441d613e",
      "dc": "dc1",
      "port": "8300",
      "role": "consul",
      "vsn": "2",
      "vsn_max": "2",
      "vsn_min": "1"
    },
    "Status": 1,
    "ProtocolMin": 1,
    "ProtocolMax": 2,
    "ProtocolCur": 2,
    "DelegateMin": 2,
    "DelegateMax": 4,
    "DelegateCur": 4
  }
]

consul.agent.reload([options])

Reload agent configuration.

Usage

await consul.agent.reload();

consul.agent.self()

Returns the agent node configuration.

Usage

await consul.agent.self();

Result

{
  "Config": {
    "Bootstrap": true,
    "Server": true,
    "Datacenter": "dc1",
    "DataDir": "/tmp/node1/data",
    "DNSRecursor": "",
    "DNSConfig": {
      "NodeTTL": 0,
      "ServiceTTL": null,
      "AllowStale": false,
      "MaxStale": 5000000000
    },
    "Domain": "consul.",
    "LogLevel": "INFO",
    "NodeName": "node1",
    "ClientAddr": "127.0.0.1",
    "BindAddr": "127.0.0.1",
    "AdvertiseAddr": "127.0.0.1",
    "Ports": {
      "DNS": 8600,
      "HTTP": 8500,
      "RPC": 8400,
      "SerfLan": 8301,
      "SerfWan": 8302,
      "Server": 8300
    },
    "LeaveOnTerm": false,
    "SkipLeaveOnInt": false,
    "StatsiteAddr": "",
    "Protocol": 2,
    "EnableDebug": false,
    "VerifyIncoming": false,
    "VerifyOutgoing": false,
    "CAFile": "",
    "CertFile": "",
    "KeyFile": "",
    "ServerName": "",
    "StartJoin": [],
    "UiDir": "",
    "PidFile": "/tmp/node1/pid",
    "EnableSyslog": false,
    "SyslogFacility": "LOCAL0",
    "RejoinAfterLeave": false,
    "CheckUpdateInterval": 300000000000,
    "Revision": "441d613e1bd96254c78c46ee7c1b35c161fc7295+CHANGES",
    "Version": "0.3.0",
    "VersionPrerelease": ""
  },
  "Member": {
    "Name": "node1",
    "Addr": "127.0.0.1",
    "Port": 8301,
    "Tags": {
      "bootstrap": "1",
      "build": "0.3.0:441d613e",
      "dc": "dc1",
      "port": "8300",
      "role": "consul",
      "vsn": "2",
      "vsn_max": "2",
      "vsn_min": "1"
    },
    "Status": 1,
    "ProtocolMin": 1,
    "ProtocolMax": 2,
    "ProtocolCur": 2,
    "DelegateMin": 2,
    "DelegateMax": 4,
    "DelegateCur": 4
  }
}

consul.agent.maintenance(options)

Set node maintenance mode.

Options

  • enable (Boolean): maintenance mode enabled
  • reason (String, optional): human readable reason for maintenance

Usage

await consul.agent.maintenance(true);

consul.agent.join(options)

Trigger agent to join a node.

Options

  • address (String): node IP address to join
  • wan (Boolean, default false): attempt to join using the WAN pool

Usage

await consul.agent.join("127.0.0.2");

consul.agent.forceLeave(options)

Force remove node.

Options

  • node (String): node name to remove

Usage

await consul.agent.forceLeave("node2");

consul.agent.check

consul.agent.check.list()

Returns the checks the agent is managing.

Usage

await consul.agent.check.list();

Result

{
  "example": {
    "Node": "node1",
    "CheckID": "example",
    "Name": "example",
    "Status": "passing",
    "Notes": "This is an example check.",
    "Output": "",
    "ServiceID": "",
    "ServiceName": ""
  }
}

consul.agent.check.register(options)

Registers a new check.

Options

  • name (String): check name
  • id (String, optional): check ID
  • serviceid (String, optional): service ID, associate check with existing service
  • http (String): url to test, 2xx passes, 429 warns, and all others fail
  • tlsskipverify (Boolean, default: false): skip HTTPS verification
  • tcp (String): host:port to test, passes if connection is established, fails otherwise
  • args (String[]): path to check script, requires interval
  • script (String): path to check script, requires interval (DEPRECATED)
  • dockercontainerid (String, optional): Docker container ID to run script
  • grpc (String, optional): gRPC endpoint (ex: 127.0.0.1:12345)
  • grpcusetls (Boolean, optional): enable TLS for gRPC check
  • shell (String, optional): shell in which to run script (currently only supported with Docker)
  • interval (String): interval to run check, requires script (ex: 15s)
  • timeout (String, optional): timeout for the check (ex: 10s)
  • ttl (String): time to live before check must be updated (ex: 60s)
  • aliasnode (String): ID of a node for an alias check (ex: web1)
  • aliasservice (String): ID of a service for an alias check (ex: web)
  • notes (String, optional): human readable description of check
  • status (String, optional): initial service status
  • deregistercriticalserviceafter (String, optional, Consul 0.7+): timeout after which to automatically deregister service if check remains in critical state
  • successbeforepassing (Number, optional): number of consecutive successful results required before check status transitions to passing
  • failuresbeforecritical (Number, optional): number of consecutive unsuccessful results required before check status transitions to critical

Usage

await consul.agent.check.register({
  name: "example",
  ttl: "15s",
  notes: "This is an example check.",
});

consul.agent.check.deregister(options)

Deregister a check.

Options

  • id (String): check ID

Usage

await consul.agent.check.deregister("example");

consul.agent.check.pass(options)

Mark a test as passing.

Options

  • id (String): check ID
  • note (String, optional): human readable message

Usage

await consul.agent.check.pass("example");

consul.agent.check.warn(options)

Mark a test as warning.

Options

  • id (String): check ID
  • note (String, optional): human readable message

Usage

await consul.agent.check.warn("example");

consul.agent.check.fail(options)

Mark a test as critical.

Options

  • id (String): check ID
  • note (String, optional): human readable message

Usage

await consul.agent.check.fail("example");

consul.agent.service

consul.agent.service.list()

Returns the services the agent is managing.

Usage

await consul.agent.service.list();

Result

{
  "example": {
    "ID": "example",
    "Service": "example",
    "Tags": ["dev", "web"],
    "Port": 80
  }
}

consul.agent.service.register(options)

Registers a new service.

Options

  • name (String): service name
  • id (String, optional): service ID
  • tags (String[], optional): service tags
  • address (String, optional): service IP address
  • port (Integer, optional): service port
  • meta (Object, optional): metadata linked to the service instance
  • check (Object, optional): service check
    • http (String): URL endpoint, requires interval
    • tcp (String): host:port to test, passes if connection is established, fails otherwise
    • script (String): path to check script, requires interval
    • dockercontainerid (String, optional): Docker container ID to run script
    • shell (String, optional): shell in which to run script (currently only supported with Docker)
    • interval (String): interval to run check, requires script (ex: 15s)
    • timeout (String, optional): timeout for the check (ex: 10s)
    • ttl (String): time to live before check must be updated, instead of http/tcp/script and interval (ex: 60s)
    • notes (String, optional): human readable description of check
    • status (String, optional): initial service status
    • deregistercriticalserviceafter (String, optional, Consul 0.7+): timeout after which to automatically deregister service if check remains in critical state
  • checks (Object[], optional): service checks (see check above)
  • connect (Object, optional): specifies the configuration for Connect
  • proxy (Object, optional): specifies the configuration for a Connect proxy instance
  • taggedAddresses (Object, optional): specifies a map of explicit LAN and WAN addresses for the service instance

Usage

await consul.agent.service.register("example");

consul.agent.service.deregister(options)

Deregister a service.

Options

  • id (String): service ID

Usage

await consul.agent.service.deregister("example");

consul.agent.service.maintenance(options)

Set service maintenance mode.

Options

  • id (String): service ID
  • enable (Boolean): maintenance mode enabled
  • reason (String, optional): human readable reason for maintenance

Usage

await consul.agent.service.maintenance({ id: "example", enable: true });

consul.catalog

consul.catalog.register(options)

Registers or updates entries in the catalog.

NOTE: this endpoint is a low-level mechanism for registering or updating entries in the catalog. It is usually preferable to instead use the agent endpoints for registration as they are simpler and perform anti-entropy. It is suggested to read the catalog API documentation before using that.

Options

  • id (String, optional): an optional UUID to assign to the node. This must be a 36-character UUID-formatted string
  • node (String, required): specifies the node ID to register
  • address (String, required): specifies the address to register.
  • taggedaddresses (Object, optional): specifies the tagged addresses
  • nodemeta (Object, optional): specifies arbitrary KV metadata pairs for filtering purposes
  • service (Objet, optional): specifies to register a service
    • id (String): service ID. If ID is not provided, it will be defaulted to the value of the Service.Service property. Only one service with a given ID may be present per node.
    • service (String): service name
    • tags (String[], optional): service tags
    • meta (Object, optional): metadata linked to the service instance
    • address (String): service IP address
    • port (Integer): service port
  • check (Object, optional): specifies to register a check.The register API manipulates the health check entry in the Catalog, but it does not setup the TCP/HTTP check to monitor the node's health.
    • node (String): the node id this check will bind to
    • name (String): check name
    • checkid (String): the CheckID can be omitted and will default to the value of Name. The CheckID must be unique on this node.
    • serviceid (String): if a ServiceID is provided that matches the ID of a service on that node, the check is treated as a service level health check, instead of a node level health check.
    • notes (String): notes is an opaque field that is meant to hold human-readable text
    • status (String): initial status. The Status must be one of passing, warning, or critical.
    • definition (Object): health check definition
      • http (String): URL endpoint, requires interval
      • tlsskipverify (Boolean, default: false): skip HTTPS verification
      • tlsservername (String): SNI
      • tcp (String): host:port to test, passes if connection is established, fails otherwise
      • intervalduration (String): interval to run check, requires script (ex: 15s)
      • timeoutduration (String): timeout for the check (ex: 10s)
      • deregistercriticalserviceafterduration (String): timeout after which to automatically deregister service if check remains in critical state (ex: 120s)
  • checks (Object[], optional): multiple checks can be provided by replacing check with checks and sending an array of check objects.
  • skipnodeupdate (Bool, optional): pecifies whether to skip updating the node's information in the registration. Note, if the parameter is enabled for a node that doesn't exist, it will still be created

Usage

await consul.catalog.register("example");

consul.catalog.deregister(options)

Deregister entries in the catalog.

NOTE:This endpoint is a low-level mechanism for directly removing entries from the Catalog. It is usually preferable to instead use the agent endpoints for deregistration as they are simpler and perform anti-entropy. It is suggested to read the catalog API documentation before using that.

Options

  • node (String, required): specifies the ID of the node. If no other values are provided, this node, all its services, and all its checks are removed.
  • checkid (String, optional): specifies the ID of the check to remove.
  • serviceid (String, optional): specifies the ID of the service to remove. The service and all associated checks will be removed.

Usage

await consul.catalog.deregister("example");

or

await consul.catalog.deregister({ id: "example" });

consul.catalog.datacenters()

Lists known datacenters.

Usage

await consul.catalog.datacenters();

Result

["dc1"]

consul.catalog.connect

consul.catalog.connect.nodes(options)

Lists the nodes for a given Connect-capable service.

Options

  • service (String): service name
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.catalog.connect.nodes("example");

Result

[
  {
    "ID": "40e4a748-2192-161a-0510-9bf59fe950b5",
    "Node": "foobar",
    "Address": "192.168.10.10",
    "Datacenter": "dc1",
    "TaggedAddresses": {
      "lan": "192.168.10.10",
      "wan": "10.0.10.10"
    },
    "NodeMeta": {
      "somekey": "somevalue"
    },
    "CreateIndex": 51,
    "ModifyIndex": 51,
    "ServiceAddress": "172.17.0.3",
    "ServiceEnableTagOverride": false,
    "ServiceID": "32a2a47f7992:nodea:5000",
    "ServiceName": "foobar",
    "ServiceKind": "connect-proxy",
    "ServiceProxyDestination": "my-service",
    "ServicePort": 5000,
    "ServiceMeta": {
      "foobar_meta_value": "baz"
    },
    "ServiceTags": ["tacos"]
  }
]

consul.catalog.node

consul.catalog.node.list([options])

Lists nodes in a given datacenter.

Options

  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.catalog.node.list();

Result

[
  {
    "Node": "node1",
    "Address": "127.0.0.1"
  }
]

consul.catalog.node.services(options)

Lists the services provided by a node.

Options

  • node (String): node ID

Usage

await consul.catalog.node.services("node1");

Result

{
  "Node": {
    "Node": "node1",
    "Address": "127.0.0.1"
  },
  "Services": {
    "consul": {
      "ID": "consul",
      "Service": "consul",
      "Tags": [],
      "Port": 8300
    },
    "example": {
      "ID": "example",
      "Service": "example",
      "Tags": ["dev", "web"],
      "Port": 80
    }
  }
}

consul.catalog.service

consul.catalog.service.list([options])

Lists services in a given datacenter.

Options

  • dc (String): datacenter (defaults to local for agent)

Usage

await consul.catalog.service.list();

Result

{
  "consul": [],
  "example": ["dev", "web"]
}

consul.catalog.service.nodes(options)

Lists the nodes for a given service.

Options

  • service (String): service name
  • dc (String, optional): datacenter (defaults to local for agent)
  • tag (String, optional): filter by tag

Usage

await consul.catalog.service.nodes("example");

Result

[
  {
    "Node": "node1",
    "Address": "127.0.0.1",
    "ServiceID": "example",
    "ServiceName": "example",
    "ServiceTags": ["dev", "web"],
    "ServicePort": 80
  }
]

consul.event

consul.event.fire(options)

Fires a new user event.

Options

  • name (String): event name
  • payload (String|Buffer): payload
  • node (String, optional): regular expression to filter by node
  • service (String, optional): regular expression to filter by service
  • tag (String, optional): regular expression to filter by tag

Usage

await consul.event.fire("deploy", "53");

Result

{
  "ID": "4730953b-3135-7ff2-47a7-9d9fc9c4e5a2",
  "Name": "deploy",
  "Payload": "53",
  "NodeFilter": "",
  "ServiceFilter": "",
  "TagFilter": "",
  "Version": 1,
  "LTime": 0
}

consul.event.list([options])

Lists the most recent events an agent has seen.

Options

  • name (String, optional): filter by event name

Usage

await consul.event.list("deploy");

Result

[
  {
    "ID": "4730953b-3135-7ff2-47a7-9d9fc9c4e5a2",
    "Name": "deploy",
    "Payload": "53",
    "NodeFilter": "",
    "ServiceFilter": "",
    "TagFilter": "",
    "Version": 1,
    "LTime": 2
  }
]

consul.health

consul.health.node(options)

Returns the health info of a node.

Options

  • node (String): node
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.health.node("node1");

Result

[
  {
    "Node": "node1",
    "CheckID": "serfHealth",
    "Name": "Serf Health Status",
    "Status": "passing",
    "Notes": "",
    "Output": "Agent alive and reachable",
    "ServiceID": "",
    "ServiceName": ""
  },
  {
    "Node": "node1",
    "CheckID": "service:example",
    "Name": "Service 'example' check",
    "Status": "critical",
    "Notes": "",
    "Output": "",
    "ServiceID": "example",
    "ServiceName": "example"
  }
]

consul.health.checks(options)

Returns the checks of a service.

Options

  • service (String): service name
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.health.checks("example");

Result

[
  {
    "Node": "node1",
    "CheckID": "service:example",
    "Name": "Service 'example' check",
    "Status": "critical",
    "Notes": "",
    "Output": "",
    "ServiceID": "example",
    "ServiceName": "example"
  }
]

consul.health.service(options)

Returns the nodes and health info of a service.

Options

  • service (String): service name
  • dc (String, optional): datacenter (defaults to local for agent)
  • tag (String, optional): filter by tag
  • passing (Boolean, optional): restrict to passing checks

Usage

await consul.health.service("example");

Result

[
  {
    "Node": {
      "Node": "node1",
      "Address": "127.0.0.1"
    },
    "Service": {
      "ID": "example",
      "Service": "example",
      "Tags": [],
      "Port": 0
    },
    "Checks": [
      {
        "Node": "node1",
        "CheckID": "service:example",
        "Name": "Service 'example' check",
        "Status": "critical",
        "Notes": "",
        "Output": "",
        "ServiceID": "example",
        "ServiceName": "example"
      },
      {
        "Node": "node1",
        "CheckID": "serfHealth",
        "Name": "Serf Health Status",
        "Status": "passing",
        "Notes": "",
        "Output": "Agent alive and reachable",
        "ServiceID": "",
        "ServiceName": ""
      }
    ]
  }
]

consul.health.state(options)

Returns the checks in a given state.

Options

  • state (String, enum: any, passing, warning, critical): state
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.health.state("critical");

Result

[
  {
    "Node": "node1",
    "CheckID": "service:example",
    "Name": "Service 'example' check",
    "Status": "critical",
    "Notes": "",
    "Output": "",
    "ServiceID": "example",
    "ServiceName": "example"
  }
]

consul.kv

consul.kv.get(options)

Return key/value (kv) pair(s) or undefined if key not found.

Options

  • key (String): path to value
  • dc (String, optional): datacenter (defaults to local for agent)
  • recurse (Boolean, default: false): return all keys with given key prefix
  • index (String, optional): used with ModifyIndex to block and wait for changes
  • wait (String, optional): limit how long to wait for changes (ex: 5m), used with index
  • raw (Boolean, optional): return raw value (can't be used with recursive, implies buffer)
  • buffer (Boolean, default: false): decode value into Buffer instead of String

Usage

await consul.kv.get("hello");

Result

{
  "CreateIndex": 6,
  "ModifyIndex": 6,
  "LockIndex": 0,
  "Key": "hello",
  "Flags": 0,
  "Value": "world"
}

consul.kv.keys(options)

Return keys for a given prefix.

Options

  • key (String): path prefix
  • dc (String, optional): datacenter (defaults to local for agent)
  • separator (String, optional): list keys up to a given separator

Usage

await consul.kv.keys("a/");

Result

["a/b", "a/c"]

consul.kv.set(options)

Set key/value (kv) pair.

Options

  • key (String): key
  • value (String|Buffer): value
  • dc (String, optional): datacenter (defaults to local for agent)
  • flags (Number, optional): unsigned integer opaque to user, can be used by application
  • cas (String, optional): use with ModifyIndex to do a check-and-set operation
  • acquire (String, optional): session ID, lock acquisition operation
  • release (String, optional): session ID, lock release operation

Usage

await consul.kv.set("hello", "world");

Result

true

consul.kv.del(options)

Delete key/value (kv) pair(s).

Options

  • key (String): key
  • dc (String, optional): datacenter (defaults to local for agent)
  • recurse (Boolean, default: false): delete all keys with given key prefix
  • cas (String, optional): use with ModifyIndex to do a check-and-set operation (must be greater than 0)

Usage

await consul.kv.del("hello");

consul.query

consul.query.list()

List prepared query.

Usage

await consul.query.list();

Result

[
  {
    "ID": "422b14b9-874b-4520-bd2e-e149a42b0066",
    "Name": "redis",
    "Session": "",
    "Token": "",
    "Template": {
      "Type": "",
      "Regexp": ""
    },
    "Service": {
      "Service": "redis",
      "Failover": {
        "NearestN": 3,
        "Datacenters": ["dc1", "dc2"]
      },
      "OnlyPassing": false,
      "Tags": ["master", "!experimental"]
    },
    "DNS": {
      "TTL": "10s"
    },
    "RaftIndex": {
      "CreateIndex": 23,
      "ModifyIndex": 42
    }
  }
]

consul.query.create(options)

Create a new prepared query.

Options

  • name (String, optional): name that can be used to execute a query instead of using its ID
  • session (String, optional): provides a way to automatically remove a prepared query when the given session is invalidated
  • token (String, optional): captured ACL Token that is reused as the ACL Token every time the query is executed
  • near (String, optional): allows specifying a particular node to sort near based on distance sorting using Network Coordinates
  • service.service (String, required): name of the service to query
  • service.failover.nearestn (Number, optional): when set the query will be forwarded to up to nearest N other datacenters based on their estimated network round trip time using Network Coordinates from the WAN gossip pool
  • service.failover.datacenters (String[], optional): fixed list of remote datacenters to forward the query to if there are no healthy nodes in the local datacenter
  • service.onlypassing (Boolean, default: false): filter results to only nodes with a passing state
  • service.tags (String[], optional): list of service tags to filter the query results
  • ttl.dns (String, optional, ex: 10s): controls how the TTL is set when query results are served over DNS

Usage

await consul.query.create({
  name: 'redis',
  service: {
    service: 'redis'
    onlypassing: true
  },
});

Result

{
  "ID": "422b14b9-874b-4520-bd2e-e149a42b0066"
}

consul.query.update(options)

Update existing prepared query.

Options

  • query (String, required): ID of the query

And all [create options][query-create].

Usage

await consul.query.update({
  query: '422b14b9-874b-4520-bd2e-e149a42b0066',
  name: 'redis',
  service: {
    service: 'redis'
    onlypassing: false
  },
});

consul.query.get(options)

Get prepared query.

Options

  • query (String, required): ID of the query

Usage

await consul.query.get("6119cabf-c052-48fe-9f07-711762e52931");

Result

{
  "ID": "6119cabf-c052-48fe-9f07-711762e52931",
  "Name": "redis",
  "Session": "",
  "Token": "",
  "Template": {
    "Type": "",
    "Regexp": ""
  },
  "Service": {
    "Service": "redis",
    "Failover": {
      "NearestN": 3,
      "Datacenters": ["dc1", "dc2"]
    },
    "OnlyPassing": false,
    "Tags": ["master", "!experimental"]
  },
  "DNS": {
    "TTL": "10s"
  },
  "RaftIndex": {
    "CreateIndex": 23,
    "ModifyIndex": 42
  }
}

consul.query.destroy(options)

Delete prepared query.

Options

  • query (String, required): ID of the query

Usage

await consul.query.destroy("422b14b9-874b-4520-bd2e-e149a42b0066");

consul.query.execute(options)

Execute prepared query.

Options

  • query (String, required): ID of the query

Usage

await consul.query.execute("6119cabf-c052-48fe-9f07-711762e52931");

Result

{
  "Service": "redis",
  "Nodes": [
    {
      "Node": {
        "Node": "foobar",
        "Address": "10.1.10.12",
        "TaggedAddresses": {
          "lan": "10.1.10.12",
          "wan": "10.1.10.12"
        }
      },
      "Service": {
        "ID": "redis",
        "Service": "redis",
        "Tags": null,
        "Port": 8000
      },
      "Checks": [
        {
          "Node": "foobar",
          "CheckID": "service:redis",
          "Name": "Service 'redis' check",
          "Status": "passing",
          "Notes": "",
          "Output": "",
          "ServiceID": "redis",
          "ServiceName": "redis"
        },
        {
          "Node": "foobar",
          "CheckID": "serfHealth",
          "Name": "Serf Health Status",
          "Status": "passing",
          "Notes": "",
          "Output": "",
          "ServiceID": "",
          "ServiceName": ""
        }
      ],
      "DNS": {
        "TTL": "10s"
      },
      "Datacenter": "dc3",
      "Failovers": 2
    }
  ]
}

consul.query.explain(options)

Explain prepared query.

Options

  • query (String, required): ID of the query

Usage

await consul.query.explain("422b14b9-874b-4520-bd2e-e149a42b0066");

Result

{
  "Query": {
    "ID": "422b14b9-874b-4520-bd2e-e149a42b0066",
    "Name": "redis",
    "Session": "",
    "Token": "",
    "Template": {
      "Type": "",
      "Regexp": ""
    },
    "Service": {
      "Service": "redis",
      "Failover": {
        "NearestN": 3,
        "Datacenters": ["dc1", "dc2"]
      },
      "OnlyPassing": false,
      "Tags": ["master", "!experimental"]
    },
    "DNS": {
      "TTL": "10s"
    },
    "RaftIndex": {
      "CreateIndex": 23,
      "ModifyIndex": 42
    }
  }
}

consul.session

consul.session.create([options])

Create a new session.

Options

  • dc (String, optional): datacenter (defaults to local for agent)
  • lockdelay (String, range: 1s-60s, default: 15s): the time consul prevents locks held by the session from being acquired after a session has been invalidated
  • name (String, optional): human readable name for the session
  • node (String, optional): node with which to associate session (defaults to connected agent)
  • checks (String[], optional): checks to associate with session
  • behavior (String, enum: release, delete; default: release): controls the behavior when a session is invalidated
  • ttl (String, optional, valid: 10s-86400s): interval session must be renewed

Usage

await consul.session.create();

Result

{
  "ID": "a0f5dc05-84c3-5f5a-1d88-05b875e524e1"
}

consul.session.destroy(options)

Destroy a given session.

Options

  • id (String): session ID
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.session.destroy("a0f5dc05-84c3-5f5a-1d88-05b875e524e1");

consul.session.get(options)

Queries a given session.

Options

  • id (String): session ID
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.session.get("a0f5dc05-84c3-5f5a-1d88-05b875e524e1");

Result

{
  "CreateIndex": 11,
  "ID": "a0f5dc05-84c3-5f5a-1d88-05b875e524e1",
  "Name": "",
  "Node": "node1",
  "Checks": ["serfHealth"],
  "LockDelay": 15000000000
}

consul.session.node(options)

Lists sessions belonging to a node.

Options

  • node (String): node
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.session.node("node1");

Result

[
  {
    "CreateIndex": 13,
    "ID": "a0f5dc05-84c3-5f5a-1d88-05b875e524e1",
    "Name": "",
    "Node": "node1",
    "Checks": ["serfHealth"],
    "LockDelay": 15000000000
  }
]

consul.session.list([options])

Lists all the active sessions.

Options

  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.session.list();

Result

[
  {
    "CreateIndex": 15,
    "ID": "a0f5dc05-84c3-5f5a-1d88-05b875e524e1",
    "Name": "",
    "Node": "node1",
    "Checks": ["serfHealth"],
    "LockDelay": 15000000000
  }
]

consul.session.renew(options)

Renew a given session.

Options

  • id (String): session ID
  • dc (String, optional): datacenter (defaults to local for agent)

Usage

await consul.session.renew("a0f5dc05-84c3-5f5a-1d88-05b875e524e1");

Result

[
  {
    "CreateIndex": 15,
    "ID": "a0f5dc05-84c3-5f5a-1d88-05b875e524e1",
    "Name": "",
    "Node": "node1",
    "Checks": ["serfHealth"],
    "LockDelay": 15000000000,
    "Behavior": "release",
    "TTL": ""
  }
]

consul.status

consul.status.leader()

Returns the current Raft leader.

Usage

await consul.status.leader();

Result

"127.0.0.1:8300"

consul.status.peers()

Returns the current Raft peer set.

Usage

await consul.status.peers();

Result

["127.0.0.1:8300"]

consul.transaction.create(operations)

operations: The body of the request should be a list of operations to perform inside the atomic transaction. Up to 64 operations may be present in a single transaction.

Usage

await consul.transaction.create([
  {
    {
      KV: {
        Verb: 'set',
        Key: 'key1',
        Value: Buffer.from('value1').toString('base64')
      }
    },{
      KV: {
        Verb: 'delete',
        Key: 'key2'
      }
    }
  }
]);

consul.watch(options)

Watch an endpoint for changes.

The watch relies on blocking queries, adding the index and wait parameters as per Consul's documentation

If a blocking query is dropped due to a Consul crash or disconnect, watch will attempt to reinitiate the blocking query with logarithmic backoff.

Upon reconnect, unlike the first call to watch() in which the latest x-consul-index is unknown, the last known x-consul-index will be reused, thus not emitting the change event unless it has been incremented since.

NOTE: If you specify an alternative options.timeout keep in mind that a small random amount of additional wait is added to all requests (wait / 16). The default timeout is currently set to (wait + wait * 0.1), you should use something similar to avoid issues.

Options

  • method (Function): method to watch
  • options (Object): method options
  • backoffFactor (Integer, default: 100): backoff factor in milliseconds to apply between attempts (backoffFactor * (2 ^ retry attempt))
  • backoffMax (Integer, default: 30000): maximum backoff time in milliseconds to wait between attempts
  • maxAttempts (Integer): maximum number of retry attempts to make before giving up

Usage

const watch = consul.watch({
  method: consul.kv.get,
  options: { key: "test" },
  backoffFactor: 1000,
});

watch.on("change", (data, res) => {
  console.log("data:", data);
});

watch.on("error", (err) => {
  console.log("error:", err);
});

setTimeout(() => {
  watch.end();
}, 30 * 1000);

Acceptance Tests

  1. Install Consul into your PATH

    $ brew install consul
  2. Attach required IPs

    $ sudo ifconfig lo0 alias 127.0.0.2 up
    $ sudo ifconfig lo0 alias 127.0.0.3 up
  3. Install client dependencies

    $ npm install
  4. Run tests

    $ npm run acceptance

License

This work is licensed under the MIT License (see the LICENSE file).

Parts of the Documentation were copied from the official Consul website, see the NOTICE file for license information.

node-consul's People

Contributors

abarre avatar agy avatar alexeykhristov avatar alonmiz avatar baranovpavel avatar daviderenger avatar duncanhall avatar francescou avatar gianricod avatar helloyou2012 avatar heycalmdown avatar kanongil avatar lmammino avatar nakshay avatar silas avatar silver83 avatar stanliek avatar tcrall avatar unidy2002 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-consul's Issues

Lock Issues

I had to comment out https://github.com/silas/node-consul/blob/master/lib/lock.js#L307-L315 and https://github.com/silas/node-consul/blob/master/lib/lock.js#L232-L235 to get the lock system to work reliably.

I found that the monitor updates code is broken and the time is always going to fail, so basically after 15 seconds ( the default) it will always release the lock.

I also found that the data.Flags would always fail on subsequent restarts of the application to check the lock.

By commenting out those two portions, the locking systems seems to work reliably for me now.

How to get more than one key at a time?

I am trying to get many keys at the same time. here is my code

consul.kv.set('hello/my/friend', 'world', function(err, result) {
        if (err) throw err;
    });
consul.kv.set('hello/my/friend1', 'world', function(err, result) {
        if (err) throw err;
    });
    consul.kv.get('hello', function(err, result) {
        if (err) throw err;
        console.log("hello",result);
    });

the result of the console.log is 'hello undefined'. I would expect it to be an object with my at the parent object, and friend and friend1 as the keys, and world as the values. instead I get 'undefined'

How can I get this package to return more than one key value pair at a time?

About those PUT verbs...

Hi there,

I noticed you changed HTTP verbs to PUT. Will that break older versions of Consul or is it simply that Consul 1.0.0 has become strict about it where before it ignored the verb?

Only a minor version bump and nothing in the readme... I wonder if blindly upgrading node-consul would've gotten me into trouble or not (FWIW, I'm not using Consul 1.0.0 yet).

Issue with register application in consul

Hi,

I am using consul in node js. My code snippet is below

var consul = require('consul')({'host': config.CONSUL_IP_ADDRESS, 'port': config.CONSUL_PORT})

consul.agent.service.register({'name': config.SERVICE_NAME, 
  'id': config.SERVICE_ID, 'tags': config.TAGS, 
  'address': config.SERVICE_IP, 
  'port': config.SERVICE_PORT}, function (err) {
 if (err) {
    console.log('error in register')
    console.log(err)
   } else {
      console.log('error in success')
      console.log('sucess')
 }
});

I am getting below error:

Failed to load resource: the server responded with a status of 400 (Bad Request)

Kindly help me to resolve this issue

Setting the http-addr option on consul.watch

How can I override the default of 127.0.0.1:8500 as the address of the consul agent on a watch command?

In the Consul cli, there is a -http-addr option, but the below code does not seem to work (I still see the watch attempting to connect to 127.0.0.1:8500)

`
var watch_options = { 'type' : 'services', 'datacenter' : 'ord', 'http-addr' : '100.78.239.21:8500'};
console.log ("Trying to reach agent ", watch_options["http-addr"]);

var watch = consul.watch({ method: consul.catalog.service.list, options: watch_options});

watch.on('change', function (data, res) {
console.log ("BOOM");
console.log('data:', data);
});
`

Global options

In a little spike I have:

consul = require("consul")({
  host: "s-consul-server-01"
})

consul.kv.get {key: "tenant/t1", dc: "production"}, (err, r) ->
  console.log "--- err=", err
  console.log "--- r=", r

This works and returns the kv value.

But when I try to move the dc to the global options:

consul = require("consul")({
  host: "s-consul-server-01"
  dc: "production"
})

consul.kv.get {key: "tenant/t1"}, (err, r) ->
  console.log "--- err=", err
  console.log "--- r=", r

Here the callback is invoked with undefined for both 'err' and 'r'.

From the docs it looks like I should be able to do this. Am I missing something here?

consul.kv.set returning SSL error

When I call consul.kv.set() with the proper params, the function returns the following error:

EPROTO 140735269093376:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:../deps/openssl/openssl/ssl/s23_clnt.c:794

I am running Consul v0.6.4

PreparedQuery and ACL

Function query.create not works in case use ACL.
For example:
const consul = require('consul')({
"host":"127.0.0.1",
"port":8085,
"sequre":false,
"defaults":{
"token":"vagrant"
}
});
consul.query.create({
name: "rabbitmqQuery",
service: {
service: "rabbitmq",
onlypassing: true
}
}).then(....)

Unhandled rejection Error: Permission denied
at create (/var/www/kvartus-parser/node_modules/consul/node_modules/papi/lib/errors.js:14:5)
at Object.response (/var/www/kvartus-parser/node_modules/consul/node_modules/papi/lib/errors.js:38:15)
at IncomingMessage. (/var/www/kvartus-parser/node_modules/consul/node_modules/papi/lib/client.js:593:26)
at emitNone (events.js:72:20)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:923:12)
at nextTickCallbackWith2Args (node.js:511:9)
at process._tickCallback (node.js:425:17)

Using a token on lock

Is it possible to set the 'key' option on a lock operation?

I'm trying to do the equivalent of

consul lock -name='ConsulSync' -pass-stdin -token=$TOKEN service/us/locks/foo child_command

My code is

var lock_options = {  key : 'service/us/locks/foo',
                      name : 'ConsulSync',
                      token : process.env.TOKEN
                   };

var lock = consul.lock(lock_options);

but I'm getting a 403 "rpc error: Permission denied"

Also, can I set 'pass-stdin'?

API consul.kv.get didn't get promisified properly with the option 'promisify: true'

Thanks a lot for this great job.

But it seems the API consul.kv.get didn't get promisified properly with the option 'promisify: true', like below, see the comments:

consul.kv.get(myKey).then((res) => {
  if (res.Value === mySub) {
    return consul.kv.set({
      key: myKey,
      value: myValue,
      cas: res.ModifyIndex
    });
  } else {
    // Here I reject with my custom error, will not reach the 'catch' properly.
    // But if I use bluebird promisify 'consul.kv.get' again, then everything will be fine.
    return bluebird.reject(new Error('My custom Error.'));
  }
}).catch((err) => {
  throw err;
});

watch v1/agent/members

i'm trying to watch changes on node status in order that every time node status change (alive/left .. ) i will get notified

for example: (output of ./consul members)
client6 172.30.110.6:8301 left client 1.0.2 2 dc1 <default>
and
client6 172.30.110.6:8301 alive client 1.0.2 2 dc1 <default>

i'm using the following http request to get the current status
curl http://localhost:8500/v1/agent/members

my watch is

var watch = consul.watch({ method: consul.agent.members});

but nothing triggered when changing client6 status
what i'm doing wrong?

Thanks!

Lock session TTL never gets renewed

I'm implementing the leader election pattern in the Consul docs. I'd like to set the session's TTL to 10s since the health checks are a little slower than I like. I've noticed that when I don't set the TTL field in the options, the leader sticks around for a while. When I do set the TTL, the leader's lock is released periodically and the rate matches the amount of time I set the TTL. I looked through the code and it appears that it should renew the TTL. Unfortunately, it looks like this isn't happening.

deregister service fail!

my consul version is 1.0.0, and node-consul is 0.29.0

here is my code

var consul = require('consul')();
consul.agent.service.deregister('example', (err, result) => {
	console.log(err, result)
})

and output is

{ Error: method GET not allowed
    at create (/home/bob/consul/node_modules/papi/lib/errors.js:14:5)
    at Object.response [as Response] (/home/bob/consul/node_modules/papi/lib/errors.js:38:15)
    at IncomingMessage.<anonymous> (/home/bob/consul/node_modules/papi/lib/client.js:592:26)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:188:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  isPapi: true,
  isResponse: true,
  message: 'method GET not allowed',
  statusCode: 405 } undefined

and code in consul/lib/agent/service.js is

93 AgentService.prototype.deregister = function(opts, callback) {
 94   if (typeof opts === 'string') {
 95     opts = { id: opts };
 96   }
 97 
 98   opts = utils.normalizeKeys(opts);
 99   opts = utils.defaults(opts, this.consul._defaults);
100 
101   var req = {
102     name: 'agent.service.deregister',
103     path: '/agent/service/deregister/{id}',
104     params: { id: opts.id },
105   };
106 
107   if (!opts.id) {
108     return callback(this.consul._err(errors.Validation('id required'), req))    ;
109   }
110 
111   utils.options(req, opts);
112 
113   this.consul._get(req, utils.empty, callback);
114 };

i think put method should be used when deregister service but uses get

`consul.kv.get('string')` fetches more than exact match

Lets say I have to following keys:
foo/bar & foo-test/bar

fetching the keys like so:
consul.kv.get({'key': 'foo', recurse:true}, function(err,kvs,res) {console.log(kvs);});

would fetch both keys. I'm not sure if this is expected or not? one solution on my side would be to append a / to the key name, but again, I'm not sure if this should be solved on the client side.

typo == bug

Hi ! Thanks for your great work !

I've found a simple bug : kv.set {release: session} doesn't work because of
https://github.com/silas/node-consul/blob/master/lib/kv.js#L110

It should read :
if (options.hasOwnProperty('release')) req.query.release = options.release;
instead of :
if (options.hasOwnProperty('release')) req.query.release = options.acrelease;

acrelease was probably a copy/paste typo...

Configurable retry intervals for watch

The retry behavior of node-consul is overly aggressive in a clustered environment.

By the 1500 millisecond mark after a network issue we have already made 4 attempts to reconnect to Consul, per process/cluster worker. This can easily spam a consul daemon if you have a larger cluster. And if you aren't running a slave on localhost, you're really in trouble.

Instead of hard-coding an interval of 100, this should be a parameter with a default.

No lock in use

Sorry to be a pest....

My code is almost working perfectly now - it went through several 'watch' and 'lock' events perfectly - but then it got an error. It looks like a lock.release() caused an error because somehow there was no lock? But the lock.release() is called only within the lock.on('acquire' callback.

/usr/src/app/node_modules/consul/lib/lock.js:110
  if (!self._ctx) throw errors.Validation('no lock in use');
                  ^

Error: no lock in use
    at create (/usr/src/app/node_modules/consul/lib/errors.js:14:5)
    at Object.validation (/usr/src/app/node_modules/consul/lib/errors.js:26:15)
    at Lock.release (/usr/src/app/node_modules/consul/lib/lock.js:110:32)
    at /usr/src/app/src/main/node/agent.js:40:18
    at /usr/src/app/src/main/node/catalog.js:32:5
    at ChildProcess.exithandler (child_process.js:204:7)
    at emitTwo (events.js:87:13)
    at ChildProcess.emit (events.js:172:7)
    at maybeClose (internal/child_process.js:827:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
  var watch = consul.watch({ method: consul.catalog.service.list, options: this.watch_options});

  watch.on('change', function (data, res) {

    that.health.setWatch ("UP");

    var lock = consul.lock(that.lock_options);

    lock.on('acquire', function(){
        that.health.setLock ("UP");
        var catalog = new Catalog(that.health);
        catalog.update(data, function(){
            lock.release();
        });
    });

    lock.on('error', function(err){
        console.log ("ERROR: Consul Lock Error");
        console.log (JSON.stringify(err, null, 4));
        that.health.setLock ("ERROR");
    });

    lock.acquire();
  });

  watch.on('error', function (err) {
    console.log ('ERROR: Consul Watch Error');
    console.log (JSON.stringify(err, null, 4));
    that.health.setWatch ("ERROR");
  });

Consul watcher never emits 'error' event if connection to consul is lost

Hello. I'm using consul client for service discovery. My code looks like:

const consulCli = require('consul');
const Promise = require('bluebird');

const client = consulCli({
  host,
  port,
  promisify: Promise.fromCallback
});

const options = {
  service: 'my-service-name'
};

client
      .watch({
        method: client.catalog.service.nodes,
        options,
        wait: '2m'
      })
      .on('change', (data) => {
        console.log('CHANGE');
      })
      .on('error', (err) => {
        console.log('ERROR');
      });

I run this code locally on my machine and consul is running on remote machine. When network connection is up, changes coming (it logs CHANGE). But when I shutdown my network connection consul client never steps into neither change event, nor in error event.

Such behavior only appear when network disconnect happens after establishing consul client connection (line const client = consulCli({).

Steps 2 reproduce:

  • Connect to consul via consul client library
  • Create watcher via client
  • Wait some time
  • Disconnect from network
  • See result - no error event emitted

Also when I enable connection again consul client never receive nether change nor error event. It looks like it's getting stuck somewhere inside request.

If consul host is already down papi lib throws timeout exception and it's handled well.

UPD: Seems it happens not always. Also specifying defaults with timeout seems resolves this issue (but I think that some timeout should be set by default to value passed in wait + some seconds.

docker interval support

Hi,
In the register service. is there a support for the docker + interval feature of consul?

Thanks,
Ofer

lock kv.get request timeout is too sensitive and causing random request timeout

The default request timeout for a lock kv.get request which is being set is too sensitive for some environments - lockwaittime +1000ms.
This is causing random timeout errors which are emitting 'end' event for the lock.

Changing this to +5000ms seems to fix my issues, so I've opened a PR with a fix to expose the request timeout to the lock() options.

#56

Can't install version 0.22.0

Hi.
I can't install the latest version, as npm says its not exist:

$ npm install [email protected]
npm ERR! Darwin 14.5.0
npm ERR! argv "/usr/local/Cellar/node/5.3.0/bin/node" "/usr/local/bin/npm" "install" "[email protected]"
npm ERR! node v5.3.0
npm ERR! npm  v3.3.12

npm ERR! No compatible version found: [email protected]
npm ERR! Valid install targets:
npm ERR! 0.20.0, 0.19.0, 0.18.1, 0.18.0, 0.17.0, 0.16.0, 0.15.0, 0.14.0, 0.13.0, 0.12.0, 0.11.0, 0.10.0, 0.9.2, 0.9.1, 0.9.0, 0.8.0, 0.7.1, 0.7.0, 0.6.0, 0.5.0, 0.4.2, 0.4.1, 0.4.0, 0.3.0, 0.2.1, 0.1.0
npm ERR!
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/shmuell/Workspace/playground/npm-debug.log

as you can see, the latest version by npm is 0.20.0, although if ill look here you can see that the latest version is published.
BTW, I tried that on node v4.1.2 and on node v5.3.0.

Thanks.

consul.kv.watch callback on invalid keys

Hi,

consider following code:

var consul = require('consul')({host: '192.168.59.103'});

consul.watch({ method: consul.kv.get, options: { key: 'test1' }}).on('change', function (result) {
  console.log('test1:', result);
});

consul.watch({ method: consul.kv.get, options: { key: 'test2' }}).on('change', function (result) {
  console.log('test2:', result);
});
  1. before starting app, KV is empty:

    test1: undefined
    test2: undefined
    
  2. Create test1 entry:

    test1: { CreateIndex: 215,
      ModifyIndex: 215,
      LockIndex: 0,
      Key: 'test1',
      Flags: 0,
      Value: 'va1' }
    test2: undefined
    
  3. Create test2 entry:

    test2: { CreateIndex: 218,
      ModifyIndex: 218,
      LockIndex: 0,
      Key: 'test2',
      Flags: 0,
      Value: 'tes2' }
    
  4. Update test1:

    test1: { CreateIndex: 215,
      ModifyIndex: 219,
      LockIndex: 0,
      Key: 'test1',
      Flags: 0,
      Value: 'va11' }
    
  5. Delete test2:

    test2: undefined
    
  6. Update test1:

    test2: undefined
    test1: { CreateIndex: 215,
      ModifyIndex: 223,
      LockIndex: 0,
      Key: 'test1',
      Flags: 0,
      Value: 'va111' }
    

Question

Why in 2 and 6 callback for test2 get fired? Look like that on every key update every callback for key that doesn't exist get fired. Is it proper behaviour?

Local port exhaustion (ENOBUFS)

The problem is in conflict with the https://github.com/silas/node-papi repository.
The issues occurs when running multiple health checks to consul with a delay.

For health check, use consul.agent.check.pass({id: ...}).
A new http client instance is created for each request against consul, which exhausts local ports and results in a ENOBUFS execption after a while.

Support Consul 1.0.0 HTTP verb breaking changes

The release of Consul ver 1.0.0 has resulted in breaking changes to the allowed verbs for many API endpoints. e.g. agent/service/deregister MUST now be a PUT operation rather than a GET. A complete list of change can be found in the 1.0.0 changelog.
The current client is essentially unusable for the latest version of Consul.

I'd be willing to submit a pull request to fix this if you could provide some guidance on how you would like backwards compatibility to be handled, I can't seem to see any way to know what version of server the client is talking to in order to decide on which verbs to use.

KV Value not a string

Is there a way to get the Value of a key value pair to not be a string? IE: I add a key value pair foo with value 10. It looks like the client will receive the value "10". I'm going down the path of using a Joi schema for all of our Key value pairs but I wanted to double check there isn't something built in already with consul and node-consul.

combine efforts?

I somehow didn't see this module on npm before I started working on my own... which are quite similar actually! Do you think you will keep working on this module? If so, I think I'll just drop mine off the face of the earth and send you a bunch of PRs.

https://github.com/gjohnson/consul-node

consul.watch + consul.event.list seems to be broken

This does not seem to work very consistently.

While using consul watch -type event echo "event" first every time an even is received, doing the same with node-consul results in inconsistent behavior.

Sometimes the change event will fire, other times it will not, if I manually trigger 10 events, generally node-consul will fire change on the first, and then it could do it on the next or after I've fired 10 events and then change will be fired and contain all the events I triggered.

Acceptance tests fail with Consul 0.6

8 acceptance tests fail when moving from Consul 0.5.x to 0.6.x due to extra keys. For example:

  8) Session renew should renew session:
     Uncaught AssertionError: expected Object {
  Behavior: 'release',
  Checks: Array [ 'serfHealth' ],
  CreateIndex: 21,
  ID: 'f40db325-912a-07d2-e2fc-f0f190ece90b',
  LockDelay: 15000000000,
  ModifyIndex: 21,
  Name: '',
  Node: 'node1',
  TTL: ''
} to have keys CreateIndex, ID, Name, Node, Checks, LockDelay, Behavior, TTL
    extra keys: ModifyIndex

Service event handling

I maybe misinterpreting something, but how would a registered service listen/handle an event that was fired?

consul.watch doesn't work with consul.event.list

I've been toying with this all afternoon, and the only conclusion I can come to is that this doesn't work. The X-Consul-Index header is a number larger than parseInt supports (for instance, I'm seeing 2728514738556540332 and 16053482842036918036 and such as indexes), which causes Watch.prototype._run to spam the consul server with requests similar to:

    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (35.285µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (27.953µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (30.412µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (33.294µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (29.642µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (33.401µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (31.815µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (36.465µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (32.218µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (29.328µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (42.818µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (31.697µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (33.518µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (29.718µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (30.11µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (34.945µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (32.085µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (41.429µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (38.103µs)
    2015/12/04 14:30:34 [DEBUG] http: Request /v1/event/list?index=996658596045402018&wait=30s (35.314µs)

Eventually it seems that the watch gives up on that particular run and stops making requests. I don't know if this is supposed to be supported, but it would be nice if it was supported. For the moment, I'm going to write my own watch logic.

Register multiple checks with service

Consul 0.5.0 supports a new (poorly documented) Checks field, which can be used to associate multiple checks with a service at registration. The new field is an array, with each element a check. See hashicorp/consul#591 for full implementation details.

Can you expose this in the consul.agent.service.register() call?

Unable to get keys from consul server

I'm unable to get information from my consul server.. here is what I'm doing

var CONSUL_HOST, consul, opts;

CONSUL_HOST = "myconsulserver.com";

opts = {
  host: CONSUL_HOST,
  secure: false
};

consul = require('consul')(opts);

consul.kv.get("/code/deploy/sha", function(err, data) {
  console.log(err);
  return console.log(data);
});

I get an error like this:

{ [Error: consul: kv.get: moved permanently]
  isPapi: true,
  isResponse: true,
  message: 'consul: kv.get: moved permanently' }

consul.kv.keys returns always undefined when an error-handling function is passed

Using version 0.31.0

My method:

async keys(path: string): Promise<string[]> {
    const data = await this.consul.kv.keys(path);
    return data;
}

works fine. However if the path does not exist, a 500 error will be thrown, crashing the application.

If I pass an error handling function:

async keys(path: string): Promise<string[]> {
    const data = await this.consul.kv.keys(path, function(e) {
      console.log(e);
    });
    return data ? data : [];
}

then calling it with a non-existing path will not make the application crash, because the error will be properly handled. However this will make all calls always returning undefined (even with existing paths).

Allow for promises

It would be awesome if this module provided support for promises. Right now, we're wrapping our calls in Bluebird but with ES6 gaining ground, it would be nice to follow the standard.

Won't initialize with default params

node-consul won't initialize with default params

var consul = require('consul')();
node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: Expecting a function in instanceof check, but got http://127.0.0.1:8500/v1
    at Consul.Client (/vagrant/web/node_modules/consul/node_modules/papi/lib/client.js:44:36)
    at new Consul (/vagrant/web/node_modules/consul/lib/consul.js:43:15)
    at Consul (/vagrant/web/node_modules/consul/lib/consul.js:30:12)
    at Object.<anonymous> (/vagrant/web/index.js:7:9)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:32)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:41)

The papi library is now checking the baseUrl to make sure its an instance of url.Url. node-consul is creating a baseUrl string. Which fails on the test.

Consul.health.service() functionality does not match documentation

According to the README, consul.health.service() works as follows:

consul.health.service(options, callback)

Returns the nodes and health info of a service.

Options

  • service (String): service ID
  • dc (String, optional): datacenter (defaults to local for agent)
  • tag (String, optional): filter by tag
  • passing (Boolean, optional): restrict to passing checks

Usage

consul.health.service('example', function(err, result) {
 if (err) throw err;
});

Result

[
 {
   "Node": {
     "Node": "node1",
     "Address": "127.0.0.1"
   },
   "Service": {
     "ID": "example",
     "Service": "example",
     "Tags": [],
     "Port": 0
   },
   "Checks": [
     {
       "Node": "node1",
       "CheckID": "service:example",
       "Name": "Service 'example' check",
       "Status": "critical",
       "Notes": "",
       "Output": "",
       "ServiceID": "example",
       "ServiceName": "example"
     },
     {
       "Node": "node1",
       "CheckID": "serfHealth",
       "Name": "Serf Health Status",
       "Status": "passing",
       "Notes": "",
       "Output": "Agent alive and reachable",
       "ServiceID": "",
       "ServiceName": ""
     }
   ]
 }
]

However, according to the Consul documentation for the API command it uses, the parameter used isn't actually serviceID, it's name:

/v1/health/service/

This endpoint is hit with a GET and returns the nodes providing the service indicated on the path. By default, the datacenter of the agent is queried; however, the dc can be provided using the "?dc=" query parameter.

By default, all nodes matching the service are returned. The list can be filtered by tag using the "?tag=" query parameter.

Providing the "?passing" query parameter, added in Consul 0.2, will filter results to only nodes with all checks in the passing state. This can be used to avoid extra filtering logic on the client side.

This endpoint is very similar to the /v1/catalog/service endpoint; however, this endpoint automatically returns the status of the associated health check as well as any system level health checks. This allows a client to avoid sending traffic to nodes that are failing health tests or reporting warnings.

Users can also build in support for dynamic load balancing and other features by incorporating the use of health checks.

It returns a JSON body like this:

[
 {
   "Node": {
     "Node": "foobar",
     "Address": "10.1.10.12"
   },
   "Service": {
     "ID": "redis",
     "Service": "redis",
     "Tags": null,
     "Port": 8000
   },
   "Checks": [
     {
       "Node": "foobar",
       "CheckID": "service:redis",
       "Name": "Service 'redis' check",
       "Status": "passing",
       "Notes": "",
       "Output": "",
       "ServiceID": "redis",
       "ServiceName": "redis"
     },
     {
       "Node": "foobar",
       "CheckID": "serfHealth",
       "Name": "Serf Health Status",
       "Status": "passing",
       "Notes": "",
       "Output": "",
       "ServiceID": "",
       "ServiceName": ""
     }
   ]
 }
]

This endpoint supports blocking queries and all consistency modes.

Note the line

This endpoint is hit with a GET and returns the nodes providing the service indicated on the path.

This caused a few minutes of confusion as I was trying to use consul.health.service() to test the health of a specific instance of a service by id. The documentation here says that is what it does, but the documentation for Consul says that it returns the health of all instances of the service by service name.

catalog.list.service vs catalog.list.services

It seems that the API is missing getting a status on a specific service.
It also seems the the correct api should be catalog.list.service.
Currently this api is providing list of all services which should be a different api call... (catalog.list.services)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.