feat: interface and lib refactoring

This commit is contained in:
Jaka Hudoklin 2019-03-07 18:02:26 +01:00
parent e260ad9bb4
commit 5d8b66f8a0
No known key found for this signature in database
GPG key ID: 6A08896BFD32BD95
10 changed files with 111 additions and 88 deletions

View file

@ -1,14 +1,21 @@
{ pkgs ? import <nixpkgs> {}, lib ? pkgs.lib }:
let
lib' = lib.extend (lib: self: import ./lib.nix { inherit lib pkgs; });
with lib;
specialArgs' = {
let
kubenixLib = import ./lib { inherit lib pkgs; };
lib' = lib.extend (lib: self: import ./lib/extra.nix { inherit lib pkgs; });
defaultSpecialArgs = {
inherit kubenix;
};
evalKubernetesModules = {module ? null, modules ? [module], specialArgs ? specialArgs', ...}@attrs: let
attrs' = lib.filterAttrs (n: _: n != "module") attrs;
evalModules = {
module ? null,
modules ? [module],
specialArgs ? defaultSpecialArgs, ...
}@attrs: let
attrs' = filterAttrs (n: _: n != "module") attrs;
in lib'.evalModules (attrs' // {
inherit specialArgs modules;
args = {
@ -17,14 +24,11 @@ let
};
});
buildResources = args:
(evalKubernetesModules args).config.kubernetes.generated;
modules = import ./modules;
kubenix = {
inherit evalKubernetesModules buildResources kubenix;
inherit evalModules kubenix;
lib = lib';
lib = kubenixLib;
} // modules;
in kubenix

6
lib/default.nix Normal file
View file

@ -0,0 +1,6 @@
{ lib, pkgs }:
(import ./extra.nix { inherit pkgs lib; }) // {
k8s = import ./k8s.nix { inherit lib; };
docker = import ./docker.nix { inherit lib pkgs; };
}

15
lib/docker.nix Normal file
View file

@ -0,0 +1,15 @@
{ lib, pkgs }:
with lib;
{
copyDockerImages = { images, dest, args ? "" }:
pkgs.writeScriptBin "copy-docker-images" (concatMapStrings (image: ''
#!${pkgs.bash}/bin/bash
set -e
echo "copying ${image.imageName}:${image.imageTag}"
${pkgs.skopeo}/bin/skopeo copy ${args} $@ docker-archive:${image} ${dest}/${image.imageName}:${image.imageTag}
'') images);
}

View file

@ -1,9 +1,8 @@
{lib, pkgs}:
{ lib, pkgs }:
with lib;
let
in rec {
rec {
moduleToAttrs = value:
if isAttrs value
then mapAttrs (n: v: moduleToAttrs v) (filterAttrs (n: v: !(hasPrefix "_" n) && v != null) value)
@ -39,8 +38,7 @@ in rec {
exp = base: exp: foldr (value: acc: acc * base) 1 (range 1 exp);
octalToDecimal = value:
(foldr (char: acc: {
octalToDecimal = value: (foldr (char: acc: {
i = acc.i + 1;
value = acc.value + (toInt char) * (exp 8 acc.i);
}) {i = 0; value = 0;} (stringToCharacters value)).value;

54
lib/k8s.nix Normal file
View file

@ -0,0 +1,54 @@
{ lib }:
with lib;
rec {
mkSecretOption = {description ? "", default ? null}: mkOption {
inherit description;
type = types.nullOr (types.submodule {
options = {
name = mkOption {
description = "Name of the secret where secret is stored";
type = types.str;
};
key = mkOption {
description = "Name of the key where secret is stored";
type = types.str;
};
};
config = mkDefault (if default == null then {} else default);
});
default = {};
};
secretToEnv = value: {
valueFrom.secretKeyRef = {
inherit (value) name key;
};
};
# Creates kubernetes list from a list of kubernetes objects
mkList = { items, labels ? {} }: {
kind = "List";
apiVersion = "v1";
inherit items labels;
};
# Creates hashed kubernetes list from a list of kubernetes objects
mkHashedList = { items, labels ? {} }: let
hash = builtins.hashString "sha1" (builtins.toJSON items);
labeledItems = map (item: recursiveUpdate item {
metadata.labels."kubenix/hash" = hash;
}) items;
in mkList {
items = labeledItems;
labels = {
"kubenix/hash" = hash;
} // labels;
};
}

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{ config, lib, pkgs, k8s, ... }:
with lib;
@ -32,12 +32,6 @@ let
) resources
);
toKubernetesList = resources: {
kind = "List";
apiVersion = "v1";
items = resources;
};
apiOptions = { config, ... }: {
options = {
definitions = mkOption {
@ -114,7 +108,8 @@ let
indexOf = lst: value:
head (filter (v: v != -1) (imap0 (i: v: if v == value then i else -1) lst));
in {
imports = [./lib.nix];
# expose k8s helper methods through arg in modules
config._module.args.k8s = import ../../lib/k8s.nix { inherit lib; };
options.kubernetes.version = mkOption {
description = "Kubernetes version to use";
@ -222,7 +217,7 @@ in {
}) cfg.customResources;
options.kubernetes.objects = mkOption {
description = "Attribute set of kubernetes objects";
description = "List of generated kubernetes objects";
type = types.listOf types.attrs;
apply = items: sort (r1: r2:
if elem r1.kind cfg.resourceOrder && elem r2.kind cfg.resourceOrder
@ -239,25 +234,11 @@ in {
) cfg.api.resources);
options.kubernetes.generated = mkOption {
description = "Generated kubernetes list object";
type = types.attrs;
description = "Generated json file";
};
config.kubernetes.generated = let
kubernetesList = toKubernetesList cfg.objects;
hashedList = kubernetesList // {
labels."kubenix/build" = cfg.hash;
items = map (resource: recursiveUpdate resource {
metadata.labels."kubenix/build" = cfg.hash;
}) kubernetesList.items;
config.kubernetes.generated = k8s.mkHashedList {
items = config.kubernetes.objects;
};
in hashedList;
options.kubernetes.hash = mkOption {
type = types.str;
description = "Output hash";
};
config.kubernetes.hash = builtins.hashString "sha1" (builtins.toJSON cfg.objects);
}

View file

@ -1,35 +0,0 @@
{ lib, ... }:
with lib;
let
k8s = {
mkSecretOption = {description ? "", default ? null}: mkOption {
inherit description;
type = types.nullOr (types.submodule {
options = {
name = mkOption {
description = "Name of the secret where secret is stored";
type = types.str;
};
key = mkOption {
description = "Name of the key where secret is stored";
type = types.str;
};
};
config = mkDefault (if default == null then {} else default);
});
default = {};
};
secretToEnv = value: {
valueFrom.secretKeyRef = {
inherit (value) name key;
};
};
};
in {
_module.args.k8s = k8s;
}

View file

@ -71,7 +71,7 @@ let
nixosTesting.makeTest {
inherit name;
nodes.kube = { config, pkgs, lib, nodes, ... }: {
nodes.kube = { config, pkgs, nodes, ... }: {
imports = [ kubernetesBaseConfig ];
services.kubernetes = {
roles = ["master" "node"];
@ -113,14 +113,14 @@ let
config._module.args.test = config;
}] ++ cfg.defaults;
test = (kubenix.evalKubernetesModules {
test = (kubenix.evalModules {
check = false;
inherit modules;
}).config.test;
evaled =
if test.enable
then builtins.trace "testing ${test.name}" (kubenix.evalKubernetesModules {
then builtins.trace "testing ${test.name}" (kubenix.evalModules {
inherit modules;
})
else {success = false;};

View file

@ -1,6 +1,6 @@
{ pkgs ? import <nixpkgs> {}
, kubenix ? import ../. {inherit pkgs;}
, lib ? kubenix.lib
, lib ? pkgs.lib
, kubenix ? import ../. { inherit pkgs lib; }
, k8sVersions ? ["1.7" "1.8" "1.9" "1.10" "1.11" "1.12" "1.13"]
# whether any testing error should throw an error
@ -14,7 +14,7 @@ let
tests = listToAttrs (map (version: let
version' = replaceStrings ["."] ["_"] version;
in nameValuePair "v${version'}" (evalModules {
in nameValuePair "v${version'}" (kubenix.evalModules {
modules = [
kubenix.testing

View file

@ -1,7 +1,7 @@
{ config, lib, test, pkgs, kubenix, k8s, helm, ... }:
{ config, lib, test, pkgs, kubenix, helm, ... }:
with lib;
with k8s;
with kubenix.lib;
with pkgs.dockerTools;
let
@ -56,7 +56,7 @@ in {
$kube->waitUntilSucceeds("docker load < ${postgresql}");
$kube->waitUntilSucceeds("docker load < ${postgresqlExporter}");
$kube->waitUntilSucceeds("docker load < ${minideb}");
$kube->waitUntilSucceeds("kubectl apply -f ${toYAML config.kubernetes.generated}");
$kube->waitUntilSucceeds("kubectl apply -f ${toYAML config.kubernetes.objects}");
$kube->waitUntilSucceeds("PGPASSWORD=postgres ${pkgs.postgresql}/bin/psql -h app-psql-postgresql.test.svc.cluster.local -U postgres -l");
'';
};