Giuseppe Lavagetto has submitted this change and it was merged.

Change subject: etcd: create puppet module
......................................................................


etcd: create puppet module

This also creates the puppet role so that it is directly usable in production

Bug: T97973
Change-Id: Ib80e3d3c3e46f9ff0b81c5dd675ce79184324576
---
A manifests/role/etcd.pp
A modules/etcd/files/etcd_cluster_health
A modules/etcd/files/logrotate.conf
A modules/etcd/files/rsyslog.conf
A modules/etcd/manifests/init.pp
A modules/etcd/manifests/logging.pp
A modules/etcd/manifests/monitoring.pp
A modules/etcd/manifests/ssl.pp
A modules/etcd/templates/initscripts/etcd.systemd.erb
9 files changed, 329 insertions(+), 0 deletions(-)

Approvals:
  Giuseppe Lavagetto: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/manifests/role/etcd.pp b/manifests/role/etcd.pp
new file mode 100644
index 0000000..93fc1d7
--- /dev/null
+++ b/manifests/role/etcd.pp
@@ -0,0 +1,24 @@
+# === Class role::etcd
+#
+class role::etcd {
+    system::role { 'role::etcd':
+        description => 'Highly-consistent distributed k/v store'
+    }
+
+    require standard
+    include base::firewall
+
+    ferm::rule{'etcd_clients':
+        proto => 'tcp',
+        port  => $etcd::client_port,
+    }
+
+    ferm::rule{'etcd_peers':
+        proto => 'tcp',
+        port  => $etcd::peer_port,
+    }
+
+    include etcd
+    include etcd::monitoring
+
+}
diff --git a/modules/etcd/files/etcd_cluster_health 
b/modules/etcd/files/etcd_cluster_health
new file mode 100755
index 0000000..b904d41a
--- /dev/null
+++ b/modules/etcd/files/etcd_cluster_health
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+# Copyright 2015 Giuseppe Lavagetto
+# Copyright 2015 Wikimedia Foundation, Inc.
+#
+# This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY.
+# It may be used, redistributed and/or modified under the terms of the GNU
+# General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).
+#
+# Example usage:
+#   etcd_cluster_health --url https://localhost:2379
+
+use strict;
+use Nagios::Plugin;
+
+my $np = Nagios::Plugin->new(usage => "Usage: %s --url <URL>");
+$np->add_arg(
+             spec     => 'url|u=s',
+             help     => '--url https://localhost:2379',
+             required => 1,
+            );
+$np->getopts;
+
+my $url = $np->opts->url;
+my $opts = "-C '$url'";
+
+if ($url =~ /^https:\/\//) {
+    $opts = "--ca-file /var/lib/etcd/ssl/ca.pem $opts";
+}
+
+open(CHECK, "/usr/bin/etcdctl $opts cluster-health |");
+
+my @members;
+
+while (<CHECK>) {
+    chomp;
+    next unless /^(cluster|member)/;
+    next if /is healthy$/;
+    $np->nagios_exit(CRITICAL, $_) if /^cluster/;
+    $np->nagios_exit(WARNING, $_) if /^member/;
+}
+$np->nagios_exit(OK, "The etcd cluster is healthy");
diff --git a/modules/etcd/files/logrotate.conf 
b/modules/etcd/files/logrotate.conf
new file mode 100644
index 0000000..a7586e4
--- /dev/null
+++ b/modules/etcd/files/logrotate.conf
@@ -0,0 +1,16 @@
+# logrotate(8) config for etcd
+# This file is managed by puppet
+
+/var/log/etcd.log {
+    daily
+    dateext
+    dateyesterday
+    rotate 10
+    missingok
+    nocreate
+    delaycompress
+    sharedscripts
+    postrotate
+        service rsyslog rotate >/dev/null 2>&1 || true
+    endscript
+}
diff --git a/modules/etcd/files/rsyslog.conf b/modules/etcd/files/rsyslog.conf
new file mode 100644
index 0000000..95ed2ab
--- /dev/null
+++ b/modules/etcd/files/rsyslog.conf
@@ -0,0 +1,3 @@
+# rsyslogd(8) configuration file for etcd.
+# This file is managed by Puppet.
+:programname, startswith, "etcd" /var/log/etcd.log
diff --git a/modules/etcd/manifests/init.pp b/modules/etcd/manifests/init.pp
new file mode 100644
index 0000000..c837f34
--- /dev/null
+++ b/modules/etcd/manifests/init.pp
@@ -0,0 +1,89 @@
+# == Class: etcd
+#
+# Installs an etcd server and defines all its clustering
+#
+# SSL between peers is not supported at the moment as it's
+# broken upstream
+#
+# === Parameters
+# [*host*]
+#   host (or IP) of the etcd server
+#
+# [*client_port*]
+#   TCP port for the client connections
+#
+# [*peer_port*]
+#   TCP port for the cluster traffic
+#
+# [*cluster_name*]
+#   Name of the cluster - defaults to the datacenter
+#
+# [*cluster_state*]
+#   State of the cluster at bootstrap, if any.
+#
+# [*srv_dns*]
+#   Domain to use for DNS-based cluster discovery.
+#
+# [*peers_list*]
+#   When DNS-based cluster discovery is not available, provide a peers list
+#
+# [*use_ssl*]
+#   set to true if you want to impose use of HTTPS to communicate with
+#   clients
+#
+# [*use_client_certs*]
+#   Whether to require use of SSL certificates to connect to etcd.
+#
+class etcd (
+    $host      = '127.0.0.1',
+    $client_port      = 2739,
+    $peer_port        = 2380,
+    $cluster_name     = $::domain,
+    $cluster_state    = undef,
+    $srv_dns          = undef,
+    $peers_list       = undef,
+    $use_ssl          = false,
+    $use_client_certs = false,
+    ) {
+    # This module is jessie only for now
+    requires_os('Debian >= jessie')
+
+    # Validation of parameters
+    if ($use_client_certs and ! $use_ssl) {
+        fail("Can't use SSL client certs if we don't use SSL")
+    }
+    unless $srv_dns or $peers_list {
+        fail("We need either the domain name for DNS discovery or an explicit 
peers list")
+    }
+
+    require etcd::logging
+
+    require_package 'etcd', 'etcdctl'
+
+    # SSL setup
+    if $use_ssl {
+        $scheme = 'https'
+        include etcd::ssl
+    } else {
+        $scheme = 'http'
+    }
+
+    $client_url = "${scheme}://${host}:${client_port}"
+    $peer_url = "http://${host}:${peer_port}"; # Peer TLS is currently broken?
+    $etcd_data_dir = "/var/lib/etcd/${cluster_name}"
+
+    file { $etcd_data_dir:
+        ensure  => directory,
+        owner   => 'etcd',
+        group   => 'etcd',
+        mode    => '0700',
+        require => Package['etcd'],
+    }
+
+    base::service_unit{ 'etcd':
+        ensure  => present,
+        systemd => true,
+        refresh => true,
+        require => File[$etcd_data_dir],
+    }
+}
diff --git a/modules/etcd/manifests/logging.pp 
b/modules/etcd/manifests/logging.pp
new file mode 100644
index 0000000..afe7c0a
--- /dev/null
+++ b/modules/etcd/manifests/logging.pp
@@ -0,0 +1,19 @@
+# == Class etcd::logging
+#
+# Manages all the logging logic for etcd.
+class etcd::logging {
+
+    file { '/etc/logrotate.d/etcd':
+        source => 'puppet:///modules/etcd/logrotate.conf',
+        owner  => 'root',
+        group  => 'root',
+        mode   => '0444',
+    }
+
+
+    rsyslog::conf { 'etcd':
+        source   => 'puppet:///modules/etcd/rsyslog.conf',
+        priority => 20,
+        require  => File['/etc/logrotate.d/etcd'],
+    }
+}
diff --git a/modules/etcd/manifests/monitoring.pp 
b/modules/etcd/manifests/monitoring.pp
new file mode 100644
index 0000000..125f7bc
--- /dev/null
+++ b/modules/etcd/manifests/monitoring.pp
@@ -0,0 +1,36 @@
+# === Class etcd::monitoring
+#
+class etcd::monitoring {
+    require etcd
+
+    # For now, this is not critical, but should probably be in the future.
+    nrpe::monitor_systemd_unit{ 'etcd':
+        require => Service['etcd'],
+    }
+
+    require_package 'libnagios-plugin-perl'
+
+    file { '/usr/local/bin/nrpe_etcd_cluster_health':
+        ensure  => present,
+        source  => 'puppet:///modules/etcd/etcd_cluster_health',
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0555',
+        require => Service['etcd'],
+    }
+
+    sudo::user { 'nagios_check_etcd':
+        user       => 'nagios',
+        privileges => ['ALL = NOPASSWD: 
/usr/local/bin/nrpe_etcd_cluster_health'],
+    }
+
+    nrpe::monitor_service{ 'etcd_cluster_health':
+        description  => 'Etcd cluster health',
+        nrpe_command => "/usr/local/bin/nrpe_etcd_cluster_health --url 
${::etcd::client_url}",
+        require      => [
+          File['/usr/local/bin/etcd-cluster-health'],
+          Sudo::User['nagios_check_etcd'],
+        ],
+    }
+
+}
diff --git a/modules/etcd/manifests/ssl.pp b/modules/etcd/manifests/ssl.pp
new file mode 100644
index 0000000..c13f8cc
--- /dev/null
+++ b/modules/etcd/manifests/ssl.pp
@@ -0,0 +1,65 @@
+# == Class etcd::ssl
+#
+# Copies the relevant certificates from the puppet/ssl directory to
+# where they can used for etcd.
+#
+# === Parameters
+#
+# [*puppet_cert_name*]
+#   The name on the puppet certificate.
+#
+# [*ssldir*]
+#   The directory where the puppet ssl certs are contained
+#
+class etcd::ssl($puppet_cert_name = $::fqdn, $ssldir = '/var/lib/puppet/ssl') {
+
+    file { '/var/lib/etcd/ssl':
+        ensure  => directory,
+        owner   => 'etcd',
+        group   => 'etcd',
+        mode    => '0500',
+        require => Package['etcd']
+    }
+
+    file { '/var/lib/etcd/ssl/certs':
+        ensure  => directory,
+        owner   => 'etcd',
+        group   => 'etcd',
+        mode    => '0500',
+    }
+
+    file { '/var/lib/etcd/ssl/certs/ca.pem':
+        ensure => present,
+        owner  => 'etcd',
+        group  => 'etcd',
+        mode   => '0400',
+        source => "${ssldir}/certs/ca.pem",
+        notify => Service['etcd'],
+    }
+
+    file { '/var/lib/etcd/ssl/certs/cert.pem':
+        ensure  => present,
+        owner   => 'etcd',
+        group   => 'etcd',
+        mode    => '0400',
+        source  => "${ssldir}/certs/${puppet_cert_name}.pem",
+        require => File['/var/lib/etcd/ssl/certs/ca.pem'],
+        notify  => Service['etcd'],
+    }
+
+    file { '/var/lib/etcd/ssl/private_keys':
+        ensure => directory,
+        owner  => 'etcd',
+        group  => 'etcd',
+        mode   => '0500',
+    }
+
+    file { '/var/lib/etcd/ssl/private_keys/server.key':
+        ensure => present,
+        owner  => 'etcd',
+        group  => 'etcd',
+        mode   => '0400',
+        source => "${ssldir}/private_keys/${puppet_cert_name}.pem",
+        notify => Service['etcd'],
+    }
+}
diff --git a/modules/etcd/templates/initscripts/etcd.systemd.erb 
b/modules/etcd/templates/initscripts/etcd.systemd.erb
new file mode 100644
index 0000000..c916eac
--- /dev/null
+++ b/modules/etcd/templates/initscripts/etcd.systemd.erb
@@ -0,0 +1,35 @@
+[Unit]
+Description=etcd
+
+[Service]
+User=etcd
+PermissionsStartOnly=true
+LimitNOFILE=infinity
+Environment=ETCD_DATA_DIR=<%= @etcd_data_dir %>
+Environment=ETCD_NAME=<%= @hostname %>
+<% if @cluster_state -%>
+Environment="ETCD_INITIAL_CLUSTER_STATE=<%= @cluster_state %>"
+<% end -%>
+<% if @peers_list -%>
+Environment="ETCD_INITIAL_CLUSTER=<%= @peers_list %>"
+<% end -%>
+<% if @srv_dns -%>
+Environment="ETCD_DISCOVERY_SRV=<%= @srv_dns %>"
+Environment=ETCD_DISCOVERY_FALLBACK=exit
+<% end -%>
+Environment=ETCD_INITIAL_ADVERTISE_PEER_URLS=<%= @peer_url %>
+Environment=ETCD_LISTEN_PEER_URLS=<%= @peer_url %>
+Environment=ETCD_LISTEN_CLIENT_URLS=<%= @client_url %>
+Environment=ETCD_ADVERTISE_CLIENT_URLS=<%= @client_url %>
+<% if @use_ssl -%>
+# TLS certs, see 
https://github.com/coreos/etcd/blob/v2.0.10/Documentation/security.md
+# Also note that peer auth is currently broken.
+Environment=ETCD_CERT_FILE=/var/lib/etcd/ssl/certs/cert.pem
+Environment=ETCD_KEY_FILE=/var/lib/etcd/ssl/private_keys/server.key
+<%- if @use_client_certs -%>
+Environment=ETCD_CA_FILE=/var/lib/etcd/ssl/certs/ca.pem
+<%- end -%>
+<% end -%>
+ExecStart=/usr/bin/etcd
+Restart=always
+RestartSec=10s

-- 
To view, visit https://gerrit.wikimedia.org/r/208928
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib80e3d3c3e46f9ff0b81c5dd675ce79184324576
Gerrit-PatchSet: 20
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Giuseppe Lavagetto <glavage...@wikimedia.org>
Gerrit-Reviewer: Alexandros Kosiaris <akosia...@wikimedia.org>
Gerrit-Reviewer: Filippo Giunchedi <fgiunch...@wikimedia.org>
Gerrit-Reviewer: Giuseppe Lavagetto <glavage...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to