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

[FEATURE] Update github action #140

Merged
merged 10 commits into from
Oct 31, 2024
Merged
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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ ignore-words-list = [
"priv",
"sproc",
"snowpark",
"pathspec",
]
skip = [
"./build/",
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"snowflake-connector-python>=3.7.0",
"snowflake-snowpark-python>=1.14.0",
"jinja2",
"pathspec",
],
extras_require={
"dev": [
Expand Down
8 changes: 5 additions & 3 deletions tests/integration/data_provider/test_list_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,16 @@ def test_list_resource(cursor, list_resources_database, resource, marked_for_cle
f"Skipping {resource.__class__.__name__}, not supported by account edition {session_ctx['account_edition']}"
)

if not hasattr(data_provider, f"list_{pluralize(resource_label_for_type(resource.resource_type))}"):
pytest.skip(f"{resource.resource_type} is not supported")

if resource.__class__ == res.ScannerPackage:
pytest.skip("Flaky test, skipping for now")
if isinstance(resource.scope, DatabaseScope):
list_resources_database.add(resource)
elif isinstance(resource.scope, SchemaScope):
list_resources_database.public_schema.add(resource)

if not hasattr(data_provider, f"list_{pluralize(resource_label_for_type(resource.resource_type))}"):
pytest.skip(f"{resource.resource_type} is not supported")

try:
create(cursor, resource)
marked_for_cleanup.append(resource)
Expand Down
1 change: 1 addition & 0 deletions tests/integration/test_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def test_create_drop_from_json(resource, cursor, suffix):
res.Grant,
res.RoleGrant,
res.FutureGrant,
res.ScannerPackage,
):
pytest.skip("Skipping")

Expand Down
4 changes: 3 additions & 1 deletion titan/blueprint_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ def __post_init__(self):
if self.scope == BlueprintScope.DATABASE and self.schema is not None:
raise ValueError("Cannot specify a schema when using DATABASE scope")
elif self.scope == BlueprintScope.ACCOUNT and (self.database is not None or self.schema is not None):
raise ValueError("Cannot specify a database or schema when using ACCOUNT scope")
raise ValueError(
f"Cannot specify a database or schema when using ACCOUNT scope (database={repr(self.database)}, schema={repr(self.schema)})"
)


def set_vars_defaults(vars_spec: list[dict], vars: dict) -> dict:
Expand Down
207 changes: 139 additions & 68 deletions titan/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,31 @@
import yaml

from titan.blueprint import dump_plan
from titan.enums import RunMode
from titan.enums import RunMode, BlueprintScope
from titan.gitops import (

Check warning on line 9 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L8-L9

Added lines #L8 - L9 were not covered by tests
collect_configs_from_path,
collect_vars_from_environment,
merge_configs,
merge_vars,
parse_resources,
)
from titan.operations.blueprint import blueprint_apply, blueprint_apply_plan, blueprint_plan
from titan.operations.export import export_resources
from titan.operations.connector import connect, get_env_vars
from titan.operations.export import export_resources

Check warning on line 18 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L18

Added line #L18 was not covered by tests


class RunModeParamType(click.ParamType):
name = "run_mode"

Check warning on line 22 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L21-L22

Added lines #L21 - L22 were not covered by tests

def convert(self, value, param, ctx):
return RunMode(value)

Check warning on line 25 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L24-L25

Added lines #L24 - L25 were not covered by tests

from .identifiers import resource_type_for_label

class ScopeParamType(click.ParamType):
name = "scope"

Check warning on line 29 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L28-L29

Added lines #L28 - L29 were not covered by tests

def convert(self, value, param, ctx):
return BlueprintScope(value)

Check warning on line 32 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L31-L32

Added lines #L31 - L32 were not covered by tests


class JsonParamType(click.ParamType):
Expand All @@ -30,18 +49,6 @@
return parse_resources(value)


def parse_resources(resource_labels_str):
if resource_labels_str is None:
return None
return [resource_type_for_label(resource_label) for resource_label in resource_labels_str.split(",")]


def load_config(config_file):
with open(config_file, "r") as f:
config = yaml.safe_load(f)
return config


def load_plan(plan_file):
with open(plan_file, "r") as f:
plan = json.load(f)
Expand All @@ -54,39 +61,95 @@
pass


# Shared click options


def config_path_option():
return click.option(

Check warning on line 68 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L67-L68

Added lines #L67 - L68 were not covered by tests
"--config",
"config_path",
type=str,
help="Path to configuration YAML file or directory",
metavar="<file_or_dir>",
)


def vars_option():
return click.option(

Check warning on line 78 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L77-L78

Added lines #L77 - L78 were not covered by tests
"--vars",
type=JsonParamType(),
help="Dynamic values, specified as a JSON dictionary",
metavar="<JSON_string>",
)


def allowlist_option():
return click.option(

Check warning on line 87 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L86-L87

Added lines #L86 - L87 were not covered by tests
"--allowlist",
type=CommaSeparatedListParamType(),
help="List of resources types allowed in the plan. If not specified, all resources are allowed.",
metavar="<resource_types>",
)


def run_mode_option():
return click.option(

Check warning on line 96 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L95-L96

Added lines #L95 - L96 were not covered by tests
"--mode",
"run_mode",
type=RunModeParamType(),
metavar="<run_mode>",
show_default=True,
help="Run mode",
)


def scope_option():
return click.option(

Check warning on line 107 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L106-L107

Added lines #L106 - L107 were not covered by tests
"--scope",
type=ScopeParamType(),
help="Limit the scope of resources to a specific database or schema",
metavar="<scope>",
)


def database_option():
return click.option(

Check warning on line 116 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L115-L116

Added lines #L115 - L116 were not covered by tests
"--database",
type=str,
help="Database to limit the scope to",
metavar="<database_name>",
)


def schema_option():
return click.option(

Check warning on line 125 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L124-L125

Added lines #L124 - L125 were not covered by tests
"--schema",
type=str,
help="Schema to limit the scope to",
metavar="<schema_name>",
)


@titan_cli.command("plan", no_args_is_help=True)
@click.option("--config", "config_file", type=str, help="Path to configuration YAML file", metavar="<filename>")
@config_path_option()

Check warning on line 134 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L134

Added line #L134 was not covered by tests
@click.option("--json", "json_output", is_flag=True, help="Output plan in machine-readable JSON format")
@click.option("--out", "output_file", type=str, help="Write plan to a file", metavar="<filename>")
@click.option("--vars", type=JsonParamType(), help="Vars to pass to the blueprint")
@click.option(
"--allowlist",
type=CommaSeparatedListParamType(),
help="List of resources types allowed in the plan. If not specified, all resources are allowed.",
metavar="<resource_types>",
)
@click.option(
"--mode",
"run_mode",
type=click.Choice(["CREATE-OR-UPDATE", "SYNC"]),
metavar="<run_mode>",
show_default=True,
help="Run mode",
)
@click.option(
"--scope",
type=click.Choice(["ACCOUNT", "DATABASE", "SCHEMA"]),
help="Limit the scope of resources to a specific database or schema",
metavar="<scope>",
)
@click.option("--database", type=str, help="Database to limit the scope to", metavar="<database>")
@click.option("--schema", type=str, help="Schema to limit the scope to", metavar="<schema>")
def plan(config_file, json_output, output_file, vars: dict, allowlist, run_mode, scope, database, schema):
@vars_option()
@allowlist_option()
@run_mode_option()
@scope_option()
@database_option()
@schema_option()
def plan(config_path, json_output, output_file, vars: dict, allowlist, run_mode, scope, database, schema):

Check warning on line 143 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L137-L143

Added lines #L137 - L143 were not covered by tests
"""Generate an execution plan based on your configuration"""
yaml_config = load_config(config_file)

if yaml_config is None:
raise click.UsageError(f"Config file {config_file} is empty")
if not config_path:
raise click.UsageError("--config is required")

Check warning on line 147 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L146-L147

Added lines #L146 - L147 were not covered by tests

yaml_config: dict[str, Any] = {}
configs = collect_configs_from_path(config_path)
for config in configs:
yaml_config = merge_configs(yaml_config, config[1])

Check warning on line 152 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L149-L152

Added lines #L149 - L152 were not covered by tests

cli_config: dict[str, Any] = {}
if vars:
Expand All @@ -102,6 +165,10 @@
if schema:
cli_config["schema"] = schema

env_vars = collect_vars_from_environment()
if env_vars:
cli_config["vars"] = merge_vars(cli_config.get("vars", {}), env_vars)

Check warning on line 170 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L168-L170

Added lines #L168 - L170 were not covered by tests

plan_obj = blueprint_plan(yaml_config, cli_config)
if output_file:
with open(output_file, "w") as f:
Expand All @@ -116,31 +183,24 @@


@titan_cli.command("apply", no_args_is_help=True)
@click.option("--config", "config_file", type=str, help="Path to configuration YAML file", metavar="<filename>")
@config_path_option()

Check warning on line 186 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L186

Added line #L186 was not covered by tests
@click.option("--plan", "plan_file", type=str, help="Path to plan JSON file", metavar="<filename>")
@click.option("--vars", type=JsonParamType(), help="Vars to pass to the blueprint")
@click.option(
"--allowlist",
type=CommaSeparatedListParamType(),
help="List of resources types allowed in the plan. If not specified, all resources are allowed.",
)
@click.option(
"--mode",
"run_mode",
type=click.Choice(["CREATE-OR-UPDATE", "SYNC"]),
metavar="<run_mode>",
show_default=True,
help="Run mode",
)
@click.option("--dry-run", is_flag=True, help="Perform a dry run without applying changes")
def apply(config_file, plan_file, vars, allowlist, run_mode, dry_run):
@vars_option()
@allowlist_option()
@run_mode_option()
@scope_option()
@database_option()
@schema_option()
@click.option("--dry-run", is_flag=True, help="When dry run is true, Titan will not make any changes to Snowflake")
def apply(config_path, plan_file, vars, allowlist, run_mode, scope, database, schema, dry_run):

Check warning on line 195 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L188-L195

Added lines #L188 - L195 were not covered by tests
"""Apply an execution plan to a Snowflake account"""
if config_file and plan_file:

if config_path and plan_file:

Check warning on line 198 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L198

Added line #L198 was not covered by tests
raise click.UsageError("Cannot specify both --config and --plan.")
if not config_file and not plan_file:
if not config_path and not plan_file:

Check warning on line 200 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L200

Added line #L200 was not covered by tests
raise click.UsageError("Either --config or --plan must be specified.")

cli_config = {}
cli_config: dict[str, Any] = {}

Check warning on line 203 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L203

Added line #L203 was not covered by tests
if vars:
cli_config["vars"] = vars
if run_mode:
Expand All @@ -149,11 +209,22 @@
cli_config["dry_run"] = dry_run
if allowlist:
cli_config["allowlist"] = allowlist
if scope:
cli_config["scope"] = scope
if database:
cli_config["database"] = database
if schema:
cli_config["schema"] = schema

Check warning on line 217 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L212-L217

Added lines #L212 - L217 were not covered by tests

env_vars = collect_vars_from_environment()
if env_vars:
cli_config["vars"] = merge_vars(cli_config.get("vars", {}), env_vars)

Check warning on line 221 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L219-L221

Added lines #L219 - L221 were not covered by tests

if config_file:
yaml_config = load_config(config_file)
if yaml_config is None:
raise click.UsageError(f"Config file {config_file} is empty")
if config_path:
yaml_config: dict[str, Any] = {}
configs = collect_configs_from_path(config_path)
for config in configs:
yaml_config = merge_configs(yaml_config, config[1])

Check warning on line 227 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L223-L227

Added lines #L223 - L227 were not covered by tests
blueprint_apply(yaml_config, cli_config)
elif plan_file:
plan_obj = load_plan(plan_file)
Expand Down Expand Up @@ -206,7 +277,7 @@
if resources and export_all:
raise click.UsageError("You can't specify both --resource and --all options at the same time.")

resource_config = {}
resource_config: dict[str, Any] = {}

Check warning on line 280 in titan/cli.py

View check run for this annotation

Codecov / codecov/patch

titan/cli.py#L280

Added line #L280 was not covered by tests
if resources:
resource_config = export_resources(include=resources)
elif export_all:
Expand Down
Loading
Loading