예제 #1
0
 def testSingleTypeMultiResource(self):
     args = ("pod", "mypod", "myotherpod")
     _, rl = parse.parse_get_resources(args)
     r_type, r_name = next(rl)
     self.assertEqual(1, len(rl))
     self.assertEqual("pod", r_type)
     self.assertEqual({"mypod", "myotherpod"}, r_name)
예제 #2
0
 def testSingleSlash(self):
     args = ("pods/mypod", )
     _, rl = parse.parse_get_resources(args)
     r_type, r_name = next(rl)
     self.assertEqual(1, len(rl))
     self.assertEqual("pod", r_type)
     self.assertEqual({"mypod"}, r_name)
예제 #3
0
 def testAllResource(self):
     args = ("pods", )
     _, rl = parse.parse_get_resources(args)
     r_type, r_name = next(rl)
     self.assertEqual(1, len(rl))
     self.assertEqual("pod", r_type)
     self.assertEqual({parse.ALL_RESOURCES}, r_name)
예제 #4
0
def generate_completions(objects, incomplete, namespace):
    # We're completing something like `oc get pod/<tab>`.
    if "/" in incomplete:
        restypein = incomplete.split("/")[0]
        resname = incomplete.split("/")[1]
        names = get_resource_names(restypein, "_all", namespace)
        return [
            restypein + "/" + n
            for n in names
            if n.startswith(resname) and restypein + "/" + n not in objects
        ]

    if "," in incomplete or [o for o in objects if "," in o]:
        # This is a NOP like oc
        return []

    get_method, resource_list = parse.parse_get_resources(objects)

    # First arg after get, autocomplete type
    # or autocompleting after existing slash-notation arg
    if not objects or get_method == parse.Method.SLASH:
        if get_method == parse.Method.SLASH:
            add_slash = "/"
        else:
            add_slash = ""
        sugg = _suggest_type(incomplete)
        return [s + add_slash for s in sugg]

    if get_method == parse.Method.PLAIN and len(resource_list) > 0:
        # Autocomplete resource names based on the type: oc get pod mypod1 mypod2
        restypein, _ = next(resource_list)
        names = get_resource_names(restypein, "_all", namespace)
        return [n for n in names if n.startswith(incomplete) and n not in objects]
    # Catch all
    return []
예제 #5
0
 def testMultipleResourcesOneName(self):
     expected_args = ["endpoint", "service"]
     args = ("svc,endpoints", "dns-default")
     _, rl = parse.parse_get_resources(args)
     for r_type, r_name in rl:
         expected = expected_args.pop()
         self.assertEqual(expected, r_type)
         self.assertEqual({"dns-default"}, r_name)
예제 #6
0
 def testMultipleResources(self):
     expected_args = ["endpoint", "service", "pod"]
     args = ("pods,svc,endpoints", )
     _, rl = parse.parse_get_resources(args)
     for r_type, r_name in rl:
         expected = expected_args.pop()
         self.assertEqual(expected, r_type)
         self.assertEqual({parse.ALL_RESOURCES}, r_name)
예제 #7
0
    def testAllTypes(self):
        args = ("all", )
        _, rl = parse.parse_get_resources(args)

        for expected_type in parse.ALL_TYPES:
            self.assertIn(expected_type, rl)

        for _, n in rl:
            self.assertEqual({parse.ALL_RESOURCES}, n)
예제 #8
0
    def testMultiSlash(self):
        args = ("pods/mypod", "svc/default")
        _, rl = parse.parse_get_resources(args)
        self.assertEqual(2, len(rl))

        r_type, r_name = next(rl)
        self.assertEqual("pod", r_type)
        self.assertEqual({"mypod"}, r_name)

        r_type, r_name = next(rl)
        self.assertEqual("service", r_type)
        self.assertEqual({"default"}, r_name)
예제 #9
0
def generate_completions(config, objects, incomplete):
    """
    Given a config, tuple of args, and incomplete input from user, generate a list of completions.

    This function should not print stack traces or do any error logging (without turning it on explicitly)
    since shell completion should be transparent to user.
    """
    try:
        get_method, resource_list = parse.parse_get_resources(objects)
    except Exception as e:
        # Swallow any error since we don't want to spam terminal during autcompletion.
        print(e)
        return []

    # We're completing something like `oc get pod/name`.
    if "/" in incomplete:
        restypein = incomplete.split("/")[0]
        resname = incomplete.split("/")[1]
        restype = map_res(restypein)
        resources = restype['get_func']('items', config.project, '_all',
                                        restype['yaml_loc'],
                                        restype['need_ns'])
        return [
            restypein + "/" + r['res']['metadata']['name'] for r in resources
            if r['res']['metadata']['name'].startswith(resname)
        ]

    if len(resource_list) == 0 and "," in incomplete:
        # This is a NOP like oc
        return []
    elif get_method == parse.Method.SINGLE_TYPE or \
            get_method == parse.Method.ALL:
        # Autocomplete resource names based on the type: oc get pod mypod1 mypod2
        restypein, _ = next(resource_list)
        restype = map_res(restypein)
        resources = restype['get_func']('items', config.project, '_all',
                                        restype['yaml_loc'],
                                        restype['need_ns'])
        return [
            r['res']['metadata']['name'] for r in resources
            if r['res']['metadata']['name'].startswith(incomplete)
        ]
    else:
        # Return completions for resource types
        # TODO: Include aliases
        fullset = set(parse.ALL_TYPES + [t['type'] for t in map])
        return [t for t in fullset if t.startswith(incomplete)]
예제 #10
0
def get_main(objects, output, namespace, all_namespaces, show_labels):
    # Check if -A/--all-namespaces is set
    # else, Set the namespace
    # -n/--namespace takes precedence over current project
    if all_namespaces is True:
        ns = "_all"
    else:
        if namespace is not None:
            ns = namespace
        elif Config().project is not None:
            ns = Config().project
        else:
            ns = None

    # Parse get args and get normalized resources to get
    try:
        _, resource_list = parse.parse_get_resources(objects)
    except parse.ResourceParseError as e:
        print(e)
        return

    # Call the get function for all the requested types
    # then call the output function or simply print if its yaml/json

    # Flag to mark if we have already printed something
    printed_something = False

    for r_type, r_name in resource_list:

        res = get_resources(r_type, r_name, ns)

        if len(res) > 0:
            # If printing multiple objects, add a blank line between each
            if printed_something:
                print("")
            # Yaml dump if -o yaml
            if output == "yaml":
                if len(res) == 1:
                    print(yaml.dump(res[0]["res"]))
                elif len(res) > 1:
                    print(
                        yaml.dump({
                            "apiVersion": "v1",
                            "items": [cp["res"] for cp in res]
                        }))
            # Json dump if -o json
            elif output == "json":
                if len(res) == 1:
                    print(json.dumps(res[0]["res"], indent=4))
                elif len(res) > 1:
                    print(
                        json.dumps(
                            {
                                "apiVersion": "v1",
                                "items": [cp["res"] for cp in res]
                            },
                            indent=4,
                        ))
            # Call the respective output function if -o is not set or -o wide
            elif output in [None, "wide"]:
                # If we displaying more than one resource_type,
                # we need to display resource_type with the name (type/name)
                if len(resource_list) > 1:
                    show_type = True
                else:
                    show_type = False
                getout_func = map_res(r_type)["getout_func"]
                getout_func(r_type, ns, res, output, show_type, show_labels)

            # We printed something
            printed_something = True

    # Error out if nothing was printed
    if not printed_something:
        print("No resources found in %s namespace" % ns)
예제 #11
0
 def testInvalidMultiTypeMultiResource(self):
     args = ("pods/mypod", "svc/myservice", "blarg/bad")
     with self.assertRaises(parse.ResourceParseError):
         parse.parse_get_resources(args)
예제 #12
0
 def testInvalidMultiTypeComma(self):
     args = ("pods,svc,asdf", )
     with self.assertRaises(parse.ResourceParseError):
         parse.parse_get_resources(args)
예제 #13
0
 def testInvalidType(self):
     args = ("podzzzz", )
     with self.assertRaises(parse.ResourceParseError):
         parse.parse_get_resources(args)
예제 #14
0
def get_main(objects, output, namespace, all_namespaces):
    # a = args passed from cli
    # Check if -A/--all-namespaces is set
    # else, Set the namespace
    # -n/--namespace takes precedence over current project
    if all_namespaces is True:
        ns = '_all'
    else:
        if namespace is not None:
            ns = namespace
        elif Config().project is not None:
            ns = Config().project
        else:
            ns = None

    try:
        get_method, resource_list = parse.parse_get_resources(objects)
    except parse.ResourceParseError as e:
        print(e)
        return

    # Object based routing
    # i.e, call the get function for all the requested types
    # then call the output function or simply print if its yaml/json

    # If printing multiple objects, add a blank line between each
    mult_objs_blank_line = False

    for r_type, res_set in resource_list:
        rt_info = map_res(r_type)
        get_func = rt_info['get_func']
        getout_func = rt_info['getout_func']
        yaml_loc = rt_info['yaml_loc']
        need_ns = rt_info['need_ns']

        # Call the get function to get the resoruces
        res = get_func(r_type, ns, res_set, yaml_loc, need_ns)

        # Error out if no objects/resources were collected
        if len(res) == 0 and get_method is not parse.Method.ALL:
            print('No resources found for type "%s" in %s namespace' %
                  (r_type, ns))
        elif len(res) > 0:
            # If printing multiple objects, add a blank line between each
            if mult_objs_blank_line:
                print('')
            # Yaml dump if -o yaml
            if output == 'yaml':
                if len(res) == 1:
                    print(yaml.dump(res[0]['res']))
                elif len(res) > 1:
                    print(
                        yaml.dump({
                            'apiVersion': 'v1',
                            'items': [cp['res'] for cp in res]
                        }))
            # Json dump if -o json
            elif output == 'json':
                if len(res) == 1:
                    print(json.dumps(res[0]['res'], indent=4))
                elif len(res) > 1:
                    print(
                        json.dumps(
                            {
                                'apiVersion': 'v1',
                                'items': [cp['res'] for cp in res]
                            },
                            indent=4))
            # Call the respective output function if -o is not set or -o wide
            elif output in [None, 'wide']:
                # If we displaying more than one resource_type,
                # we need to display resource_type with the name (type/name)

                if len(resource_list) > 1:
                    show_type = True
                else:
                    show_type = False
                getout_func(r_type, ns, res, output, show_type)
            # Flag to print multiple objects
            if not mult_objs_blank_line:
                mult_objs_blank_line = True

    # Error out once if multiple objects/resources requested and none collected
    if not mult_objs_blank_line and get_method == parse.Method.ALL:
        print('No resources found in %s namespace' % ns)