From fd9207d4528cd0a582ac20e5b45f5c94f9c3963e Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Fri, 14 Sep 2018 18:06:30 +0200 Subject: [PATCH 01/15] Update Consul version to v1.2.3 --- versions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.yaml b/versions.yaml index 123bd5584..1a2e0a7cc 100644 --- a/versions.yaml +++ b/versions.yaml @@ -1,4 +1,4 @@ yorc_version: 3.1.0-SNAPSHOT -consul_version: 1.0.6 +consul_version: 1.2.3 terraform_version: 0.9.11 ansible_version: 2.6.3 From d627a87dc43c3a9bbd003b272b48862833902110 Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Tue, 18 Sep 2018 12:05:14 +0200 Subject: [PATCH 02/15] Register HTTP service into Consul for Yorc --- helper/consulutil/service.go | 29 ++++++++++++++++++++++++----- rest/health.go | 22 ++++++++++++++++++++++ rest/http.go | 1 + rest/http_api.md | 22 ++++++++++++++++++++++ rest/structs.go | 5 +++++ 5 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 rest/health.go diff --git a/helper/consulutil/service.go b/helper/consulutil/service.go index 191d991d5..ad35c0cf9 100644 --- a/helper/consulutil/service.go +++ b/helper/consulutil/service.go @@ -16,6 +16,7 @@ package consulutil import ( "fmt" + "github.com/hashicorp/consul/api" "github.com/ystia/yorc/config" "github.com/ystia/yorc/log" @@ -27,17 +28,35 @@ const YorcService = "yorc" // RegisterServerAsConsulService allows to register the Yorc server as a Consul service func RegisterServerAsConsulService(cfg config.Configuration, cc *api.Client, chShutdown chan struct{}) error { log.Printf("Register Yorc as Consul Service for node %q", cfg.ServerID) - service := &api.AgentServiceRegistration{ + var service *api.AgentServiceRegistration + + var sslEnabled bool + sslEnabled = ((&cfg.KeyFile != nil) && len(cfg.KeyFile) != 0) || ((&cfg.CertFile != nil) && len(cfg.CertFile) != 0) + + var httpString string + if sslEnabled { + httpString = fmt.Sprintf("https://localhost:%d/health", cfg.HTTPPort) + log.Debugf("Register Yorc service with HTTPS check: %s", httpString) + } else { + httpString = fmt.Sprintf("http://localhost:%d/health", cfg.HTTPPort) + log.Debugf("Register Yorc service with HTTP check: %s", httpString) + } + + service = &api.AgentServiceRegistration{ Name: YorcService, Tags: []string{"server", cfg.ServerID}, Port: cfg.HTTPPort, Check: &api.AgentServiceCheck{ - Name: "TCP check on yorc port", - Interval: "5s", - TCP: fmt.Sprintf("localhost:%d", cfg.HTTPPort), - Status: api.HealthPassing, + Name: "HTTP check on yorc port", + Interval: "5s", + HTTP: httpString, + Method: "GET", + TLSSkipVerify: false, + Header: map[string][]string{"Accept": []string{"application/json"}}, + Status: api.HealthPassing, }, } + go func() { for { select { diff --git a/rest/health.go b/rest/health.go new file mode 100644 index 000000000..8421c9645 --- /dev/null +++ b/rest/health.go @@ -0,0 +1,22 @@ +// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// 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. + +package rest + +import "net/http" + +func (s *Server) getHealthHandler(w http.ResponseWriter, r *http.Request) { + health := Health{"passing"} + encodeJSONResponse(w, r, health) +} diff --git a/rest/http.go b/rest/http.go index 65818b90b..b73820b65 100644 --- a/rest/http.go +++ b/rest/http.go @@ -142,6 +142,7 @@ func NewServer(configuration config.Configuration, client *api.Client, shutdownC func (s *Server) registerHandlers() { commonHandlers := alice.New(telemetryHandler, loggingHandler, recoverHandler) + s.router.Get("/health", commonHandlers.Append(acceptHandler("application/json")).ThenFunc(s.getHealthHandler)) s.router.Post("/deployments", commonHandlers.Append(contentTypeHandler("application/zip")).ThenFunc(s.newDeploymentHandler)) s.router.Put("/deployments/:id", commonHandlers.Append(contentTypeHandler("application/zip")).ThenFunc(s.newDeploymentHandler)) s.router.Delete("/deployments/:id", commonHandlers.ThenFunc(s.deleteDeploymentHandler)) diff --git a/rest/http_api.md b/rest/http_api.md index 34e5eda54..596e7d090 100644 --- a/rest/http_api.md +++ b/rest/http_api.md @@ -690,6 +690,28 @@ Content-Type: application/json } } ``` +## Health + +### Get the Yorc service health + +This request si made by Consul to check the Yorc service is alive + +'Accept' header should be set to 'application/json'. + +`GET /health` + +**Response**: + +```HTTP +HTTP/1.1 200 Created +Content-Type: application/json +``` + +```json +{ + "value": "passing" +} +``` ## Registry diff --git a/rest/structs.go b/rest/structs.go index b83be2b88..3c772df73 100644 --- a/rest/structs.go +++ b/rest/structs.go @@ -73,6 +73,11 @@ func newAtomLink(rel, href string) AtomLink { return AtomLink{Rel: rel, Href: href, LinkType: "application/json"} } +// Health of a Yorc instance +type Health struct { + Value string `json:"value"` +} + // Deployment is the representation of a Yorc deployment // // Deployment's links may be of type LinkRelSelf, LinkRelNode, LinkRelTask, LinkRelOutput. From 6f0cf20deabedb7fda1b87a25c27e885bf25e71f Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Tue, 18 Sep 2018 16:06:30 +0200 Subject: [PATCH 03/15] Update security setup for consul agents using HTTP checks --- doc/secured.rst | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/secured.rst b/doc/secured.rst index 393cebdc0..71ddf90a6 100644 --- a/doc/secured.rst +++ b/doc/secured.rst @@ -108,7 +108,7 @@ Bellow is an example of configuration file with TLS enabled and using the colloc "ca_cert": "{PATH_TO_CA_PEM}", "key_file": "{PATH_TO_CONSUL_CLIENT_KEY}", "cert_file": "{PATH_TO_CONSUL_CLIENT_PEM}", - "address": "127.0.0.1:8543", + "address": "127.0.0.1:8543" }, "resources_prefix": "yorc1-", "key_file": "{PATH_TO_YORC_SERVER_KEY}", @@ -126,6 +126,30 @@ Bellow is an example of configuration file with TLS enabled and using the colloc } } +If you enable SSL verification for Yorc (ssl_verify set to true), the Consul Agent must be enabled to use TLS configuration files for HTTP health checks. Otherwise, the TLS handshake may fail. +You can find below the Consul agent's configuration: + +.. code-block:: json + + { + "domain": "starlings", + "data_dir": "/tmp/work", + "client_addr": "0.0.0.0", + "advertise_addr": "{IP}", + "ui": true, + "retry_join": [ "{SERVER_IP}" ], + "encrypt": "{ENCRYPT_KEY}", + "ports": { + "https": 8543 + }, + "key_file": "{PATH_TO_CONSUL_CLIENT_KEY}", + "cert_file": "{PATH_TO_CONSUL_CLIENT_PEM}", + "ca_file": "{PATH_TO_CA_PEM}", + "enable_agent_tls_for_checks": true, + "verify_incoming_rpc": true, + "verify_outgoing": true + } + As for Consul, you may need to install CA certificate in the OS, in case you get errors about trusting the signing authority. Secured Yorc CLI Setup From 745de1a5bb7c64454fe426eff4e2810fd2c87057 Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Wed, 19 Sep 2018 15:30:29 +0200 Subject: [PATCH 04/15] Use updated docker image containing consul verion 1.2.3 --- pkg/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/Dockerfile b/pkg/Dockerfile index 267042981..c26729191 100644 --- a/pkg/Dockerfile +++ b/pkg/Dockerfile @@ -1,4 +1,4 @@ -FROM laurentg/alpine-consul:1.0.4_consul-1.0.6 +FROM ystia/alpine-consul:1.0.4_consul-1.2.3 ARG TERRAFORM_VERSION ARG ANSIBLE_VERSION # Update terraform default when possible From 3c2e4ffe050c65794b1ceeae4a1530375e791cc4 Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 11:10:31 +0200 Subject: [PATCH 05/15] improvements on doc security section --- doc/secured.rst | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/doc/secured.rst b/doc/secured.rst index 71ddf90a6..51b735816 100644 --- a/doc/secured.rst +++ b/doc/secured.rst @@ -4,8 +4,10 @@ Run Yorc in Secured mode To run Yorc in secured mode, the following issues have to be addressed: * Setup a secured Consul cluster -* Setup a secured Yorc server and configure it to use a secured Consul client -* Setup Alien4Cloud security and configure it to use the secured Yorc server +* Setup a secured Yorc server and configure it to use a secured Consul client. +* Setup Alien4Cloud security and configure it to use a secured Yorc server + +In the case of Yorc HA setup (see :ref:`ha`), all the Yorc servers composing the cluster need to be secured. To secure the components listed above, and enable TLS, Multi-Domain (SAN) certificates need to be generated. A short list of commands based on openSSL is provided below. @@ -22,9 +24,10 @@ You might already have one, otherwise, create it using OpenSSL commands below: Generate certificates signed by your CA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You need to generate certificates for all the software component to be secured (Consul, Yorc, Alien4Cloud). +You need to generate certificates for all the software component to be secured (Consul agents, Yorc servers, Alien4Cloud). -Use the commands below for each component instance (where represents host's IP address used to connect to): +Use the commands below for each component instance (where represents IP address used to connect to the component). +Replace ``comp`` by a string of your choise for each of the components to be secured. .. code-block:: bash @@ -36,26 +39,26 @@ In the sections below, the ``comp.key`` and ``comp.pem`` files are used to defin Secured Consul cluster Setup ---------------------------- -Create a ``consul.key`` and ``consul.pem`` for all the Consul agents within the Consul cluster you setup: +.. note:: You need to generate cerificates for all the Consul agents within the Consul cluster you setup. - * the server (you may need 3 servers for HA), - * and the client (you need one client on each host where a Yorc server is running). +Use the above commands to create the ``comp.key`` and a ``comp.pem`` files, and replace by the host's IP address. -Use the above commands and replace and by the host's IP address. +In a High Availability cluster, you need to setup at least 3 consul servers, and one consul client on each host where a Yorc server is running. Check Consul documentation for details about `agent's configuration `_ and `network traffic encryption `_. -You may find below a typical configuration file for a consul server: +You may find below a typical configuration file for a consul server. Start by creating a ``consul_server.key`` and ``consul_server.pem`` using the above commands. .. code-block:: json { - "domain": "starlings", + "domain": "yorc", "data_dir": "/tmp/work", "client_addr": "0.0.0.0", "advertise_addr": "{SERVER_IP}", "server": true, "bootstrap": true, + "ui": true, "encrypt": "{ENCRYPT_KEY}", "ports": { "https": 8543 @@ -67,16 +70,15 @@ You may find below a typical configuration file for a consul server: "verify_outgoing": true } -And below, one for a consul client. +And below, a typical configuration file for a consul client. Start by creating a ``consul_client.key`` and ``consul_client.pem``. .. code-block:: json { - "domain": "starlings", + "domain": "yorc", "data_dir": "/tmp/work", "client_addr": "0.0.0.0", "advertise_addr": "{IP}", - "ui": true, "retry_join": [ "{SERVER_IP}" ], "encrypt": "{ENCRYPT_KEY}", "ports": { @@ -89,14 +91,13 @@ And below, one for a consul client. "verify_outgoing": true } - You can also consult this `Blog `_. You may found useful information about how to install CA certificate in the OS, in case you get errors about trusting the signing authority. Secured Yorc Setup ------------------ -Create a ``yorc-server.key`` and ``yorc-server.pem`` using the above commands and replace by the host's IP address. +Create a ``yorc_server.key`` and ``yorc_server.pem`` using the above commands and replace by the host's IP address. Bellow is an example of configuration file with TLS enabled and using the collocated and secured Consul client. @@ -126,13 +127,13 @@ Bellow is an example of configuration file with TLS enabled and using the colloc } } -If you enable SSL verification for Yorc (ssl_verify set to true), the Consul Agent must be enabled to use TLS configuration files for HTTP health checks. Otherwise, the TLS handshake may fail. +In the above example SSL verification is enabled for Yorc (ssl_verify set to true). In this case, the Consul Agent must be enabled to use TLS configuration files for HTTP health checks. Otherwise, the TLS handshake may fail. You can find below the Consul agent's configuration: .. code-block:: json { - "domain": "starlings", + "domain": "yorc", "data_dir": "/tmp/work", "client_addr": "0.0.0.0", "advertise_addr": "{IP}", @@ -155,9 +156,9 @@ As for Consul, you may need to install CA certificate in the OS, in case you get Secured Yorc CLI Setup ---------------------- -If ``ssl_verify`` is enabled for Yorc server the Yorc CLI have to provide a client certificate signed by the Yorc's Certificate Authority. +If ``ssl_verify`` is enabled for Yorc server, the Yorc CLI have to provide a client certificate signed by the Yorc's Certificate Authority. -So, create a ``yorc-client.key`` and ``yorc-client.pem`` using the above commands and replace by the host's IP address. +So, create a ``yorc_client.key`` and ``yorc_client.pem`` using the above commands and replace by the host's IP address. Bellow is an example of configuration file with TLS enabled. Refer to :ref:`yorc_config_client_section` for more information. From 336d3a8201ea82c96292fb70c7c075e6bb35af9f Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 11:47:17 +0200 Subject: [PATCH 06/15] more doc improvements --- doc/ha.rst | 1 + doc/secured.rst | 18 +++++++----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/doc/ha.rst b/doc/ha.rst index 3136223dc..47eb807de 100644 --- a/doc/ha.rst +++ b/doc/ha.rst @@ -1,6 +1,7 @@ Run Yorc in High Availability (HA) mode ======================================= +.. _yorc_ha: High level view of a typical HA installation -------------------------------------------- diff --git a/doc/secured.rst b/doc/secured.rst index 51b735816..7dcf61e51 100644 --- a/doc/secured.rst +++ b/doc/secured.rst @@ -4,10 +4,10 @@ Run Yorc in Secured mode To run Yorc in secured mode, the following issues have to be addressed: * Setup a secured Consul cluster -* Setup a secured Yorc server and configure it to use a secured Consul client. +* Setup a secured Yorc server and configure it to use a secured Consul client * Setup Alien4Cloud security and configure it to use a secured Yorc server -In the case of Yorc HA setup (see :ref:`ha`), all the Yorc servers composing the cluster need to be secured. +In the case of Yorc HA setup (see :ref:`yorc_ha`), all the Yorc servers composing the cluster need to be secured. To secure the components listed above, and enable TLS, Multi-Domain (SAN) certificates need to be generated. A short list of commands based on openSSL is provided below. @@ -27,7 +27,7 @@ Generate certificates signed by your CA You need to generate certificates for all the software component to be secured (Consul agents, Yorc servers, Alien4Cloud). Use the commands below for each component instance (where represents IP address used to connect to the component). -Replace ``comp`` by a string of your choise for each of the components to be secured. +Replace ``comp`` by a string of your choise corresponding to the components to be secured. .. code-block:: bash @@ -35,19 +35,17 @@ Replace ``comp`` by a string of your choise for each of the components to be sec openssl req -new -sha256 -key comp.key -subj "/C=FR/O=Atos/CN=127.0.0.1" -reqexts SAN -config <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=IP:127.0.0.1,IP:,DNS:localhost")) -out comp.csr openssl x509 -req -in comp.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out comp.pem -days 2048 -extensions SAN -extfile <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=IP:127.0.0.1,IP:,DNS:localhost")) -In the sections below, the ``comp.key`` and ``comp.pem`` files are used to define the different components' configuration. +In the sections below, the ``comp.key`` and ``comp.pem`` files path are used in the components' configuration file. Secured Consul cluster Setup ---------------------------- .. note:: You need to generate cerificates for all the Consul agents within the Consul cluster you setup. -Use the above commands to create the ``comp.key`` and a ``comp.pem`` files, and replace by the host's IP address. - In a High Availability cluster, you need to setup at least 3 consul servers, and one consul client on each host where a Yorc server is running. Check Consul documentation for details about `agent's configuration `_ and `network traffic encryption `_. -You may find below a typical configuration file for a consul server. Start by creating a ``consul_server.key`` and ``consul_server.pem`` using the above commands. +You may find below a typical configuration file for a consul server ; to be updated after having generated the ``consul_server.key`` and ``consul_server.pem`` files. .. code-block:: json @@ -59,7 +57,6 @@ You may find below a typical configuration file for a consul server. Start by cr "server": true, "bootstrap": true, "ui": true, - "encrypt": "{ENCRYPT_KEY}", "ports": { "https": 8543 }, @@ -70,7 +67,7 @@ You may find below a typical configuration file for a consul server. Start by cr "verify_outgoing": true } -And below, a typical configuration file for a consul client. Start by creating a ``consul_client.key`` and ``consul_client.pem``. +And below, a typical configuration file for a consul client. .. code-block:: json @@ -80,7 +77,6 @@ And below, a typical configuration file for a consul client. Start by creating a "client_addr": "0.0.0.0", "advertise_addr": "{IP}", "retry_join": [ "{SERVER_IP}" ], - "encrypt": "{ENCRYPT_KEY}", "ports": { "https": 8543 }, @@ -97,7 +93,7 @@ You may found useful information about how to install CA certificate in the OS, Secured Yorc Setup ------------------ -Create a ``yorc_server.key`` and ``yorc_server.pem`` using the above commands and replace by the host's IP address. +Generate a ``yorc_server.key`` and ``yorc_server.pem`` using the above commands and replace by the host's IP address. Bellow is an example of configuration file with TLS enabled and using the collocated and secured Consul client. From a91f851dbdc09d26005670c4fd8833a943ef2ad0 Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 11:57:08 +0200 Subject: [PATCH 07/15] try to fix links in the doc --- doc/ha.rst | 3 ++- doc/secured.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/ha.rst b/doc/ha.rst index 47eb807de..2565ae372 100644 --- a/doc/ha.rst +++ b/doc/ha.rst @@ -1,7 +1,8 @@ Run Yorc in High Availability (HA) mode ======================================= -.. _yorc_ha: +.. _yorc_ha_section: + High level view of a typical HA installation -------------------------------------------- diff --git a/doc/secured.rst b/doc/secured.rst index 7dcf61e51..3b1f91b20 100644 --- a/doc/secured.rst +++ b/doc/secured.rst @@ -7,7 +7,7 @@ To run Yorc in secured mode, the following issues have to be addressed: * Setup a secured Yorc server and configure it to use a secured Consul client * Setup Alien4Cloud security and configure it to use a secured Yorc server -In the case of Yorc HA setup (see :ref:`yorc_ha`), all the Yorc servers composing the cluster need to be secured. +In the case of Yorc HA setup (see :ref:`yorc_ha_section`), all the Yorc servers composing the cluster need to be secured. To secure the components listed above, and enable TLS, Multi-Domain (SAN) certificates need to be generated. A short list of commands based on openSSL is provided below. From e98b90edb6717559f83a046c49f9623edffb97f9 Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 12:10:53 +0200 Subject: [PATCH 08/15] update changelog.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7e34c93a..875ed955c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### DEPENDENCIES * The orchestrator requires now at least Terraform 0.11.8 and following Terraform plugins (with corresponding version constraints): `Consul (~> 2.1)`, `AWS (~> 1.36)`, `OpenStack (~> 1.9)`, `Google (~ 1.18)` and `null provider (~ 1.0)`. (Terraform upgrade from 0.9.11 introduced in [GH-82](https://github.com/ystia/yorc/issues/82)) +* Consul version updated to 1.2.3 ### IMPROVEMENTS @@ -13,7 +14,8 @@ ### BUG FIXES -* inputs are not injected into Slurm (srun) jobs ([GH-161](https://github.com/ystia/yorc/issues/161)) +* Inputs are not injected into Slurm (srun) jobs ([GH-161](https://github.com/ystia/yorc/issues/161)) +* Yorc consul service registration fails if using TLS ([GH-153](https://github.com/ystia/yorc/issues/153)) ## 3.1.0-M3 (September 14, 2018) From 85fcb083b9241b465e04bb81673e30bd8a8b3e0a Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 13:44:05 +0200 Subject: [PATCH 09/15] udate vendor folder after fetching packages for consul version 1.2.3 --- vendor/github.com/hashicorp/consul/NOTICE.md | 3 + .../github.com/hashicorp/consul/api/README.md | 60 ++-- vendor/github.com/hashicorp/consul/api/acl.go | 2 +- .../github.com/hashicorp/consul/api/agent.go | 189 ++++++++++- vendor/github.com/hashicorp/consul/api/api.go | 62 +++- .../hashicorp/consul/api/catalog.go | 22 +- .../hashicorp/consul/api/connect.go | 12 + .../hashicorp/consul/api/connect_ca.go | 172 ++++++++++ .../hashicorp/consul/api/connect_intention.go | 302 ++++++++++++++++++ .../github.com/hashicorp/consul/api/health.go | 19 +- .../github.com/hashicorp/consul/api/lock.go | 5 +- .../hashicorp/consul/api/operator_area.go | 3 +- .../hashicorp/consul/api/prepared_query.go | 16 +- .../hashicorp/consul/api/semaphore.go | 5 +- .../hashicorp/consul/testutil/server.go | 31 +- vendor/vendor.json | 36 +-- 16 files changed, 872 insertions(+), 67 deletions(-) create mode 100644 vendor/github.com/hashicorp/consul/NOTICE.md create mode 100644 vendor/github.com/hashicorp/consul/api/connect.go create mode 100644 vendor/github.com/hashicorp/consul/api/connect_ca.go create mode 100644 vendor/github.com/hashicorp/consul/api/connect_intention.go diff --git a/vendor/github.com/hashicorp/consul/NOTICE.md b/vendor/github.com/hashicorp/consul/NOTICE.md new file mode 100644 index 000000000..fe34b5e57 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/NOTICE.md @@ -0,0 +1,3 @@ +Copyright © 2014-2018 HashiCorp, Inc. + +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 project, you can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/vendor/github.com/hashicorp/consul/api/README.md b/vendor/github.com/hashicorp/consul/api/README.md index 7e64988f4..3255cbb24 100644 --- a/vendor/github.com/hashicorp/consul/api/README.md +++ b/vendor/github.com/hashicorp/consul/api/README.md @@ -17,27 +17,51 @@ Usage Below is an example of using the Consul client: ```go -// Get a new client -client, err := api.NewClient(api.DefaultConfig()) -if err != nil { - panic(err) -} +package main -// Get a handle to the KV API -kv := client.KV() +import "github.com/hashicorp/consul/api" +import "fmt" -// PUT a new KV pair -p := &api.KVPair{Key: "foo", Value: []byte("test")} -_, err = kv.Put(p, nil) -if err != nil { - panic(err) -} +func main() { + // Get a new client + client, err := api.NewClient(api.DefaultConfig()) + if err != nil { + panic(err) + } + + // Get a handle to the KV API + kv := client.KV() -// Lookup the pair -pair, _, err := kv.Get("foo", nil) -if err != nil { - panic(err) + // PUT a new KV pair + p := &api.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) } -fmt.Printf("KV: %v", pair) +``` + +To run this example, start a Consul server: +```bash +consul agent -dev ``` + +Copy the code above into a file such as `main.go`. + +Install and run. You'll see a key (`REDIS_MAXCLIENTS`) and value (`1000`) printed. + +```bash +$ go get +$ go run main.go +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 diff --git a/vendor/github.com/hashicorp/consul/api/acl.go b/vendor/github.com/hashicorp/consul/api/acl.go index 6ea0a752e..8ec9aa585 100644 --- a/vendor/github.com/hashicorp/consul/api/acl.go +++ b/vendor/github.com/hashicorp/consul/api/acl.go @@ -5,7 +5,7 @@ import ( ) const ( - // ACLCLientType is the client type token + // ACLClientType is the client type token ACLClientType = "client" // ACLManagementType is the management type token diff --git a/vendor/github.com/hashicorp/consul/api/agent.go b/vendor/github.com/hashicorp/consul/api/agent.go index 2c826660c..41505e769 100644 --- a/vendor/github.com/hashicorp/consul/api/agent.go +++ b/vendor/github.com/hashicorp/consul/api/agent.go @@ -5,6 +5,39 @@ import ( "fmt" ) +// ServiceKind is the kind of service being registered. +type ServiceKind string + +const ( + // ServiceKindTypical is a typical, classic Consul service. This is + // represented by the absence of a value. This was chosen for ease of + // backwards compatibility: existing services in the catalog would + // default to the typical service. + ServiceKindTypical ServiceKind = "" + + // ServiceKindConnectProxy is a proxy for the Connect feature. This + // service proxies another service within Consul and speaks the connect + // protocol. + ServiceKindConnectProxy ServiceKind = "connect-proxy" +) + +// ProxyExecMode is the execution mode for a managed Connect proxy. +type ProxyExecMode string + +const ( + // ProxyExecModeDaemon indicates that the proxy command should be long-running + // and should be started and supervised by the agent until it's target service + // is deregistered. + ProxyExecModeDaemon ProxyExecMode = "daemon" + + // ProxyExecModeScript indicates that the proxy command should be invoke to + // completion on each change to the configuration of lifecycle event. The + // script typically fetches the config and certificates from the agent API and + // then configures an externally managed daemon, perhaps starting and stopping + // it if necessary. + ProxyExecModeScript ProxyExecMode = "script" +) + // AgentCheck represents a check known to the agent type AgentCheck struct { Node string @@ -18,16 +51,41 @@ type AgentCheck struct { Definition HealthCheckDefinition } +// AgentWeights represent optional weights for a service +type AgentWeights struct { + Passing int + Warning int +} + // AgentService represents a service known to the agent type AgentService struct { + Kind ServiceKind ID string Service string Tags []string + Meta map[string]string Port int Address string + Weights AgentWeights EnableTagOverride bool CreateIndex uint64 ModifyIndex uint64 + ProxyDestination string + Connect *AgentServiceConnect +} + +// AgentServiceConnect represents the Connect configuration of a service. +type AgentServiceConnect struct { + Native bool + Proxy *AgentServiceConnectProxy +} + +// AgentServiceConnectProxy represents the Connect Proxy configuration of a +// service. +type AgentServiceConnectProxy struct { + ExecMode ProxyExecMode + Command []string + Config map[string]interface{} } // AgentMember represents a cluster member known to the agent @@ -60,14 +118,19 @@ type MembersOpts struct { // AgentServiceRegistration is used to register a new service type AgentServiceRegistration struct { - ID string `json:",omitempty"` - Name string `json:",omitempty"` - Tags []string `json:",omitempty"` - Port int `json:",omitempty"` - Address string `json:",omitempty"` - EnableTagOverride bool `json:",omitempty"` + Kind ServiceKind `json:",omitempty"` + ID string `json:",omitempty"` + Name string `json:",omitempty"` + Tags []string `json:",omitempty"` + Port int `json:",omitempty"` + Address string `json:",omitempty"` + EnableTagOverride bool `json:",omitempty"` + Meta map[string]string `json:",omitempty"` + Weights *AgentWeights `json:",omitempty"` Check *AgentServiceCheck Checks AgentServiceChecks + ProxyDestination string `json:",omitempty"` + Connect *AgentServiceConnect `json:",omitempty"` } // AgentCheckRegistration is used to register a new check @@ -84,7 +147,6 @@ type AgentServiceCheck struct { CheckID string `json:",omitempty"` Name string `json:",omitempty"` Args []string `json:"ScriptArgs,omitempty"` - Script string `json:",omitempty"` // Deprecated, use Args. DockerContainerID string `json:",omitempty"` Shell string `json:",omitempty"` // Only supported for Docker. Interval string `json:",omitempty"` @@ -97,6 +159,8 @@ type AgentServiceCheck struct { Status string `json:",omitempty"` Notes string `json:",omitempty"` TLSSkipVerify bool `json:",omitempty"` + GRPC string `json:",omitempty"` + GRPCUseTLS bool `json:",omitempty"` // In Consul 0.7 and later, checks that are associated with a service // may also contain this optional DeregisterCriticalServiceAfter field, @@ -149,6 +213,31 @@ type SampledValue struct { Labels map[string]string } +// AgentAuthorizeParams are the request parameters for authorizing a request. +type AgentAuthorizeParams struct { + Target string + ClientCertURI string + ClientCertSerial string +} + +// AgentAuthorize is the response structure for Connect authorization. +type AgentAuthorize struct { + Authorized bool + Reason string +} + +// ConnectProxyConfig is the response structure for agent-local proxy +// configuration. +type ConnectProxyConfig struct { + ProxyServiceID string + TargetServiceID string + TargetServiceName string + ContentHash string + ExecMode ProxyExecMode + Command []string + Config map[string]interface{} +} + // Agent can be used to query the Agent endpoints type Agent struct { c *Client @@ -250,6 +339,7 @@ func (a *Agent) Services() (map[string]*AgentService, error) { if err := decodeBody(resp, &out); err != nil { return nil, err } + return out, nil } @@ -482,6 +572,91 @@ func (a *Agent) ForceLeave(node string) error { return nil } +// ConnectAuthorize is used to authorize an incoming connection +// to a natively integrated Connect service. +func (a *Agent) ConnectAuthorize(auth *AgentAuthorizeParams) (*AgentAuthorize, error) { + r := a.c.newRequest("POST", "/v1/agent/connect/authorize") + r.obj = auth + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out AgentAuthorize + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return &out, nil +} + +// ConnectCARoots returns the list of roots. +func (a *Agent) ConnectCARoots(q *QueryOptions) (*CARootList, *QueryMeta, error) { + r := a.c.newRequest("GET", "/v1/agent/connect/ca/roots") + r.setQueryOptions(q) + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out CARootList + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return &out, qm, nil +} + +// ConnectCALeaf gets the leaf certificate for the given service ID. +func (a *Agent) ConnectCALeaf(serviceID string, q *QueryOptions) (*LeafCert, *QueryMeta, error) { + r := a.c.newRequest("GET", "/v1/agent/connect/ca/leaf/"+serviceID) + r.setQueryOptions(q) + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out LeafCert + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return &out, qm, nil +} + +// ConnectProxyConfig gets the configuration for a local managed proxy instance. +// +// Note that this uses an unconventional blocking mechanism since it's +// agent-local state. That means there is no persistent raft index so we block +// based on object hash instead. +func (a *Agent) ConnectProxyConfig(proxyServiceID string, q *QueryOptions) (*ConnectProxyConfig, *QueryMeta, error) { + r := a.c.newRequest("GET", "/v1/agent/connect/proxy/"+proxyServiceID) + r.setQueryOptions(q) + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out ConnectProxyConfig + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return &out, qm, nil +} + // EnableServiceMaintenance toggles service maintenance mode on // for the given service ID. func (a *Agent) EnableServiceMaintenance(serviceID, reason string) error { diff --git a/vendor/github.com/hashicorp/consul/api/api.go b/vendor/github.com/hashicorp/consul/api/api.go index b756ceb06..649238302 100644 --- a/vendor/github.com/hashicorp/consul/api/api.go +++ b/vendor/github.com/hashicorp/consul/api/api.go @@ -82,6 +82,12 @@ type QueryOptions struct { // until the timeout or the next index is reached WaitIndex uint64 + // WaitHash is used by some endpoints instead of WaitIndex to perform blocking + // on state based on a hash of the response rather than a monotonic index. + // This is required when the state being blocked on is not stored in Raft, for + // example agent-local proxy configuration. + WaitHash string + // WaitTime is used to bound the duration of a wait. // Defaults to that of the Config, but can be overridden. WaitTime time.Duration @@ -101,11 +107,15 @@ type QueryOptions struct { // be provided for filtering. NodeMeta map[string]string - // RelayFactor is used in keyring operations to cause reponses to be + // RelayFactor is used in keyring operations to cause responses to be // relayed back to the sender through N other random nodes. Must be // a value from 0 to 5 (inclusive). RelayFactor uint8 + // Connect filters prepared query execution to only include Connect-capable + // services. This currently affects prepared query execution. + Connect bool + // ctx is an optional context pass through to the underlying HTTP // request layer. Use Context() and WithContext() to manage this. ctx context.Context @@ -137,7 +147,7 @@ type WriteOptions struct { // which overrides the agent's default token. Token string - // RelayFactor is used in keyring operations to cause reponses to be + // RelayFactor is used in keyring operations to cause responses to be // relayed back to the sender through N other random nodes. Must be // a value from 0 to 5 (inclusive). RelayFactor uint8 @@ -169,6 +179,11 @@ type QueryMeta struct { // a blocking query LastIndex uint64 + // LastContentHash. This can be used as a WaitHash to perform a blocking query + // for endpoints that support hash-based blocking. Endpoints that do not + // support it will return an empty hash. + LastContentHash string + // Time of last contact from the leader for the // server servicing the request LastContact time.Duration @@ -390,6 +405,29 @@ func SetupTLSConfig(tlsConfig *TLSConfig) (*tls.Config, error) { return tlsClientConfig, nil } +func (c *Config) GenerateEnv() []string { + env := make([]string, 0, 10) + + env = append(env, + fmt.Sprintf("%s=%s", HTTPAddrEnvName, c.Address), + fmt.Sprintf("%s=%s", HTTPTokenEnvName, c.Token), + fmt.Sprintf("%s=%t", HTTPSSLEnvName, c.Scheme == "https"), + fmt.Sprintf("%s=%s", HTTPCAFile, c.TLSConfig.CAFile), + fmt.Sprintf("%s=%s", HTTPCAPath, c.TLSConfig.CAPath), + fmt.Sprintf("%s=%s", HTTPClientCert, c.TLSConfig.CertFile), + fmt.Sprintf("%s=%s", HTTPClientKey, c.TLSConfig.KeyFile), + fmt.Sprintf("%s=%s", HTTPTLSServerName, c.TLSConfig.Address), + fmt.Sprintf("%s=%t", HTTPSSLVerifyEnvName, !c.TLSConfig.InsecureSkipVerify)) + + if c.HttpAuth != nil { + env = append(env, fmt.Sprintf("%s=%s:%s", HTTPAuthEnvName, c.HttpAuth.Username, c.HttpAuth.Password)) + } else { + env = append(env, fmt.Sprintf("%s=", HTTPAuthEnvName)) + } + + return env +} + // Client provides a client to the Consul API type Client struct { config Config @@ -533,6 +571,9 @@ func (r *request) setQueryOptions(q *QueryOptions) { if q.WaitTime != 0 { r.params.Set("wait", durToMsec(q.WaitTime)) } + if q.WaitHash != "" { + r.params.Set("hash", q.WaitHash) + } if q.Token != "" { r.header.Set("X-Consul-Token", q.Token) } @@ -547,6 +588,9 @@ func (r *request) setQueryOptions(q *QueryOptions) { if q.RelayFactor != 0 { r.params.Set("relay-factor", strconv.Itoa(int(q.RelayFactor))) } + if q.Connect { + r.params.Set("connect", "true") + } r.ctx = q.ctx } @@ -724,12 +768,16 @@ func (c *Client) write(endpoint string, in, out interface{}, q *WriteOptions) (* func parseQueryMeta(resp *http.Response, q *QueryMeta) error { header := resp.Header - // Parse the X-Consul-Index - index, err := strconv.ParseUint(header.Get("X-Consul-Index"), 10, 64) - if err != nil { - return fmt.Errorf("Failed to parse X-Consul-Index: %v", err) + // Parse the X-Consul-Index (if it's set - hash based blocking queries don't + // set this) + if indexStr := header.Get("X-Consul-Index"); indexStr != "" { + index, err := strconv.ParseUint(indexStr, 10, 64) + if err != nil { + return fmt.Errorf("Failed to parse X-Consul-Index: %v", err) + } + q.LastIndex = index } - q.LastIndex = index + q.LastContentHash = header.Get("X-Consul-ContentHash") // Parse the X-Consul-LastContact last, err := strconv.ParseUint(header.Get("X-Consul-LastContact"), 10, 64) diff --git a/vendor/github.com/hashicorp/consul/api/catalog.go b/vendor/github.com/hashicorp/consul/api/catalog.go index 08da6e16e..6cb745c36 100644 --- a/vendor/github.com/hashicorp/consul/api/catalog.go +++ b/vendor/github.com/hashicorp/consul/api/catalog.go @@ -1,5 +1,10 @@ package api +type Weights struct { + Passing int + Warning int +} + type Node struct { ID string Node string @@ -22,7 +27,9 @@ type CatalogService struct { ServiceName string ServiceAddress string ServiceTags []string + ServiceMeta map[string]string ServicePort int + ServiceWeights Weights ServiceEnableTagOverride bool CreateIndex uint64 ModifyIndex uint64 @@ -155,7 +162,20 @@ func (c *Catalog) Services(q *QueryOptions) (map[string][]string, *QueryMeta, er // Service is used to query catalog entries for a given service func (c *Catalog) Service(service, tag string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/catalog/service/"+service) + return c.service(service, tag, 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) { + return c.service(service, tag, q, true) +} + +func (c *Catalog) service(service, tag 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 tag != "" { r.params.Set("tag", tag) diff --git a/vendor/github.com/hashicorp/consul/api/connect.go b/vendor/github.com/hashicorp/consul/api/connect.go new file mode 100644 index 000000000..a40d1e232 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/connect.go @@ -0,0 +1,12 @@ +package api + +// Connect can be used to work with endpoints related to Connect, the +// feature for securely connecting services within Consul. +type Connect struct { + c *Client +} + +// Connect returns a handle to the connect-related endpoints +func (c *Client) Connect() *Connect { + return &Connect{c} +} diff --git a/vendor/github.com/hashicorp/consul/api/connect_ca.go b/vendor/github.com/hashicorp/consul/api/connect_ca.go new file mode 100644 index 000000000..a863d21d4 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/connect_ca.go @@ -0,0 +1,172 @@ +package api + +import ( + "fmt" + "time" + + "github.com/mitchellh/mapstructure" +) + +// CAConfig is the structure for the Connect CA configuration. +type CAConfig struct { + // Provider is the CA provider implementation to use. + Provider string + + // Configuration is arbitrary configuration for the provider. This + // should only contain primitive values and containers (such as lists + // and maps). + Config map[string]interface{} + + CreateIndex uint64 + ModifyIndex uint64 +} + +// CommonCAProviderConfig is the common options available to all CA providers. +type CommonCAProviderConfig struct { + LeafCertTTL time.Duration +} + +// ConsulCAProviderConfig is the config for the built-in Consul CA provider. +type ConsulCAProviderConfig struct { + CommonCAProviderConfig `mapstructure:",squash"` + + PrivateKey string + RootCert string + RotationPeriod time.Duration +} + +// ParseConsulCAConfig takes a raw config map and returns a parsed +// ConsulCAProviderConfig. +func ParseConsulCAConfig(raw map[string]interface{}) (*ConsulCAProviderConfig, error) { + var config ConsulCAProviderConfig + decodeConf := &mapstructure.DecoderConfig{ + DecodeHook: mapstructure.StringToTimeDurationHookFunc(), + ErrorUnused: true, + Result: &config, + WeaklyTypedInput: true, + } + + decoder, err := mapstructure.NewDecoder(decodeConf) + if err != nil { + return nil, err + } + + if err := decoder.Decode(raw); err != nil { + return nil, fmt.Errorf("error decoding config: %s", err) + } + + return &config, nil +} + +// CARootList is the structure for the results of listing roots. +type CARootList struct { + ActiveRootID string + TrustDomain string + Roots []*CARoot +} + +// CARoot represents a root CA certificate that is trusted. +type CARoot struct { + // ID is a globally unique ID (UUID) representing this CA root. + ID string + + // Name is a human-friendly name for this CA root. This value is + // opaque to Consul and is not used for anything internally. + Name string + + // RootCertPEM is the PEM-encoded public certificate. + RootCertPEM string `json:"RootCert"` + + // Active is true if this is the current active CA. This must only + // be true for exactly one CA. For any method that modifies roots in the + // state store, tests should be written to verify that multiple roots + // cannot be active. + Active bool + + CreateIndex uint64 + ModifyIndex uint64 +} + +// LeafCert is a certificate that has been issued by a Connect CA. +type LeafCert struct { + // SerialNumber is the unique serial number for this certificate. + // This is encoded in standard hex separated by :. + SerialNumber string + + // CertPEM and PrivateKeyPEM are the PEM-encoded certificate and private + // key for that cert, respectively. This should not be stored in the + // state store, but is present in the sign API response. + CertPEM string `json:",omitempty"` + PrivateKeyPEM string `json:",omitempty"` + + // Service is the name of the service for which the cert was issued. + // ServiceURI is the cert URI value. + Service string + ServiceURI string + + // ValidAfter and ValidBefore are the validity periods for the + // certificate. + ValidAfter time.Time + ValidBefore time.Time + + CreateIndex uint64 + ModifyIndex uint64 +} + +// CARoots queries the list of available roots. +func (h *Connect) CARoots(q *QueryOptions) (*CARootList, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/connect/ca/roots") + r.setQueryOptions(q) + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out CARootList + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return &out, qm, nil +} + +// CAGetConfig returns the current CA configuration. +func (h *Connect) CAGetConfig(q *QueryOptions) (*CAConfig, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/connect/ca/configuration") + r.setQueryOptions(q) + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out CAConfig + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return &out, qm, nil +} + +// CASetConfig sets the current CA configuration. +func (h *Connect) CASetConfig(conf *CAConfig, q *WriteOptions) (*WriteMeta, error) { + r := h.c.newRequest("PUT", "/v1/connect/ca/configuration") + r.setWriteOptions(q) + r.obj = conf + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{} + wm.RequestTime = rtt + return wm, nil +} diff --git a/vendor/github.com/hashicorp/consul/api/connect_intention.go b/vendor/github.com/hashicorp/consul/api/connect_intention.go new file mode 100644 index 000000000..a996c03e5 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/connect_intention.go @@ -0,0 +1,302 @@ +package api + +import ( + "bytes" + "fmt" + "io" + "time" +) + +// Intention defines an intention for the Connect Service Graph. This defines +// the allowed or denied behavior of a connection between two services using +// Connect. +type Intention struct { + // ID is the UUID-based ID for the intention, always generated by Consul. + ID string + + // Description is a human-friendly description of this intention. + // It is opaque to Consul and is only stored and transferred in API + // requests. + Description string + + // SourceNS, SourceName are the namespace and name, respectively, of + // the source service. Either of these may be the wildcard "*", but only + // the full value can be a wildcard. Partial wildcards are not allowed. + // The source may also be a non-Consul service, as specified by SourceType. + // + // DestinationNS, DestinationName is the same, but for the destination + // service. The same rules apply. The destination is always a Consul + // service. + SourceNS, SourceName string + DestinationNS, DestinationName string + + // SourceType is the type of the value for the source. + SourceType IntentionSourceType + + // Action is whether this is a whitelist or blacklist intention. + Action IntentionAction + + // DefaultAddr, DefaultPort of the local listening proxy (if any) to + // make this connection. + DefaultAddr string + DefaultPort int + + // Meta is arbitrary metadata associated with the intention. This is + // opaque to Consul but is served in API responses. + Meta map[string]string + + // Precedence is the order that the intention will be applied, with + // larger numbers being applied first. This is a read-only field, on + // any intention update it is updated. + Precedence int + + // CreatedAt and UpdatedAt keep track of when this record was created + // or modified. + CreatedAt, UpdatedAt time.Time + + CreateIndex uint64 + ModifyIndex uint64 +} + +// String returns human-friendly output describing ths intention. +func (i *Intention) String() string { + return fmt.Sprintf("%s => %s (%s)", + i.SourceString(), + i.DestinationString(), + i.Action) +} + +// SourceString returns the namespace/name format for the source, or +// just "name" if the namespace is the default namespace. +func (i *Intention) SourceString() string { + return i.partString(i.SourceNS, i.SourceName) +} + +// DestinationString returns the namespace/name format for the source, or +// just "name" if the namespace is the default namespace. +func (i *Intention) DestinationString() string { + return i.partString(i.DestinationNS, i.DestinationName) +} + +func (i *Intention) partString(ns, n string) string { + // For now we omit the default namespace from the output. In the future + // we might want to look at this and show this in a multi-namespace world. + if ns != "" && ns != IntentionDefaultNamespace { + n = ns + "/" + n + } + + return n +} + +// IntentionDefaultNamespace is the default namespace value. +const IntentionDefaultNamespace = "default" + +// IntentionAction is the action that the intention represents. This +// can be "allow" or "deny" to whitelist or blacklist intentions. +type IntentionAction string + +const ( + IntentionActionAllow IntentionAction = "allow" + IntentionActionDeny IntentionAction = "deny" +) + +// IntentionSourceType is the type of the source within an intention. +type IntentionSourceType string + +const ( + // IntentionSourceConsul is a service within the Consul catalog. + IntentionSourceConsul IntentionSourceType = "consul" +) + +// IntentionMatch are the arguments for the intention match API. +type IntentionMatch struct { + By IntentionMatchType + Names []string +} + +// IntentionMatchType is the target for a match request. For example, +// matching by source will look for all intentions that match the given +// source value. +type IntentionMatchType string + +const ( + IntentionMatchSource IntentionMatchType = "source" + IntentionMatchDestination IntentionMatchType = "destination" +) + +// IntentionCheck are the arguments for the intention check API. For +// more documentation see the IntentionCheck function. +type IntentionCheck struct { + // Source and Destination are the source and destination values to + // check. The destination is always a Consul service, but the source + // may be other values as defined by the SourceType. + Source, Destination string + + // SourceType is the type of the value for the source. + SourceType IntentionSourceType +} + +// Intentions returns the list of intentions. +func (h *Connect) Intentions(q *QueryOptions) ([]*Intention, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/connect/intentions") + r.setQueryOptions(q) + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*Intention + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// IntentionGet retrieves a single intention. +func (h *Connect) IntentionGet(id string, q *QueryOptions) (*Intention, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/connect/intentions/"+id) + r.setQueryOptions(q) + rtt, resp, err := h.c.doRequest(r) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + if resp.StatusCode == 404 { + return nil, qm, nil + } else if resp.StatusCode != 200 { + var buf bytes.Buffer + io.Copy(&buf, resp.Body) + return nil, nil, fmt.Errorf( + "Unexpected response %d: %s", resp.StatusCode, buf.String()) + } + + var out Intention + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return &out, qm, nil +} + +// IntentionDelete deletes a single intention. +func (h *Connect) IntentionDelete(id string, q *WriteOptions) (*WriteMeta, error) { + r := h.c.newRequest("DELETE", "/v1/connect/intentions/"+id) + r.setWriteOptions(q) + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + qm := &WriteMeta{} + qm.RequestTime = rtt + + return qm, nil +} + +// IntentionMatch returns the list of intentions that match a given source +// or destination. The returned intentions are ordered by precedence where +// result[0] is the highest precedence (if that matches, then that rule overrides +// all other rules). +// +// Matching can be done for multiple names at the same time. The resulting +// map is keyed by the given names. Casing is preserved. +func (h *Connect) IntentionMatch(args *IntentionMatch, q *QueryOptions) (map[string][]*Intention, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/connect/intentions/match") + r.setQueryOptions(q) + r.params.Set("by", string(args.By)) + for _, name := range args.Names { + r.params.Add("name", name) + } + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out map[string][]*Intention + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// IntentionCheck returns whether a given source/destination would be allowed +// or not given the current set of intentions and the configuration of Consul. +func (h *Connect) IntentionCheck(args *IntentionCheck, q *QueryOptions) (bool, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/connect/intentions/check") + r.setQueryOptions(q) + r.params.Set("source", args.Source) + r.params.Set("destination", args.Destination) + if args.SourceType != "" { + r.params.Set("source-type", string(args.SourceType)) + } + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return false, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out struct{ Allowed bool } + if err := decodeBody(resp, &out); err != nil { + return false, nil, err + } + return out.Allowed, qm, nil +} + +// IntentionCreate will create a new intention. The ID in the given +// structure must be empty and a generate ID will be returned on +// success. +func (c *Connect) IntentionCreate(ixn *Intention, q *WriteOptions) (string, *WriteMeta, error) { + r := c.c.newRequest("POST", "/v1/connect/intentions") + r.setWriteOptions(q) + r.obj = ixn + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return "", nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{} + wm.RequestTime = rtt + + var out struct{ ID string } + if err := decodeBody(resp, &out); err != nil { + return "", nil, err + } + return out.ID, wm, nil +} + +// IntentionUpdate will update an existing intention. The ID in the given +// structure must be non-empty. +func (c *Connect) IntentionUpdate(ixn *Intention, q *WriteOptions) (*WriteMeta, error) { + r := c.c.newRequest("PUT", "/v1/connect/intentions/"+ixn.ID) + r.setWriteOptions(q) + r.obj = ixn + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{} + wm.RequestTime = rtt + return wm, nil +} diff --git a/vendor/github.com/hashicorp/consul/api/health.go b/vendor/github.com/hashicorp/consul/api/health.go index 53f3de4f7..1835da559 100644 --- a/vendor/github.com/hashicorp/consul/api/health.go +++ b/vendor/github.com/hashicorp/consul/api/health.go @@ -159,7 +159,24 @@ func (h *Health) Checks(service string, q *QueryOptions) (HealthChecks, *QueryMe // for a given service. It can optionally do server-side filtering on a tag // or nodes with passing health checks only. func (h *Health) Service(service, tag string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/health/service/"+service) + return h.service(service, tag, passingOnly, q, false) +} + +// Connect is equivalent to Service except that it will only return services +// which are Connect-enabled and will returns the connection address for Connect +// client's to use which may be a proxy in front of the named service. If +// passingOnly is true only instances where both the service and any proxy are +// healthy will be returned. +func (h *Health) Connect(service, tag string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { + return h.service(service, tag, passingOnly, q, true) +} + +func (h *Health) service(service, tag string, passingOnly bool, q *QueryOptions, connect bool) ([]*ServiceEntry, *QueryMeta, error) { + path := "/v1/health/service/" + service + if connect { + path = "/v1/health/connect/" + service + } + r := h.c.newRequest("GET", path) r.setQueryOptions(q) if tag != "" { r.params.Set("tag", tag) diff --git a/vendor/github.com/hashicorp/consul/api/lock.go b/vendor/github.com/hashicorp/consul/api/lock.go index 41f72e7d2..82339cb74 100644 --- a/vendor/github.com/hashicorp/consul/api/lock.go +++ b/vendor/github.com/hashicorp/consul/api/lock.go @@ -181,11 +181,12 @@ WAIT: // Handle the one-shot mode. if l.opts.LockTryOnce && attempts > 0 { elapsed := time.Since(start) - if elapsed > qOpts.WaitTime { + if elapsed > l.opts.LockWaitTime { return nil, nil } - qOpts.WaitTime -= elapsed + // Query wait time should not exceed the lock wait time + qOpts.WaitTime = l.opts.LockWaitTime - elapsed } attempts++ diff --git a/vendor/github.com/hashicorp/consul/api/operator_area.go b/vendor/github.com/hashicorp/consul/api/operator_area.go index a630b694c..5cf7e4973 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_area.go +++ b/vendor/github.com/hashicorp/consul/api/operator_area.go @@ -1,9 +1,10 @@ +package api + // The /v1/operator/area endpoints are available only in Consul Enterprise and // interact with its network area subsystem. Network areas are used to link // together Consul servers in different Consul datacenters. With network areas, // Consul datacenters can be linked together in ways other than a fully-connected // mesh, as is required for Consul's WAN. -package api import ( "net" diff --git a/vendor/github.com/hashicorp/consul/api/prepared_query.go b/vendor/github.com/hashicorp/consul/api/prepared_query.go index ff210de3f..8bb1004ee 100644 --- a/vendor/github.com/hashicorp/consul/api/prepared_query.go +++ b/vendor/github.com/hashicorp/consul/api/prepared_query.go @@ -34,6 +34,12 @@ type ServiceQuery struct { // local datacenter. Failover QueryDatacenterOptions + // IgnoreCheckIDs is an optional list of health check IDs to ignore when + // considering which nodes are healthy. It is useful as an emergency measure + // to temporarily override some health check that is producing false negatives + // for example. + IgnoreCheckIDs []string + // If OnlyPassing is true then we will only include nodes with passing // health checks (critical AND warning checks will cause a node to be // discarded) @@ -48,6 +54,14 @@ type ServiceQuery struct { // pair is in this map it must be present on the node in order for the // service entry to be returned. NodeMeta map[string]string + + // Connect if true will filter the prepared query results to only + // include Connect-capable services. These include both native services + // and proxies for matching services. Note that if a proxy matches, + // the constraints in the query above (Near, OnlyPassing, etc.) apply + // to the _proxy_ and not the service being proxied. In practice, proxies + // should be directly next to their services so this isn't an issue. + Connect bool } // QueryTemplate carries the arguments for creating a templated query. @@ -61,7 +75,7 @@ type QueryTemplate struct { Regexp string } -// PrepatedQueryDefinition defines a complete prepared query. +// PreparedQueryDefinition defines a complete prepared query. type PreparedQueryDefinition struct { // ID is this UUID-based ID for the query, always generated by Consul. ID string diff --git a/vendor/github.com/hashicorp/consul/api/semaphore.go b/vendor/github.com/hashicorp/consul/api/semaphore.go index d0c574177..bc4f885fe 100644 --- a/vendor/github.com/hashicorp/consul/api/semaphore.go +++ b/vendor/github.com/hashicorp/consul/api/semaphore.go @@ -199,11 +199,12 @@ WAIT: // Handle the one-shot mode. if s.opts.SemaphoreTryOnce && attempts > 0 { elapsed := time.Since(start) - if elapsed > qOpts.WaitTime { + if elapsed > s.opts.SemaphoreWaitTime { return nil, nil } - qOpts.WaitTime -= elapsed + // Query wait time should not exceed the semaphore wait time + qOpts.WaitTime = s.opts.SemaphoreWaitTime - elapsed } attempts++ diff --git a/vendor/github.com/hashicorp/consul/testutil/server.go b/vendor/github.com/hashicorp/consul/testutil/server.go index 4993f13cb..32d458a7f 100644 --- a/vendor/github.com/hashicorp/consul/testutil/server.go +++ b/vendor/github.com/hashicorp/consul/testutil/server.go @@ -17,6 +17,7 @@ import ( "fmt" "io" "io/ioutil" + "log" "net" "net/http" "os" @@ -42,12 +43,14 @@ type TestPerformanceConfig struct { // TestPortConfig configures the various ports used for services // provided by the Consul server. type TestPortConfig struct { - DNS int `json:"dns,omitempty"` - HTTP int `json:"http,omitempty"` - HTTPS int `json:"https,omitempty"` - SerfLan int `json:"serf_lan,omitempty"` - SerfWan int `json:"serf_wan,omitempty"` - Server int `json:"server,omitempty"` + DNS int `json:"dns,omitempty"` + HTTP int `json:"http,omitempty"` + HTTPS int `json:"https,omitempty"` + SerfLan int `json:"serf_lan,omitempty"` + SerfWan int `json:"serf_wan,omitempty"` + Server int `json:"server,omitempty"` + ProxyMinPort int `json:"proxy_min_port,omitempty"` + ProxyMaxPort int `json:"proxy_max_port,omitempty"` } // TestAddressConfig contains the bind addresses for various @@ -94,6 +97,7 @@ type TestServerConfig struct { VerifyIncomingHTTPS bool `json:"verify_incoming_https,omitempty"` VerifyOutgoing bool `json:"verify_outgoing,omitempty"` EnableScriptChecks bool `json:"enable_script_checks,omitempty"` + Connect map[string]interface{} `json:"connect,omitempty"` ReadyTimeout time.Duration `json:"-"` Stdout, Stderr io.Writer `json:"-"` Args []string `json:"-"` @@ -133,6 +137,16 @@ func defaultServerConfig() *TestServerConfig { Server: ports[5], }, ReadyTimeout: 10 * time.Second, + Connect: map[string]interface{}{ + "enabled": true, + "ca_config": map[string]interface{}{ + // const TestClusterID causes import cycle so hard code it here. + "cluster_id": "11111111-2222-3333-4444-555555555555", + }, + "proxy": map[string]interface{}{ + "allow_managed_api_registration": true, + }, + }, } } @@ -211,6 +225,7 @@ func newTestServerConfigT(t *testing.T, cb ServerConfigCallback) (*TestServer, e return nil, errors.Wrap(err, "failed marshaling json") } + log.Printf("CONFIG JSON: %s", string(b)) configFile := filepath.Join(tmpdir, "config.json") if err := ioutil.WriteFile(configFile, b, 0644); err != nil { defer os.RemoveAll(tmpdir) @@ -299,7 +314,7 @@ type failer struct { failed bool } -func (f *failer) Log(args ...interface{}) { fmt.Println(args) } +func (f *failer) Log(args ...interface{}) { fmt.Println(args...) } func (f *failer) FailNow() { f.failed = true } // waitForAPI waits for only the agent HTTP endpoint to start @@ -314,7 +329,7 @@ func (s *TestServer) waitForAPI() error { } defer resp.Body.Close() if err := s.requireOK(resp); err != nil { - r.Fatal("failed OK respose", err) + r.Fatal("failed OK response", err) } }) if f.failed { diff --git a/vendor/vendor.json b/vendor/vendor.json index 7fc1bd4e2..4ee5359df 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -409,36 +409,36 @@ "revisionTime": "2016-07-22T20:42:12Z" }, { - "checksumSHA1": "ivSpuvm7dkBBC1kWyDWTZ9yF3Rs=", + "checksumSHA1": "SB7wK1wwrVUhTK4Ozu1oXpYJkTI=", "path": "github.com/hashicorp/consul/api", - "revision": "9a494b5fb9c86180a5702e29c485df1507a47198", - "revisionTime": "2018-02-09T18:00:27Z", - "version": "=v1.0.6", - "versionExact": "v1.0.6" + "revision": "48d287ef690ada66634885640f3444dbf7b71d18", + "revisionTime": "2018-09-13T15:22:25Z", + "version": "v1.2.3", + "versionExact": "v1.2.3" }, { "checksumSHA1": "E28E4zR1FN2v1Xiq4FUER7KVN9M=", "path": "github.com/hashicorp/consul/lib/freeport", - "revision": "9a494b5fb9c86180a5702e29c485df1507a47198", - "revisionTime": "2018-02-09T18:00:27Z", - "version": "=v1.0.6", - "versionExact": "v1.0.6" + "revision": "48d287ef690ada66634885640f3444dbf7b71d18", + "revisionTime": "2018-09-13T15:22:25Z", + "version": "v1.2.3", + "versionExact": "v1.2.3" }, { - "checksumSHA1": "gjN5oVYQR1K7hCbUq2ED4KBWuys=", + "checksumSHA1": "6XdtbiIzDZ1b5aSS6OoU111/z3g=", "path": "github.com/hashicorp/consul/testutil", - "revision": "9a494b5fb9c86180a5702e29c485df1507a47198", - "revisionTime": "2018-02-09T18:00:27Z", - "version": "=v1.0.6", - "versionExact": "v1.0.6" + "revision": "48d287ef690ada66634885640f3444dbf7b71d18", + "revisionTime": "2018-09-13T15:22:25Z", + "version": "v1.2.3", + "versionExact": "v1.2.3" }, { "checksumSHA1": "SCb2b91UYiB/23+SNDBlU5OZfFA=", "path": "github.com/hashicorp/consul/testutil/retry", - "revision": "9a494b5fb9c86180a5702e29c485df1507a47198", - "revisionTime": "2018-02-09T18:00:27Z", - "version": "=v1.0.6", - "versionExact": "v1.0.6" + "revision": "48d287ef690ada66634885640f3444dbf7b71d18", + "revisionTime": "2018-09-13T15:22:25Z", + "version": "v1.2.3", + "versionExact": "v1.2.3" }, { "checksumSHA1": "cdOCt0Yb+hdErz8NAQqayxPmRsY=", From e711df952661c3ce71cd97891954fb7a0ebfac7c Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 16:42:21 +0200 Subject: [PATCH 10/15] Test Consul client config for tests --- testutil/helper.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testutil/helper.go b/testutil/helper.go index 3aaa6fb8d..141246167 100644 --- a/testutil/helper.go +++ b/testutil/helper.go @@ -23,10 +23,11 @@ import ( "github.com/hashicorp/consul/testutil" "github.com/stretchr/testify/assert" - "github.com/ystia/yorc/config" "github.com/ystia/yorc/helper/consulutil" ) +const defaultConsulPubMaxRoutinesForTest int = 50 + // NewTestConsulInstance allows to : // - creates and returns a new Consul server and client // - starts a Consul Publisher @@ -52,7 +53,7 @@ func NewTestConsulInstance(t *testing.T) (*testutil.TestServer, *api.Client) { assert.Nil(t, err) kv := client.KV() - consulutil.InitConsulPublisher(config.DefaultConsulPubMaxRoutines, kv) + consulutil.InitConsulPublisher(defaultConsulPubMaxRoutinesForTest, kv) return srv1, client } From 5a271a622f9b11c13fef859b1be5d67edc20dd2a Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 16:59:58 +0200 Subject: [PATCH 11/15] Test Consul client config for tests --- testutil/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testutil/helper.go b/testutil/helper.go index 141246167..febe4c02a 100644 --- a/testutil/helper.go +++ b/testutil/helper.go @@ -26,7 +26,7 @@ import ( "github.com/ystia/yorc/helper/consulutil" ) -const defaultConsulPubMaxRoutinesForTest int = 50 +const defaultConsulPubMaxRoutinesForTest int = 100 // NewTestConsulInstance allows to : // - creates and returns a new Consul server and client From a7f117223fa9cfca7f358c5e1e2d62a7554aff43 Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Mon, 24 Sep 2018 17:23:24 +0200 Subject: [PATCH 12/15] Test Consul client config for tests --- testutil/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testutil/helper.go b/testutil/helper.go index febe4c02a..81991d5ac 100644 --- a/testutil/helper.go +++ b/testutil/helper.go @@ -26,7 +26,7 @@ import ( "github.com/ystia/yorc/helper/consulutil" ) -const defaultConsulPubMaxRoutinesForTest int = 100 +const defaultConsulPubMaxRoutinesForTest int = 200 // NewTestConsulInstance allows to : // - creates and returns a new Consul server and client From f142838ec6dd0d5c0d225c0c07dd90fc4700be53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Albertin?= Date: Wed, 26 Sep 2018 11:21:09 +0200 Subject: [PATCH 13/15] Fix the way we get consul client in tests. Use the same method than in a normal server by tweaking Consul http client configuration --- testutil/helper.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/testutil/helper.go b/testutil/helper.go index 81991d5ac..0129d5211 100644 --- a/testutil/helper.go +++ b/testutil/helper.go @@ -23,11 +23,10 @@ import ( "github.com/hashicorp/consul/testutil" "github.com/stretchr/testify/assert" + "github.com/ystia/yorc/config" "github.com/ystia/yorc/helper/consulutil" ) -const defaultConsulPubMaxRoutinesForTest int = 200 - // NewTestConsulInstance allows to : // - creates and returns a new Consul server and client // - starts a Consul Publisher @@ -46,14 +45,18 @@ func NewTestConsulInstance(t *testing.T) (*testutil.TestServer, *api.Client) { t.Fatalf("Failed to create consul server: %v", err) } - consulConfig := api.DefaultConfig() - consulConfig.Address = srv1.HTTPAddr + cfg := config.Configuration{ + Consul: config.Consul{ + Address: srv1.HTTPAddr, + PubMaxRoutines: config.DefaultConsulPubMaxRoutines, + }, + } - client, err := api.NewClient(consulConfig) + client, err := cfg.GetNewConsulClient() assert.Nil(t, err) kv := client.KV() - consulutil.InitConsulPublisher(defaultConsulPubMaxRoutinesForTest, kv) + consulutil.InitConsulPublisher(cfg.Consul.PubMaxRoutines, kv) return srv1, client } From 02f7b0c44c23dbd14013c29baeb687c5ebe8fb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Albertin?= Date: Wed, 26 Sep 2018 11:34:47 +0200 Subject: [PATCH 14/15] Removed Empty continuation lines in Dockerfile That will become errors in a future Docker releases --- pkg/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/Dockerfile b/pkg/Dockerfile index 4361c66ff..60c9d43d8 100644 --- a/pkg/Dockerfile +++ b/pkg/Dockerfile @@ -33,8 +33,7 @@ RUN apk add --update make openssh-client python python-dev py-pip gcc musl-dev l umask 0022 && \ chown -R yorc:yorc /var/yorc && \ chmod 400 /var/yorc/.ssh/*.pem && \ - - # Copy Terraform providers plugins + echo "Copy Terraform providers plugins" && \ cd ${YORC_TERRAFORM_PLUGINS_DIR} && \ curl -O https://releases.hashicorp.com/terraform-provider-consul/${TF_CONSUL_PLUGIN_VERSION}/terraform-provider-consul_${TF_CONSUL_PLUGIN_VERSION}_linux_amd64.zip && \ unzip terraform-provider-consul_${TF_CONSUL_PLUGIN_VERSION}_linux_amd64.zip && \ @@ -48,7 +47,7 @@ RUN apk add --update make openssh-client python python-dev py-pip gcc musl-dev l unzip terraform-provider-openstack_${TF_OPENSTACK_PLUGIN_VERSION}_linux_amd64.zip && \ rm -rf ${YORC_TERRAFORM_PLUGINS_DIR}/*.zip && \ chmod 775 ${YORC_TERRAFORM_PLUGINS_DIR}/* && \ - + echo "Cleaning up" && \ apk del make py-pip python-dev gcc musl-dev libffi-dev openssl-dev && \ rm -rf /var/cache/apk/* && \ rm -fr /tmp/* From a5965da490cb221fb5a65217f99c9ed9fe941f2e Mon Sep 17 00:00:00 2001 From: Adriana Danes Date: Tue, 2 Oct 2018 14:21:38 +0200 Subject: [PATCH 15/15] Put back information about consul encryption --- doc/secured.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/secured.rst b/doc/secured.rst index 3b1f91b20..3260401ed 100644 --- a/doc/secured.rst +++ b/doc/secured.rst @@ -43,7 +43,7 @@ Secured Consul cluster Setup In a High Availability cluster, you need to setup at least 3 consul servers, and one consul client on each host where a Yorc server is running. -Check Consul documentation for details about `agent's configuration `_ and `network traffic encryption `_. +Check Consul documentation for details about `agent's configuration `_. You may find below a typical configuration file for a consul server ; to be updated after having generated the ``consul_server.key`` and ``consul_server.pem`` files. @@ -57,6 +57,7 @@ You may find below a typical configuration file for a consul server ; to be upda "server": true, "bootstrap": true, "ui": true, + "encrypt": "{ENCRYPT_KEY}, "ports": { "https": 8543 }, @@ -77,6 +78,7 @@ And below, a typical configuration file for a consul client. "client_addr": "0.0.0.0", "advertise_addr": "{IP}", "retry_join": [ "{SERVER_IP}" ], + "encrypt": "{ENCRYPT_KEY}, "ports": { "https": 8543 }, @@ -87,6 +89,8 @@ And below, a typical configuration file for a consul client. "verify_outgoing": true } +In the above example, the encryption is enabled for the gossip traffic inside the Consul cluster. Check Consul documentation for details `network traffic encryption `_. + You can also consult this `Blog `_. You may found useful information about how to install CA certificate in the OS, in case you get errors about trusting the signing authority.