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