Merge #361424: refactor lib.packagesFromDirectoryRecursive (v2)
[NixPkgs.git] / nixos / modules / services / networking / flannel.nix
blob95ad9d8374c0908b6221982fd6c8c14911670700
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
7 let
8   cfg = config.services.flannel;
10   networkConfig = lib.filterAttrs (n: v: v != null) {
11     Network = cfg.network;
12     SubnetLen = cfg.subnetLen;
13     SubnetMin = cfg.subnetMin;
14     SubnetMax = cfg.subnetMax;
15     Backend = cfg.backend;
16   };
19   options.services.flannel = {
20     enable = lib.mkEnableOption "flannel";
22     package = lib.mkPackageOption pkgs "flannel" { };
24     publicIp = lib.mkOption {
25       description = ''
26         IP accessible by other nodes for inter-host communication.
27         Defaults to the IP of the interface being used for communication.
28       '';
29       type = lib.types.nullOr lib.types.str;
30       default = null;
31     };
33     iface = lib.mkOption {
34       description = ''
35         Interface to use (IP or name) for inter-host communication.
36         Defaults to the interface for the default route on the machine.
37       '';
38       type = lib.types.nullOr lib.types.str;
39       default = null;
40     };
42     etcd = {
43       endpoints = lib.mkOption {
44         description = "Etcd endpoints";
45         type = lib.types.listOf lib.types.str;
46         default = [ "http://127.0.0.1:2379" ];
47       };
49       prefix = lib.mkOption {
50         description = "Etcd key prefix";
51         type = lib.types.str;
52         default = "/coreos.com/network";
53       };
55       caFile = lib.mkOption {
56         description = "Etcd certificate authority file";
57         type = lib.types.nullOr lib.types.path;
58         default = null;
59       };
61       certFile = lib.mkOption {
62         description = "Etcd cert file";
63         type = lib.types.nullOr lib.types.path;
64         default = null;
65       };
67       keyFile = lib.mkOption {
68         description = "Etcd key file";
69         type = lib.types.nullOr lib.types.path;
70         default = null;
71       };
72     };
74     kubeconfig = lib.mkOption {
75       description = ''
76         Path to kubeconfig to use for storing flannel config using the
77         Kubernetes API
78       '';
79       type = lib.types.nullOr lib.types.path;
80       default = null;
81     };
83     network = lib.mkOption {
84       description = " IPv4 network in CIDR format to use for the entire flannel network.";
85       type = lib.types.str;
86     };
88     nodeName = lib.mkOption {
89       description = ''
90         Needed when running with Kubernetes as backend as this cannot be auto-detected";
91       '';
92       type = lib.types.nullOr lib.types.str;
93       default = config.networking.fqdnOrHostName;
94       defaultText = lib.literalExpression "config.networking.fqdnOrHostName";
95       example = "node1.example.com";
96     };
98     storageBackend = lib.mkOption {
99       description = "Determines where flannel stores its configuration at runtime";
100       type = lib.types.enum [
101         "etcd"
102         "kubernetes"
103       ];
104       default = "etcd";
105     };
107     subnetLen = lib.mkOption {
108       description = ''
109         The size of the subnet allocated to each host. Defaults to 24 (i.e. /24)
110         unless the Network was configured to be smaller than a /24 in which case
111         it is one less than the network.
112       '';
113       type = lib.types.int;
114       default = 24;
115     };
117     subnetMin = lib.mkOption {
118       description = ''
119         The beginning of IP range which the subnet allocation should start with.
120         Defaults to the first subnet of Network.
121       '';
122       type = lib.types.nullOr lib.types.str;
123       default = null;
124     };
126     subnetMax = lib.mkOption {
127       description = ''
128         The end of IP range which the subnet allocation should start with.
129         Defaults to the last subnet of Network.
130       '';
131       type = lib.types.nullOr lib.types.str;
132       default = null;
133     };
135     backend = lib.mkOption {
136       description = "Type of backend to use and specific configurations for that backend.";
137       type = lib.types.attrs;
138       default = {
139         Type = "vxlan";
140       };
141     };
142   };
144   config = lib.mkIf cfg.enable {
145     systemd.services.flannel = {
146       description = "Flannel Service";
147       wantedBy = [ "multi-user.target" ];
148       after = [ "network.target" ];
149       environment =
150         {
151           FLANNELD_PUBLIC_IP = cfg.publicIp;
152           FLANNELD_IFACE = cfg.iface;
153         }
154         // lib.optionalAttrs (cfg.storageBackend == "etcd") {
155           FLANNELD_ETCD_ENDPOINTS = lib.concatStringsSep "," cfg.etcd.endpoints;
156           FLANNELD_ETCD_KEYFILE = cfg.etcd.keyFile;
157           FLANNELD_ETCD_CERTFILE = cfg.etcd.certFile;
158           FLANNELD_ETCD_CAFILE = cfg.etcd.caFile;
159           ETCDCTL_CERT = cfg.etcd.certFile;
160           ETCDCTL_KEY = cfg.etcd.keyFile;
161           ETCDCTL_CACERT = cfg.etcd.caFile;
162           ETCDCTL_ENDPOINTS = lib.concatStringsSep "," cfg.etcd.endpoints;
163           ETCDCTL_API = "3";
164         }
165         // lib.optionalAttrs (cfg.storageBackend == "kubernetes") {
166           FLANNELD_KUBE_SUBNET_MGR = "true";
167           FLANNELD_KUBECONFIG_FILE = cfg.kubeconfig;
168           NODE_NAME = cfg.nodeName;
169         };
170       path = [ pkgs.iptables ];
171       preStart = lib.optionalString (cfg.storageBackend == "etcd") ''
172         echo "setting network configuration"
173         until ${pkgs.etcd}/bin/etcdctl put /coreos.com/network/config '${builtins.toJSON networkConfig}'
174         do
175           echo "setting network configuration, retry"
176           sleep 1
177         done
178       '';
179       serviceConfig = {
180         ExecStart = "${cfg.package}/bin/flannel";
181         Restart = "always";
182         RestartSec = "10s";
183         RuntimeDirectory = "flannel";
184       };
185     };
187     services.etcd.enable = lib.mkDefault (
188       cfg.storageBackend == "etcd" && cfg.etcd.endpoints == [ "http://127.0.0.1:2379" ]
189     );
191     # for some reason, flannel doesn't let you configure this path
192     # see: https://github.com/coreos/flannel/blob/master/Documentation/configuration.md#configuration
193     environment.etc."kube-flannel/net-conf.json" = lib.mkIf (cfg.storageBackend == "kubernetes") {
194       source = pkgs.writeText "net-conf.json" (builtins.toJSON networkConfig);
195     };
196   };