add support for etcd over ssl
Change-Id: If777a3835d6f8cdd0e4565d149cc2070580dcd9c
diff --git a/README.rst b/README.rst
index 0fa35e4..cf05053 100644
--- a/README.rst
+++ b/README.rst
@@ -8,6 +8,26 @@
Sample pillars
==============
+Certificates
+-------------
+
+Use certificate authentication (for peers and clients). Certificates must be prepared in advance.
+
+.. code-block:: yaml
+
+ etcd:
+ server:
+ enabled: true
+ ssl:
+ enabled: true
+ bind:
+ host: 10.0.175.101
+ token: $(uuidgen)
+ members:
+ - host: 10.0.175.101
+ name: etcd01
+ port: 4001
+
Single etcd service
---------------------
diff --git a/etcd/files/configenv b/etcd/files/configenv
new file mode 100644
index 0000000..43550b4
--- /dev/null
+++ b/etcd/files/configenv
@@ -0,0 +1,8 @@
+{%- from "etcd/map.jinja" import server with context %}
+# this file can be sourced and used to configure etcdctl
+export ETCDCTL_ENDPOINT="{%- if server.bind.host != '127.0.0.1' %}http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://{{ server.bind.host }}:4001,{% endif %}http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://127.0.0.1:4001"
+{%- if server.get('ssl', {}).get('enabled') %}
+export ETCDCTL_CA_FILE=/var/lib/etcd/ca.pem
+export ETCDCTL_CERT_FILE=/var/lib/etcd/etcd-server.pem
+export ETCDCTL_KEY_FILE=/var/lib/etcd/etcd-server.key
+{% endif %}
diff --git a/etcd/files/default b/etcd/files/default
index 3224dff..72d975c 100644
--- a/etcd/files/default
+++ b/etcd/files/default
@@ -11,7 +11,7 @@
## default: "off"
ETCD_PROXY="on"
-ETCD_INITIAL_CLUSTER="{% for member in server.members %}{{ member.name }}={%- if server.bind.host == '127.0.0.1' %}http://127.0.0.1:2380{% else %}http://{{ member.host }}:2380{% if not loop.last %},{% endif %}{% endif %}{% endfor %}"
+ETCD_INITIAL_CLUSTER="{% for member in server.members %}{{ member.name }}={%- if server.bind.host == '127.0.0.1' %}http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://127.0.0.1:2380{% else %}http{% if server.get('ssl', {}).get('enabled') %}s:{% endif %}//{{ member.host }}:2380{% if not loop.last %},{% endif %}{% endif %}{% endfor %}"
##### -proxy-failure-wait
## Time (in milliseconds) an endpoint will be held in a failed state before being
@@ -93,7 +93,7 @@
## invalid example: "http://example.com:2380" (domain name is invalid for binding)
## default: "http://localhost:2380,http://localhost:7001"
# ETCD_LISTEN_PEER_URLS="http://localhost:2380,http://localhost:7001"
-ETCD_LISTEN_PEER_URLS="http://{{ server.bind.host }}:2380"
+ETCD_LISTEN_PEER_URLS="http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://{{ server.bind.host }}:2380"
##### -listen-client-urls
## List of URLs to listen on for client traffic. This flag tells the etcd to accept
@@ -108,7 +108,7 @@
## invalid example: "http://example.com:2379" (domain name is invalid for binding)
## default: "http://localhost:2379,http://localhost:4001"
# ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://localhost:4001"
-ETCD_LISTEN_CLIENT_URLS="{%- if server.bind.host != '127.0.0.1' %}http://{{ server.bind.host }}:4001,{% endif %}http://127.0.0.1:4001"
+ETCD_LISTEN_CLIENT_URLS="{%- if server.bind.host != '127.0.0.1' %}http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://{{ server.bind.host }}:4001,{% endif %}http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://127.0.0.1:4001"
##### -max-snapshots
## Maximum number of snapshot files to retain (0 is unlimited)
## default: 5
@@ -140,7 +140,7 @@
## example: "http://example.com:2380, http://10.0.0.1:2380"
## default: "http://localhost:2380,http://localhost:7001"
# ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380,http://localhost:7001"
-ETCD_INITIAL_ADVERTISE_PEER_URLS="http://{{ server.bind.host }}:2380"
+ETCD_INITIAL_ADVERTISE_PEER_URLS="http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://{{ server.bind.host }}:2380"
##### -initial-cluster
## initial cluster configuration for bootstrapping.
@@ -148,7 +148,7 @@
## The default uses `default` for the key because this is the default for the `-name` flag.
## default: "default=http://localhost:2380,default=http://localhost:7001"
# ETCD_INITIAL_CLUSTER="default=http://localhost:2380,default=http://localhost:7001"
-ETCD_INITIAL_CLUSTER="{% for member in server.members %}{{ member.name }}={%- if server.bind.host == '127.0.0.1' %}http://127.0.0.1:2380{% else %}http://{{ member.host }}:2380{% if not loop.last %},{% endif %}{% endif %}{% endfor %}"
+ETCD_INITIAL_CLUSTER="{% for member in server.members %}{{ member.name }}={%- if server.bind.host == '127.0.0.1' %}http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://127.0.0.1:2380{% else %}http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:2380{% if not loop.last %},{% endif %}{% endif %}{% endfor %}"
##### -initial-cluster-state
## Initial cluster state ("new" or "existing"). Set to `new` for all members
## present during initial static or DNS bootstrapping. If this option is set to
@@ -178,7 +178,7 @@
## (memory, file descriptors) are eventually depleted.
## default: "http://localhost:2379,http://localhost:4001"
# ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379,http://localhost:4001"
-ETCD_ADVERTISE_CLIENT_URLS="http://{{ server.bind.host }}:4001"
+ETCD_ADVERTISE_CLIENT_URLS="http{% if server.get('ssl', {}).get('enabled') %}s{% endif %}://{{ server.bind.host }}:4001"
##### -discovery
## Discovery URL used to bootstrap the cluster.
@@ -210,22 +210,34 @@
##### -cert-file
## Path to the client server TLS cert file.
## default: none
-# ETCD_CERT_FILE=""
+# ETCD_CERT_FILE
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_CERT_FILE="/var/lib/etcd/etcd-server.crt"
+{%- endif %}
##### -key-file
## Path to the client server TLS key file.
## default: none
# ETCD_KEY_FILE=""
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_KEY_FILE="/var/lib/etcd/etcd-server.key"
+{%- endif %}
##### -client-cert-auth
## Enable client cert authentication.
## default: false
# ETCD_CLIENT_CERT_AUTH
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_CLIENT_CERT_AUTH=true
+{%- endif %}
##### -trusted-ca-file
## Path to the client server TLS trusted CA key file.
## default: none
# ETCD_TRUSTED_CA_FILE
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_TRUSTED_CA_FILE="/var/lib/etcd/ca.pem"
+{%- endif %}
##### -peer-ca-file [DEPRECATED]
## Path to the peer server TLS CA file. `-peer-ca-file ca.crt` could be replaced
@@ -237,27 +249,38 @@
## Path to the peer server TLS cert file.
## default: none
# ETCD_PEER_CERT_FILE
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_PEER_CERT_FILE="/var/lib/etcd/etcd-server.crt"
+{%- endif %}
##### -peer-key-file
## Path to the peer server TLS key file.
## default: none
# ETCD_PEER_KEY_FILE
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_PEER_KEY_FILE="/var/lib/etcd/etcd-server.key"
+{%- endif %}
##### -peer-client-cert-auth
## Enable peer client cert authentication.
## default: false
# ETCD_PEER_CLIENT_CERT_AUTH
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_PEER_CLIENT_CERT_AUTH=true
+{%- endif %}
##### -peer-trusted-ca-file
## Path to the peer server TLS trusted CA file.
## default: none
# ETCD_PEER_TRUSTED_CA_FILE
+{%- if server.get('ssl', {}).get('enabled') %}
+ETCD_PEER_TRUSTED_CA_FILE="/var/lib/etcd/ca.pem"
+{%- endif %}
### Logging Flags
##### -debug
## Drop the default log level to DEBUG for all subpackages.
## default: false (INFO for all packages)
-# ETCD_DEBUG
##### -log-package-levels
## Set individual etcd subpackages to specific log levels.
@@ -268,4 +291,4 @@
#### Daemon parameters:
# DAEMON_ARGS=""
-{% endif %}
\ No newline at end of file
+{% endif %}
diff --git a/etcd/server/service.sls b/etcd/server/service.sls
index 2f0ddf4..e9c2306 100644
--- a/etcd/server/service.sls
+++ b/etcd/server/service.sls
@@ -39,6 +39,18 @@
- source: salt://etcd/files/default
- template: jinja
+/var/lib/etcd/:
+ file.directory:
+ - user: etcd
+ - group: etcd
+
+/var/lib/etcd/configenv:
+ file.managed:
+ - source: salt://etcd/files/configenv
+ - template: jinja
+ - require:
+ - file: /var/lib/etcd/
+
etcd:
service.running:
- enable: True