Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reclass #1135

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions kapitan/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ def build_parser():
help="Select the inventory backend to use (default=reclass)",
)

inventory_backend_parser.add_argument(
"--compose-node-name",
help="Create same subfolder structure from inventory/targets inside compiled folder",
action="store_true",
default=from_dot_kapitan("compile", "compose-node-name", False),
)

eval_parser = subparser.add_parser("eval", aliases=["e"], help="evaluate jsonnet file")
eval_parser.add_argument("jsonnet_file", type=str)
eval_parser.set_defaults(func=trigger_eval, name="eval")
Expand Down Expand Up @@ -283,17 +290,6 @@ def build_parser():
default=from_dot_kapitan("compile", "use-go-jsonnet", False),
)

# compose-node-name should be used in conjunction with reclass
# config "compose_node_name: true". This allows us to make the same subfolder
# structure in the inventory folder inside the compiled folder
# https://github.com/kapicorp/kapitan/issues/932
compile_parser.add_argument(
"--compose-node-name",
help="Create same subfolder structure from inventory/targets inside compiled folder",
action="store_true",
default=from_dot_kapitan("compile", "compose-node-name", False),
)

compile_parser.add_argument(
"--schemas-path",
default=from_dot_kapitan("validate", "schemas-path", "./schemas"),
Expand Down Expand Up @@ -666,6 +662,10 @@ def main():
cached.args[args.name] = args
if "inventory_backend" in args:
cached.args["inventory-backend"] = args.inventory_backend
cached.args.setdefault("global", {}).setdefault("inventory-backend", args.inventory_backend)

if "compose_node_name" in args:
cached.args.setdefault("global", {}).setdefault("compose_node_name", args.compose_node_name)

if hasattr(args, "verbose") and args.verbose:
setup_logging(level=logging.DEBUG, force=True)
Expand Down
75 changes: 48 additions & 27 deletions kapitan/inventory/inv_reclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,36 @@


class ReclassInventory(Inventory):

def render_targets(self, targets: list = None, ignore_class_notfound: bool = False):
"""
Runs a reclass inventory in inventory_path
(same output as running ./reclass.py -b inv_base_uri/ --inventory)
Will attempt to read reclass config from 'reclass-config.yml' otherwise
it will fall back to the default config.
Returns a reclass style dictionary

Does not throw errors if a class is not found while ignore_class_notfound is specified
"""
reclass_config = get_reclass_config(self.inventory_path)
reclass_config.setdefault("ignore_class_notfound", ignore_class_notfound)
reclass_config["compose_node_name"] = self.compose_target_name
def __init__(self, inventory_path, compose_target_name=False):
super().__init__(inventory_path, compose_target_name=compose_target_name)

self.reclass_config = get_reclass_config(inventory_path)

compose_node_name = self.reclass_config.get("compose_node_name", self.compose_target_name)
if compose_node_name != self.compose_target_name:
logger.warning(
f"reclass-config.yml has compose_node_name={compose_node_name} but kapitan has --compose-node-name={self.compose_target_name}."
)
logger.warning(
f"Using --compose-node-name={self.compose_target_name}: Please update reclass-config.yml to remove this warning."
)
compose_node_name = self.compose_target_name

self.reclass_config.setdefault("ignore_class_notfound", True)

try:
storage = reclass.get_storage(
reclass_config["storage_type"],
reclass_config["nodes_uri"],
reclass_config["classes_uri"],
reclass_config["compose_node_name"],
self.reclass_config["storage_type"],
self.reclass_config["nodes_uri"],
self.reclass_config["classes_uri"],
compose_node_name,
)
class_mappings = reclass_config.get("class_mappings") # this defaults to None (disabled)
_reclass = reclass.core.Core(storage, class_mappings, reclass.settings.Settings(reclass_config))
rendered_inventory = _reclass.inventory()

# store parameters and classes
for target_name, rendered_target in rendered_inventory["nodes"].items():
self.targets[target_name].parameters = rendered_target["parameters"]
self.targets[target_name].classes = rendered_target["classes"]
class_mappings = self.reclass_config.get("class_mappings") # this defaults to None (disabled)
_reclass = reclass.core.Core(
storage, class_mappings, reclass.settings.Settings(self.reclass_config)
)
self.rendered_inventory = _reclass.inventory()

except ReclassException as e:
if isinstance(e, NotFoundError):
Expand All @@ -53,14 +53,33 @@ def render_targets(self, targets: list = None, ignore_class_notfound: bool = Fal
raise InventoryError(e.message)


def render_targets(
self,
targets: list = None,
ignore_class_notfound: bool = False,
):
"""
Runs a reclass inventory in inventory_path
(same output as running ./reclass.py -b inv_base_uri/ --inventory)
Will attempt to read reclass config from 'reclass-config.yml' otherwise
it will fall back to the default config.
Returns a reclass style dictionary

Does not throw errors if a class is not found while ignore_class_notfound is specified
"""
# store parameters and classes
for target_name, rendered_target in self.rendered_inventory["nodes"].items():
self.targets[target_name].parameters = rendered_target["parameters"]
self.targets[target_name].classes = rendered_target["classes"]


def get_reclass_config(inventory_path: str) -> dict:
# set default values initially
reclass_config = {
"storage_type": "yaml_fs",
"inventory_base_uri": inventory_path,
"nodes_uri": "targets",
"classes_uri": "classes",
"compose_node_name": False,
"allow_none_override": True,
}
try:
Expand All @@ -79,7 +98,9 @@ def get_reclass_config(inventory_path: str) -> dict:
for key, value in config.items():
reclass_config[key] = value
else:
logger.debug(f"Reclass config: Empty config file at {cfg_file}. Using reclass inventory config defaults")
logger.debug(
f"Reclass config: Empty config file at {cfg_file}. Using reclass inventory config defaults"
)
else:
logger.debug("Inventory reclass: No config file found. Using reclass inventory config defaults")

Expand Down
5 changes: 3 additions & 2 deletions kapitan/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,15 @@ def get_inventory(inventory_path) -> Inventory:

# select inventory backend
backend_id = cached.args.get("inventory-backend")
compose_node_name = cached.args["global"].get("compose_node_name")
backend = AVAILABLE_BACKENDS.get(backend_id)
inventory_backend: Inventory = None
if backend != None:
logger.debug(f"Using {backend_id} as inventory backend")
inventory_backend = backend(inventory_path)
inventory_backend = backend(inventory_path, compose_node_name)
else:
logger.debug(f"Backend {backend_id} is unknown, falling back to reclass as inventory backend")
inventory_backend = ReclassInventory(inventory_path)
inventory_backend = ReclassInventory(inventory_path, compose_node_name)

inventory_backend.search_targets()

Expand Down
Loading