def test_compile_config_default_folder(self, fname_param_config): """Folder location. This is tricky because it depends on whether or not the user specified a config file and whether or not he also specified the "--folder" flag. """ _, param, _ = fname_param_config # Config file and no "--folder": config file entry wins. param.configfile = str(TEST_CONFIG_FNAME) param.folder = None cfg, err = main.compile_config(param) assert not err assert cfg.folder == TEST_CONFIG_FNAME.parent.absolute() / "some/path" # Config file and "--folder some/where": `--folder` wins. param.configfile = str(TEST_CONFIG_FNAME) param.folder = "some/where" cfg, err = main.compile_config(param) assert not err and cfg.folder == Filepath("some/where") # No config file and no "--folder": manifest folder must be CWD. param.configfile = None param.folder = None cfg, err = main.compile_config(param) assert not err and cfg.folder == Filepath.cwd() / "foo" / "bar" # No config file and "--folder some/where": must point to `some/where`. param.configfile = None param.folder = "some/where" cfg, err = main.compile_config(param) assert not err and cfg.folder == Filepath("some/where")
def compile_config(cmdline_param) -> Tuple[Config, bool]: """Return `Config` from `cmdline_param`. Inputs: cmdline_param: SimpleNamespace Returns: Config, err """ err_resp = Config( folder=Filepath(""), kubeconfig=Filepath(""), kubecontext=None, selectors=Selectors(set(), namespaces=[], labels=[]), groupby=GroupBy("", []), priorities=[], ), True # Convenience. p = cmdline_param # Load the default configuration unless the user specified an explicit one. if p.configfile: logit.info(f"Loading configuration file <{p.configfile}>") cfg, err = square.cfgfile.load(p.configfile) # Use the folder the `load()` function determined. folder = cfg.folder # Look for `--kubeconfig`. Default to the value in config file. kubeconfig = p.kubeconfig or cfg.kubeconfig else: # Pick the configuration file, depending on whether the user specified # `--no-config`, `--config` and whether a `.square.yaml` file exists. default_cfg = DEFAULT_CONFIG_FILE dot_square = Filepath(".square.yaml") if p.no_config: cfg_file = default_cfg else: cfg_file = dot_square if dot_square.exists() else default_cfg logit.info(f"Loading configuration file <{cfg_file}>") cfg, err = square.cfgfile.load(cfg_file) # Determine which Kubeconfig to use. The order is: `--kubeconfig`, # `--config`, `.square`, `KUBECONFIG` environment variable. if cfg_file == default_cfg: kubeconfig = p.kubeconfig or os.getenv("KUBECONFIG", "") else: kubeconfig = p.kubeconfig or str(cfg.kubeconfig) or os.getenv("KUBECONFIG", "") # noqa del dot_square, default_cfg # Use the current working directory as the folder directory because the # user did not specify an explicit configuration file which would # contain the desired folder. folder = Filepath.cwd() # Abort if neither `--kubeconfig` nor KUBECONFIG env var. if not kubeconfig: logit.error("Must specify a Kubernetes config file.") return err_resp if err: return err_resp # Override the folder if user specified "--folder". folder = folder if p.folder is None else p.folder # Expand the user's home folder, ie if the path contains a "~". folder = Filepath(folder).expanduser() kubeconfig = Filepath(kubeconfig).expanduser() # ------------------------------------------------------------------------ # GroupBy (determines the folder hierarchy that GET will create). # In : `--groupby ns kind label=app` # Out: GroupBy(order=["ns", "kind", "label"], label="app") # ------------------------------------------------------------------------ # Unpack the ordering and replace all `label=*` with `label`. # NOTE: `p.groups` does not necessarily exist because the option only makes # sense for eg `square GET` and is thus not implemented for `square apply`. order = getattr(p, "groupby", None) if order is None: groupby = cfg.groupby else: clean_order = [_ if not _.startswith("label") else "label" for _ in order] if not set(clean_order).issubset({"ns", "kind", "label"}): logit.error("Invalid definition of `groupby`") return err_resp labels = [_ for _ in order if _.startswith("label")] if len(labels) > 1: logit.error("Can only specify one `label=<name>` in `--groupby`.") return err_resp # Unpack the label name from the `--groupby` argument. # Example, if user specified `--groupby label=app` then we need to extract # the `app` part. This also includes basic sanity checks. label_name = "" if len(labels) == 1: try: _, label_name = labels[0].split("=") assert len(label_name) > 0 except (ValueError, AssertionError): logit.error(f"Invalid label specification <{labels[0]}>") return err_resp # Compile the final `GroupBy` structure. groupby = GroupBy(order=list(clean_order), label=label_name) del order, clean_order, label_name # ------------------------------------------------------------------------ # General: folder, kubeconfig, kubecontext, ... # ------------------------------------------------------------------------ kinds = set(p.kinds) if p.kinds else cfg.selectors.kinds # Use the value from the (default) config file unless the user overrode # them on the command line. kubeconfig = Filepath(kubeconfig) kubecontext = p.kubecontext or cfg.kubecontext namespaces = cfg.selectors.namespaces if p.namespaces is None else p.namespaces sel_labels = cfg.selectors.labels if p.labels is None else p.labels priorities = p.priorities or cfg.priorities selectors = Selectors(kinds, namespaces, sel_labels) # Use filters from (default) config file because they cannot be specified # on the command line. filters = cfg.filters # ------------------------------------------------------------------------ # Verify inputs. # ------------------------------------------------------------------------ # Abort without credentials. if not kubeconfig.exists(): logit.error(f"Cannot find Kubernetes config file <{kubeconfig}>") return err_resp # ------------------------------------------------------------------------- # Assemble the full configuration and return it. # ------------------------------------------------------------------------- cfg = Config( folder=folder, kubeconfig=kubeconfig, kubecontext=kubecontext, selectors=selectors, groupby=groupby, priorities=priorities, filters=filters, ) return cfg, False