示例#1
0
def get_service_ref(k8s_path):
    service_file_path = os.path.join(k8s_path, "service.yaml")
    if not os.path.exists(service_file_path):
        service_file_path = os.path.join(k8s_path, "kservice.yaml")
    try:
        with open(service_file_path) as f:
            service_components = list(yaml.load_all(f, Loader=yaml.SafeLoader))
            if len(service_components) == 1:
                service_components = service_components[0]
    except FileNotFoundError:
        error("%s not found" % service_file_path)
        return None
    if isinstance(service_components, Mapping):
        if service_components.get("kind") == "Service":
            name = service_components.get("metadata", {}).get("name")
            if name is not None:
                return {
                    "serviceApiVersion": service_components.get("apiVersion"),
                    "rulesetName": name
                }
    elif isinstance(service_components, list):
        for c in service_components:
            if c.get("kind") == "Service":
                name = c.get("metadata", {}).get("name")
                if name is not None:
                    return {
                        "serviceApiVersion": c.get("apiVersion"),
                        "rulesetName": name
                    }
    return None
示例#2
0
def get_default_namespace():
    error("fetching kubectl config...")
    namespace = subprocess.check_output(
        ["kubectl", "config", "current-context", "namespace"])
    if namespace is None:
        return "default"
    return namespace.decode("utf-8").replace("\n", "")
示例#3
0
def add_profile(profile_name,
                project_root,
                namespace,
                docker_registry,
                set_default=False):

    config_path = os.path.join(project_root, PROJECT_CONF_DIR,
                               PROJECT_CONF_FILE_NAME)
    config = get_config(config_path)

    if PROFILES_SECTION not in config:
        config[PROFILES_SECTION] = {}
    elif profile_name in config[PROFILES_SECTION]:
        error("%s profile already exists" % profile_name)
        return

    if namespace is None or len(namespace) == 0:
        default_namespace = get_default_namespace()
        while namespace is None or len(namespace) == 0:
            answer = get_user_input("Namespace [%s]: " % default_namespace)
            if answer == "":
                namespace = default_namespace
            else:
                namespace = answer

    if docker_registry is None or len(docker_registry) == 0:
        docker_registry = ""
        default_docker_registry = get_default_docker_registry()
        while len(docker_registry) == 0:
            if default_docker_registry is not None:
                output_request = "Docker Registry [%s]: " % default_docker_registry
            else:
                output_request = "Docker Registry: "

            answer = get_user_input(output_request)
            if answer == "":
                if default_docker_registry is not None:
                    docker_registry = default_docker_registry
                else:
                    error("You must set value for Docker Registry")
            else:
                docker_registry = answer.replace(" ", "")
    profile = {"namespace": namespace, "docker_registry": docker_registry}

    config[PROFILES_SECTION][profile_name] = profile
    save_config(config, config_path)
    print("Profile %s added properly" % profile_name)
    if set_default:
        workspace_path = os.path.join(project_root, PROJECT_CONF_DIR,
                                      PROJECT_WORKSPACE_FILE_NAME)
        update_workspace(workspace_path, current_profile=profile_name)
        print("Profile %s is now the current one" % profile_name)
    return profile
示例#4
0
def set_current_profile(profile_name):
    project_root = get_project_root(os.getcwd())
    config_path = os.path.join(project_root, PROJECT_CONF_DIR,
                               PROJECT_CONF_FILE_NAME)
    config = get_config(config_path)
    profiles = list(config.get(PROFILES_SECTION, {}).keys())
    if profile_name not in profiles:
        error("\"%s\" is not a valid profile name" % profile_name)
        error("Choose between %s" % str(profiles))
    else:
        workspace_path = os.path.join(project_root, PROJECT_CONF_DIR,
                                      PROJECT_WORKSPACE_FILE_NAME)
        update_workspace(workspace_path, current_profile=profile_name)
        print("%s now is the current profile" % profile_name)
示例#5
0
def patch_kustomization(path, images):
    if path is None or path == "":
        path = os.getcwd()
    if not os.path.exists(os.path.join(path, "kustomization.yaml")):
        path = os.path.join(path, "k8s")
        if not os.path.exists(path):
            error(
                "\"kustomization.yaml\" not found in the current directory or in the subdirectory \"k8s\""
            )
            return
    if images is not None:
        build_kustomization(path, images=images)
    else:
        build_kustomization(path)
示例#6
0
def build_docker_file(path):
    origin_filepath = os.path.join(path, "Dockerfile.origin")
    if os.path.exists(origin_filepath):
        project_root = get_project_root(path)
        with open(os.path.join(project_root, "base", "VERSION")) as v:
            version = v.read()
        profile = get_current_profile()
        config = get_config(
            os.path.join(project_root, PROJECT_CONF_DIR,
                         PROJECT_CONF_FILE_NAME))
        parsed_content = load_template(
            path,
            "Dockerfile.origin",
            dockerRegistry=profile["docker_registry"],
            projectName=config[PROJECT_SECTION]["name"],
            baseVersion=version)
        dockerfile_path = os.path.join(path, "Dockerfile")
        with open(dockerfile_path, "w") as dockerfile:
            dockerfile.write(parsed_content)
    else:
        error("Dockerfile.origin not found!")
        return
示例#7
0
def update_ruleset(merge_strategy, pk=None, **values):
    values["action"] = "update"
    cwd = os.getcwd()
    project_root = get_project_root(cwd)
    _, ruleset_name = os.path.split(cwd)
    project_config = get_config(
        os.path.join(project_root, PROJECT_CONF_DIR, PROJECT_CONF_FILE_NAME))
    template_dir = project_config[PROJECT_SECTION].get(
        DEFAULT_RS_TEMPLATE_PATH_KEY, None)
    if template_dir is None:
        template_dir = os.path.join(ASSETS_PATH, "ruleset_tmpl")
    else:
        template_dir = os.path.join(project_root, template_dir)

    parent, current_folder_name = os.path.split(cwd)
    if current_folder_name == "k8s":
        ruleset_path = parent
        k8s_path = cwd
    else:
        k8s_path = os.path.join(cwd, "k8s")
        if os.path.exists(k8s_path):
            ruleset_path = cwd
        else:
            error("k8s folder not found!")
            return
    service_ref = get_service_ref(k8s_path)
    if service_ref is None:
        error(
            "No Service found in the current directory or in the subdirectory \"k8s\""
        )
        return
    values.update(service_ref)
    recursive_copy(template_dir,
                   ruleset_path,
                   values,
                   merge_strategy=merge_strategy,
                   pk=pk)
示例#8
0
def init_project_tree(project_name, project_location, namespace,
                      docker_registry, image_base):
    if project_location is None:
        project_location = os.getcwd()
    project_location = os.path.abspath(project_location)

    if os.path.exists(os.path.join(project_location, PROJECT_CONF_DIR)):
        error('Project already exists in %s' % project_location)
        return

    if project_name is not None and not is_valid_project_name(project_name):
        error("Project name must match %s" % VALID_PROJECT_NAME_REGEX)
        return

    if project_name is None or len(project_name) == 0:
        default_project_name = get_default_project_name(project_location)
        while project_name is None or len(project_name) == 0:
            answer = get_user_input("Project name [%s]: " %
                                    default_project_name)
            if answer == "":
                project_name = default_project_name
            else:
                if is_valid_project_name(answer):
                    project_name = answer
                else:
                    error("Project name must match %s" %
                          VALID_PROJECT_NAME_REGEX)

    config = {PROJECT_SECTION: {"name": project_name}}
    save_config(
        config,
        os.path.join(project_location, PROJECT_CONF_DIR,
                     PROJECT_CONF_FILE_NAME))
    profile = add_profile(DEFAULT_KEY,
                          project_location,
                          namespace,
                          docker_registry,
                          set_default=True)

    defaults = {
        "projectName": project_name,
        "dockerRegistry": profile["docker_registry"],
        "projectNamespace": profile["namespace"]
    }
    with open(os.path.join(ASSETS_PATH, "defaults.yaml")) as df:
        defaults.update(yaml.load(df.read(), Loader=yaml.SafeLoader))
    if image_base is not None:
        defaults["imageBase"] = image_base

    os.makedirs(project_location, exist_ok=True)
    recursive_copy(os.path.join(ASSETS_PATH, "project_tmpl"), project_location,
                   defaults)
    print("Project %s created successfully" % project_name)
    print("Now you have to configure subject storage support\n"
          "Look at \"Config subject storage support\" section in README")
示例#9
0
def parse_args(args):
    scope = args.get("scope")
    command = args.get("command")

    if scope == "project":
        if command == "init":
            init_project_tree(args.get("name"), args.get("location"),
                              args.get("namespace"),
                              args.get("docker_registry"),
                              args.get("image_base"))
        else:
            project_parser.print_help(sys.stdout)
    elif scope == "ruleset":
        if command == "create":
            init_ruleset_tree(args.get("name"), args.get("template_dir"),
                              args.get("service_type"))
        elif command == "patch":
            patch_kustomization(args.get("path"), args.get("set_image"))
        elif command == "build-dockerfile":
            build_docker_file(os.getcwd())
        else:
            ruleset_parser.print_help(sys.stdout)
    elif scope == "trigger":
        name = args.get("name")
        if args.get("type"):
            if args.get("on_propchange") or args.get("attrs"):
                error(UPDATE_TRIGGER_ERROR_MESSAGE)
                return
            else:
                update_ruleset(resourceKinds=["Trigger"],
                               triggerKind="trigger-for-type",
                               type=args.get("type"),
                               merge_strategy=MERGE_STRATEGY_MIXED,
                               pk="metadata.name",
                               triggerName=name)
        elif args.get("on_propchange"):
            if args.get("type") or args.get("attrs"):
                error(UPDATE_TRIGGER_ERROR_MESSAGE)
                return
            else:
                update_ruleset(resourceKinds=["Trigger"],
                               triggerKind="trigger-on-propchange",
                               propertyName=args.get("on_propchange"),
                               merge_strategy=MERGE_STRATEGY_MIXED,
                               pk="metadata.name",
                               triggerName=name)
        elif args.get("attrs"):
            if args.get("type") or args.get("on_propchange"):
                error(UPDATE_TRIGGER_ERROR_MESSAGE)
                return
            else:
                attributes = {}
                for attr in args.get("attrs"):
                    try:
                        k, v = attr.split("=")
                    except ValueError:
                        error("Bad formatted attributes (expected attr=value)")
                        return
                    if k in attributes:
                        error("Duplicated attribute %s" % k)
                        return
                    attributes[k] = v
                update_ruleset(resourceKinds=["Trigger"],
                               triggerKind="trigger-attrs",
                               triggerAttributes=attributes,
                               merge_strategy=MERGE_STRATEGY_MIXED,
                               pk="metadata.name",
                               triggerName=name)
        else:
            update_ruleset(resourceKinds=["Trigger"],
                           triggerKind="trigger-sourced",
                           triggerSourced=name,
                           merge_strategy=MERGE_STRATEGY_MIXED,
                           pk="metadata.name",
                           triggerName=name)
    elif scope == "gen-rs-template":
        location = args.get("location")
        if location is not None:
            export_rs_template_from_assets(location, args.get("set_default"))
        elif args.get("unset_default"):
            unset_default()
        else:
            gen_rs_template_parser.print_help()
    elif scope == "profile":
        if command == "get":
            print(get_current_profile_name())
        elif command == "set":
            set_current_profile(args.get("profile_name"))
        elif command == "list":
            get_profiles_list()
        elif command == "get-value":
            print(get_profile_value(args.get("key")))
        elif command == "set-value":
            set_profile_value(args.get("key"), args.get("value"))
        elif command == "values":
            print_current_profile_values()
        elif command == "add":
            project_root = get_project_root(os.getcwd())
            add_profile(args.get("name"), project_root, args.get("namespace"),
                        args.get("docker_registry"), args.get("set_default"))
        else:
            profile_parser.print_help()
    else:
        parser.print_help()