| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  | { config, lib, pkgs, ... }: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | with lib; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  |   cfg = config.services.etcd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | in { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   options.services.etcd = { | 
					
						
							|  |  |  |     enable = mkOption { | 
					
						
							|  |  |  |       description = "Whether to enable etcd."; | 
					
						
							|  |  |  |       default = false; | 
					
						
							| 
									
										
										
										
											2015-04-25 14:29:13 +02:00
										 |  |  |       type = types.bool; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     name = mkOption { | 
					
						
							|  |  |  |       description = "Etcd unique node name."; | 
					
						
							|  |  |  |       default = config.networking.hostName; | 
					
						
							|  |  |  |       type = types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     advertiseClientUrls = mkOption { | 
					
						
							|  |  |  |       description = "Etcd list of this member's client URLs to advertise to the rest of the cluster."; | 
					
						
							|  |  |  |       default = cfg.listenClientUrls; | 
					
						
							|  |  |  |       type = types.listOf types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     listenClientUrls = mkOption { | 
					
						
							|  |  |  |       description = "Etcd list of URLs to listen on for client traffic."; | 
					
						
							| 
									
										
										
										
											2016-08-25 14:41:47 +02:00
										 |  |  |       default = ["http://127.0.0.1:2379"]; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       type = types.listOf types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     listenPeerUrls = mkOption { | 
					
						
							|  |  |  |       description = "Etcd list of URLs to listen on for peer traffic."; | 
					
						
							| 
									
										
										
										
											2016-08-25 14:41:47 +02:00
										 |  |  |       default = ["http://127.0.0.1:2380"]; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       type = types.listOf types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     initialAdvertisePeerUrls = mkOption { | 
					
						
							|  |  |  |       description = "Etcd list of this member's peer URLs to advertise to rest of the cluster."; | 
					
						
							|  |  |  |       default = cfg.listenPeerUrls; | 
					
						
							|  |  |  |       type = types.listOf types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     initialCluster = mkOption { | 
					
						
							|  |  |  |       description = "Etcd initial cluster configuration for bootstrapping."; | 
					
						
							| 
									
										
										
										
											2016-08-24 20:11:39 +02:00
										 |  |  |       default = ["${cfg.name}=http://127.0.0.1:2380"]; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       type = types.listOf types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     initialClusterState = mkOption { | 
					
						
							|  |  |  |       description = "Etcd initial cluster configuration for bootstrapping."; | 
					
						
							|  |  |  |       default = "new"; | 
					
						
							|  |  |  |       type = types.enum ["new" "existing"]; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     initialClusterToken = mkOption { | 
					
						
							|  |  |  |       description = "Etcd initial cluster token for etcd cluster during bootstrap."; | 
					
						
							|  |  |  |       default = "etcd-cluster"; | 
					
						
							|  |  |  |       type = types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     discovery = mkOption { | 
					
						
							|  |  |  |       description = "Etcd discovery url"; | 
					
						
							|  |  |  |       default = ""; | 
					
						
							|  |  |  |       type = types.str; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 20:11:39 +02:00
										 |  |  |     clientCertAuth = mkOption { | 
					
						
							|  |  |  |       description = "Whether to use certs for client authentication"; | 
					
						
							|  |  |  |       default = false; | 
					
						
							|  |  |  |       type = types.bool; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trustedCaFile = mkOption { | 
					
						
							|  |  |  |       description = "Certificate authority file to use for clients"; | 
					
						
							|  |  |  |       default = null; | 
					
						
							|  |  |  |       type = types.nullOr types.path; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     certFile = mkOption { | 
					
						
							|  |  |  |       description = "Cert file to use for clients"; | 
					
						
							|  |  |  |       default = null; | 
					
						
							|  |  |  |       type = types.nullOr types.path; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     keyFile = mkOption { | 
					
						
							|  |  |  |       description = "Key file to use for clients"; | 
					
						
							|  |  |  |       default = null; | 
					
						
							|  |  |  |       type = types.nullOr types.path; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peerCertFile = mkOption { | 
					
						
							|  |  |  |       description = "Cert file to use for peer to peer communication"; | 
					
						
							|  |  |  |       default = cfg.certFile; | 
					
						
							|  |  |  |       type = types.nullOr types.path; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peerKeyFile = mkOption { | 
					
						
							|  |  |  |       description = "Key file to use for peer to peer communication"; | 
					
						
							|  |  |  |       default = cfg.keyFile; | 
					
						
							|  |  |  |       type = types.nullOr types.path; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peerTrustedCaFile = mkOption { | 
					
						
							|  |  |  |       description = "Certificate authority file to use for peer to peer communication"; | 
					
						
							|  |  |  |       default = cfg.trustedCaFile; | 
					
						
							|  |  |  |       type = types.nullOr types.path; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peerClientCertAuth = mkOption { | 
					
						
							|  |  |  |       description = "Whether to check all incoming peer requests from the cluster for valid client certificates signed by the supplied CA"; | 
					
						
							|  |  |  |       default = false; | 
					
						
							|  |  |  |       type = types.bool; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |     extraConf = mkOption { | 
					
						
							|  |  |  |       description = ''
 | 
					
						
							|  |  |  |         Etcd extra configuration. See | 
					
						
							| 
									
										
										
										
											2017-04-16 00:24:53 +02:00
										 |  |  |         <link xlink:href='https://github.com/coreos/etcd/blob/master/Documentation/op-guide/configuration.md#configuration-flags' /> | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       '';
 | 
					
						
							|  |  |  |       type = types.attrsOf types.str; | 
					
						
							|  |  |  |       default = {}; | 
					
						
							|  |  |  |       example = literalExample ''
 | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2016-01-17 19:34:55 +01:00
										 |  |  |           "CORS" = "*"; | 
					
						
							|  |  |  |           "NAME" = "default-name"; | 
					
						
							|  |  |  |           "MAX_RESULT_BUFFER" = "1024"; | 
					
						
							|  |  |  |           "MAX_CLUSTER_SIZE" = "9"; | 
					
						
							|  |  |  |           "MAX_RETRY_ATTEMPTS" = "3"; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dataDir = mkOption { | 
					
						
							|  |  |  |       type = types.path; | 
					
						
							|  |  |  |       default = "/var/lib/etcd"; | 
					
						
							|  |  |  |       description = "Etcd data directory."; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   config = mkIf cfg.enable { | 
					
						
							| 
									
										
										
										
											2019-02-24 16:04:37 -05:00
										 |  |  |     systemd.tmpfiles.rules = [ | 
					
						
							|  |  |  |       "d '${cfg.dataDir}' 0700 etcd - - -" | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |     systemd.services.etcd = { | 
					
						
							| 
									
										
										
										
											2016-09-12 16:34:10 +02:00
										 |  |  |       description = "etcd key-value store"; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       wantedBy = [ "multi-user.target" ]; | 
					
						
							| 
									
										
										
										
											2016-09-12 16:34:10 +02:00
										 |  |  |       after = [ "network.target" ]; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 20:11:39 +02:00
										 |  |  |       environment = (filterAttrs (n: v: v != null) { | 
					
						
							| 
									
										
										
										
											2014-11-23 01:25:53 +01:00
										 |  |  |         ETCD_NAME = cfg.name; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |         ETCD_DISCOVERY = cfg.discovery; | 
					
						
							|  |  |  |         ETCD_DATA_DIR = cfg.dataDir; | 
					
						
							|  |  |  |         ETCD_ADVERTISE_CLIENT_URLS = concatStringsSep "," cfg.advertiseClientUrls; | 
					
						
							|  |  |  |         ETCD_LISTEN_CLIENT_URLS = concatStringsSep "," cfg.listenClientUrls; | 
					
						
							|  |  |  |         ETCD_LISTEN_PEER_URLS = concatStringsSep "," cfg.listenPeerUrls; | 
					
						
							|  |  |  |         ETCD_INITIAL_ADVERTISE_PEER_URLS = concatStringsSep "," cfg.initialAdvertisePeerUrls; | 
					
						
							| 
									
										
										
										
											2016-08-24 20:11:39 +02:00
										 |  |  |         ETCD_PEER_TRUSTED_CA_FILE = cfg.peerTrustedCaFile; | 
					
						
							|  |  |  |         ETCD_PEER_CERT_FILE = cfg.peerCertFile; | 
					
						
							|  |  |  |         ETCD_PEER_KEY_FILE = cfg.peerKeyFile; | 
					
						
							|  |  |  |         ETCD_CLIENT_CERT_AUTH = toString cfg.peerClientCertAuth; | 
					
						
							|  |  |  |         ETCD_TRUSTED_CA_FILE = cfg.trustedCaFile; | 
					
						
							|  |  |  |         ETCD_CERT_FILE = cfg.certFile; | 
					
						
							|  |  |  |         ETCD_KEY_FILE = cfg.keyFile; | 
					
						
							|  |  |  |       }) // (optionalAttrs (cfg.discovery == ""){ | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |         ETCD_INITIAL_CLUSTER = concatStringsSep "," cfg.initialCluster; | 
					
						
							|  |  |  |         ETCD_INITIAL_CLUSTER_STATE = cfg.initialClusterState; | 
					
						
							|  |  |  |         ETCD_INITIAL_CLUSTER_TOKEN = cfg.initialClusterToken; | 
					
						
							|  |  |  |       }) // (mapAttrs' (n: v: nameValuePair "ETCD_${n}" v) cfg.extraConf); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-12 16:34:10 +02:00
										 |  |  |       unitConfig = { | 
					
						
							|  |  |  |         Documentation = "https://github.com/coreos/etcd"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       serviceConfig = { | 
					
						
							| 
									
										
										
										
											2016-03-26 22:01:00 -04:00
										 |  |  |         Type = "notify"; | 
					
						
							| 
									
										
										
										
											2016-06-13 23:32:16 +02:00
										 |  |  |         ExecStart = "${pkgs.etcd.bin}/bin/etcd"; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |         User = "etcd"; | 
					
						
							| 
									
										
										
										
											2016-09-12 16:34:10 +02:00
										 |  |  |         LimitNOFILE = 40000; | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     environment.systemPackages = [ pkgs.etcdctl ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 01:58:35 +02:00
										 |  |  |     users.users = singleton { | 
					
						
							| 
									
										
										
										
											2014-11-15 16:27:27 +01:00
										 |  |  |       name = "etcd"; | 
					
						
							|  |  |  |       uid = config.ids.uids.etcd; | 
					
						
							|  |  |  |       description = "Etcd daemon user"; | 
					
						
							|  |  |  |       home = cfg.dataDir; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } |