mirror of
https://github.com/TECHNOFAB11/kubenix.git
synced 2025-12-12 16:10:05 +01:00
feat: interface and lib refactoring
This commit is contained in:
parent
e260ad9bb4
commit
5d8b66f8a0
10 changed files with 111 additions and 88 deletions
24
default.nix
24
default.nix
|
|
@ -1,14 +1,21 @@
|
||||||
{ pkgs ? import <nixpkgs> {}, lib ? pkgs.lib }:
|
{ pkgs ? import <nixpkgs> {}, lib ? pkgs.lib }:
|
||||||
|
|
||||||
let
|
with lib;
|
||||||
lib' = lib.extend (lib: self: import ./lib.nix { inherit lib pkgs; });
|
|
||||||
|
|
||||||
specialArgs' = {
|
let
|
||||||
|
kubenixLib = import ./lib { inherit lib pkgs; };
|
||||||
|
lib' = lib.extend (lib: self: import ./lib/extra.nix { inherit lib pkgs; });
|
||||||
|
|
||||||
|
defaultSpecialArgs = {
|
||||||
inherit kubenix;
|
inherit kubenix;
|
||||||
};
|
};
|
||||||
|
|
||||||
evalKubernetesModules = {module ? null, modules ? [module], specialArgs ? specialArgs', ...}@attrs: let
|
evalModules = {
|
||||||
attrs' = lib.filterAttrs (n: _: n != "module") attrs;
|
module ? null,
|
||||||
|
modules ? [module],
|
||||||
|
specialArgs ? defaultSpecialArgs, ...
|
||||||
|
}@attrs: let
|
||||||
|
attrs' = filterAttrs (n: _: n != "module") attrs;
|
||||||
in lib'.evalModules (attrs' // {
|
in lib'.evalModules (attrs' // {
|
||||||
inherit specialArgs modules;
|
inherit specialArgs modules;
|
||||||
args = {
|
args = {
|
||||||
|
|
@ -17,14 +24,11 @@ let
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
buildResources = args:
|
|
||||||
(evalKubernetesModules args).config.kubernetes.generated;
|
|
||||||
|
|
||||||
modules = import ./modules;
|
modules = import ./modules;
|
||||||
|
|
||||||
kubenix = {
|
kubenix = {
|
||||||
inherit evalKubernetesModules buildResources kubenix;
|
inherit evalModules kubenix;
|
||||||
|
|
||||||
lib = lib';
|
lib = kubenixLib;
|
||||||
} // modules;
|
} // modules;
|
||||||
in kubenix
|
in kubenix
|
||||||
|
|
|
||||||
6
lib/default.nix
Normal file
6
lib/default.nix
Normal 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
15
lib/docker.nix
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
{lib, pkgs}:
|
{ lib, pkgs }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
rec {
|
||||||
in rec {
|
|
||||||
moduleToAttrs = value:
|
moduleToAttrs = value:
|
||||||
if isAttrs value
|
if isAttrs value
|
||||||
then mapAttrs (n: v: moduleToAttrs v) (filterAttrs (n: v: !(hasPrefix "_" n) && v != null) value)
|
then mapAttrs (n: v: moduleToAttrs v) (filterAttrs (n: v: !(hasPrefix "_" n) && v != null) value)
|
||||||
|
|
@ -39,9 +38,8 @@ in rec {
|
||||||
|
|
||||||
exp = base: exp: foldr (value: acc: acc * base) 1 (range 1 exp);
|
exp = base: exp: foldr (value: acc: acc * base) 1 (range 1 exp);
|
||||||
|
|
||||||
octalToDecimal = value:
|
octalToDecimal = value: (foldr (char: acc: {
|
||||||
(foldr (char: acc: {
|
i = acc.i + 1;
|
||||||
i = acc.i + 1;
|
value = acc.value + (toInt char) * (exp 8 acc.i);
|
||||||
value = acc.value + (toInt char) * (exp 8 acc.i);
|
}) {i = 0; value = 0;} (stringToCharacters value)).value;
|
||||||
}) {i = 0; value = 0;} (stringToCharacters value)).value;
|
|
||||||
}
|
}
|
||||||
54
lib/k8s.nix
Normal file
54
lib/k8s.nix
Normal 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, k8s, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
|
@ -32,12 +32,6 @@ let
|
||||||
) resources
|
) resources
|
||||||
);
|
);
|
||||||
|
|
||||||
toKubernetesList = resources: {
|
|
||||||
kind = "List";
|
|
||||||
apiVersion = "v1";
|
|
||||||
items = resources;
|
|
||||||
};
|
|
||||||
|
|
||||||
apiOptions = { config, ... }: {
|
apiOptions = { config, ... }: {
|
||||||
options = {
|
options = {
|
||||||
definitions = mkOption {
|
definitions = mkOption {
|
||||||
|
|
@ -114,7 +108,8 @@ let
|
||||||
indexOf = lst: value:
|
indexOf = lst: value:
|
||||||
head (filter (v: v != -1) (imap0 (i: v: if v == value then i else -1) lst));
|
head (filter (v: v != -1) (imap0 (i: v: if v == value then i else -1) lst));
|
||||||
in {
|
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 {
|
options.kubernetes.version = mkOption {
|
||||||
description = "Kubernetes version to use";
|
description = "Kubernetes version to use";
|
||||||
|
|
@ -222,7 +217,7 @@ in {
|
||||||
}) cfg.customResources;
|
}) cfg.customResources;
|
||||||
|
|
||||||
options.kubernetes.objects = mkOption {
|
options.kubernetes.objects = mkOption {
|
||||||
description = "Attribute set of kubernetes objects";
|
description = "List of generated kubernetes objects";
|
||||||
type = types.listOf types.attrs;
|
type = types.listOf types.attrs;
|
||||||
apply = items: sort (r1: r2:
|
apply = items: sort (r1: r2:
|
||||||
if elem r1.kind cfg.resourceOrder && elem r2.kind cfg.resourceOrder
|
if elem r1.kind cfg.resourceOrder && elem r2.kind cfg.resourceOrder
|
||||||
|
|
@ -239,25 +234,11 @@ in {
|
||||||
) cfg.api.resources);
|
) cfg.api.resources);
|
||||||
|
|
||||||
options.kubernetes.generated = mkOption {
|
options.kubernetes.generated = mkOption {
|
||||||
|
description = "Generated kubernetes list object";
|
||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
description = "Generated json file";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config.kubernetes.generated = let
|
config.kubernetes.generated = k8s.mkHashedList {
|
||||||
kubernetesList = toKubernetesList cfg.objects;
|
items = config.kubernetes.objects;
|
||||||
|
|
||||||
hashedList = kubernetesList // {
|
|
||||||
labels."kubenix/build" = cfg.hash;
|
|
||||||
items = map (resource: recursiveUpdate resource {
|
|
||||||
metadata.labels."kubenix/build" = cfg.hash;
|
|
||||||
}) kubernetesList.items;
|
|
||||||
};
|
|
||||||
in hashedList;
|
|
||||||
|
|
||||||
options.kubernetes.hash = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "Output hash";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config.kubernetes.hash = builtins.hashString "sha1" (builtins.toJSON cfg.objects);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -71,7 +71,7 @@ let
|
||||||
nixosTesting.makeTest {
|
nixosTesting.makeTest {
|
||||||
inherit name;
|
inherit name;
|
||||||
|
|
||||||
nodes.kube = { config, pkgs, lib, nodes, ... }: {
|
nodes.kube = { config, pkgs, nodes, ... }: {
|
||||||
imports = [ kubernetesBaseConfig ];
|
imports = [ kubernetesBaseConfig ];
|
||||||
services.kubernetes = {
|
services.kubernetes = {
|
||||||
roles = ["master" "node"];
|
roles = ["master" "node"];
|
||||||
|
|
@ -113,14 +113,14 @@ let
|
||||||
config._module.args.test = config;
|
config._module.args.test = config;
|
||||||
}] ++ cfg.defaults;
|
}] ++ cfg.defaults;
|
||||||
|
|
||||||
test = (kubenix.evalKubernetesModules {
|
test = (kubenix.evalModules {
|
||||||
check = false;
|
check = false;
|
||||||
inherit modules;
|
inherit modules;
|
||||||
}).config.test;
|
}).config.test;
|
||||||
|
|
||||||
evaled =
|
evaled =
|
||||||
if test.enable
|
if test.enable
|
||||||
then builtins.trace "testing ${test.name}" (kubenix.evalKubernetesModules {
|
then builtins.trace "testing ${test.name}" (kubenix.evalModules {
|
||||||
inherit modules;
|
inherit modules;
|
||||||
})
|
})
|
||||||
else {success = false;};
|
else {success = false;};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{ pkgs ? import <nixpkgs> {}
|
{ pkgs ? import <nixpkgs> {}
|
||||||
, kubenix ? import ../. {inherit pkgs;}
|
, lib ? pkgs.lib
|
||||||
, lib ? kubenix.lib
|
, kubenix ? import ../. { inherit pkgs lib; }
|
||||||
, k8sVersions ? ["1.7" "1.8" "1.9" "1.10" "1.11" "1.12" "1.13"]
|
, k8sVersions ? ["1.7" "1.8" "1.9" "1.10" "1.11" "1.12" "1.13"]
|
||||||
|
|
||||||
# whether any testing error should throw an error
|
# whether any testing error should throw an error
|
||||||
|
|
@ -14,7 +14,7 @@ let
|
||||||
|
|
||||||
tests = listToAttrs (map (version: let
|
tests = listToAttrs (map (version: let
|
||||||
version' = replaceStrings ["."] ["_"] version;
|
version' = replaceStrings ["."] ["_"] version;
|
||||||
in nameValuePair "v${version'}" (evalModules {
|
in nameValuePair "v${version'}" (kubenix.evalModules {
|
||||||
modules = [
|
modules = [
|
||||||
kubenix.testing
|
kubenix.testing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{ config, lib, test, pkgs, kubenix, k8s, helm, ... }:
|
{ config, lib, test, pkgs, kubenix, helm, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
with k8s;
|
with kubenix.lib;
|
||||||
with pkgs.dockerTools;
|
with pkgs.dockerTools;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
@ -56,7 +56,7 @@ in {
|
||||||
$kube->waitUntilSucceeds("docker load < ${postgresql}");
|
$kube->waitUntilSucceeds("docker load < ${postgresql}");
|
||||||
$kube->waitUntilSucceeds("docker load < ${postgresqlExporter}");
|
$kube->waitUntilSucceeds("docker load < ${postgresqlExporter}");
|
||||||
$kube->waitUntilSucceeds("docker load < ${minideb}");
|
$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");
|
$kube->waitUntilSucceeds("PGPASSWORD=postgres ${pkgs.postgresql}/bin/psql -h app-psql-postgresql.test.svc.cluster.local -U postgres -l");
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue