Skip to content

Commit

Permalink
Related-Bug: #1463208 - Bug fixes for Cliff Client based on Testing [2]
Browse files Browse the repository at this point in the history
This checkin has the following changes:
    - Upload image options in CLI
    - Image defaults added to ini
    - Removing unnecessary mandatory options
    - Bug fix: import defaults from ini
    - Add server roles as list in json
    - Remove template options
    - Remove unused image types
    - Extending timeout to 40 secs
    - Bug Fix: Displaying response as table
    - Remove image edit
    - Bug Fix: Restart Server match keys
    - Server Status in table
    - Upload image - Add Category (Related-Bug: #1508296)
    - Upload image fixed
    - Display columns added
    - Delete using where clause fixed

Change-Id: I78c72edd35cf55e6a7e6db5ada67376b62eb42a1
  • Loading branch information
nitishkrishna committed Nov 5, 2015
1 parent d687af1 commit 2609a31
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 104 deletions.
8 changes: 7 additions & 1 deletion src/smgr_cliff_client/smgrcliapp/interactive.py
Expand Up @@ -211,7 +211,7 @@ def completedefault(self, text, line, begidx, endidx):
available_options["force"] = ['--no_confirm', '-F']
available_options["file"] = ['-f', '--file_name', '--provision_params_file']
available_options["obj_select"] = ['--server_id', '--cluster_id', '--tag', '--where',
'--image_id', '--mac', '--ip', '--discovered']
'--image_id', '--mac', '--ip', '--discovered', '--table']
available_options["package"] = ['--package_image_id', '-p']
available_options["interactive"] = ['--interactive', '-I']
available_options["reboot"] = ['--no_reboot', '-n']
Expand Down Expand Up @@ -260,6 +260,12 @@ def completedefault(self, text, line, begidx, endidx):
last_arg = ""
if len(chosen_sub_option_list) > 0 and last_arg != chosen_sub_option_list[-1] and line[-1] == " ":
last_arg = ""
if chosen_command == "upload-image":
cmd_mandatory_args_dict = cmd.get_mandatory_options()
available_mandatory_options = \
set(cmd_mandatory_args_dict[chosen_command]).difference(chosen_sub_option_set)
cmd_dict[chosen_command] += [x for x in available_mandatory_options]
available_options_list += [x for x in available_mandatory_options]

sub_option_list = [str(str(line).rsplit(' ', 1)[0] + " " + so)
for so in cmd_dict[str(chosen_command)]
Expand Down
1 change: 1 addition & 0 deletions src/smgr_cliff_client/smgrcliapp/sm-client-config.ini
Expand Up @@ -23,3 +23,4 @@ analytics_data_ttl = 168
[SERVER]

[TAG]
[IMAGE]
24 changes: 17 additions & 7 deletions src/smgr_cliff_client/smgrcliapp/smgr_add.py
Expand Up @@ -42,11 +42,11 @@ def get_description(self):
def get_parser(self, prog_name):

self.smgr_objects = ["server", "cluster", "image", "tag"]
self.mandatory_params["server"] = ['id', 'mac_address', 'ip_address', 'ipmi_address', 'subnet_mask', 'gateway']
self.mandatory_params["server"] = ['id', 'mac_address', 'ip_address', 'subnet_mask', 'gateway']
self.mandatory_params["cluster"] = ['id']
self.mandatory_params["image"] = ['id', 'category', 'version', 'type', 'path']
self.mandatory_params["tag"] = []
self.multilevel_param_classes["server"] = ["network", "parameters", "tag", "contrail"]
self.multilevel_param_classes["server"] = ["network", "parameters", "contrail"]
self.multilevel_param_classes["cluster"] = ["parameters"]
self.multilevel_param_classes["image"] = ["parameters"]

Expand Down Expand Up @@ -165,7 +165,7 @@ def get_default_object(self, obj):
return default_object
default_object["parameters"] = {}
default_object["tag"] = {}
for key, value in config_ini_object_defaults:
for key, value in config_ini_object_defaults.iteritems():
if key in self.object_dict[obj]:
default_object[key] = value
elif key in self.object_dict[obj]["parameters"]:
Expand Down Expand Up @@ -201,19 +201,19 @@ def merge_with_defaults(self, object_item, payload):

# end merge_with_defaults

def verify_added_tags(self, obj, obj_payload):
def verify_added_tags(self, smgr_obj, obj_payload):
existing_tags = smgrutils.send_REST_request(
self.smgr_ip, self.smgr_port,
obj="tag", detail=True, method="GET")
tag_dict = json.loads(existing_tags)
rev_tag_dict = dict((v, k) for k, v in tag_dict.iteritems())
allowed_tags = self.object_dict["tag"].keys()
if obj == "tag":
if smgr_obj == "tag":
for tag_idx in obj_payload:
if tag_idx not in allowed_tags:
self.app.print_error_message_and_quit("\nThe tag " + str(tag_idx) +
" is not a valid tag index. Please use tags1-7\n\n")
elif obj == "server":
elif smgr_obj == "server":
added_tag_dict = obj_payload["tag"]
added_tags = added_tag_dict.keys()
for tag in added_tags:
Expand All @@ -228,7 +228,11 @@ def pairwise(self, iterable):

def process_val(self, val_set):
return_dict = dict()
if "," in val_set and "=" in val_set:
if '[' in val_set and ']' in val_set:
list_str = str(val_set)
val_list = str(list_str)
return val_list
elif "," in val_set and "=" in val_set:
key_val_pairs = str(val_set).split(",")
for key_val_pair in key_val_pairs:
key, val = key_val_pair.split("=")
Expand Down Expand Up @@ -363,6 +367,10 @@ def add_object(self, obj, parsed_args, remaining_args=None):
for arg in vars(parsed_args):
if arg in top_level_object_params and arg not in multilevel_obj_params and getattr(parsed_args, arg, None):
obj_payload[arg] = self.process_val(getattr(parsed_args, arg, None))
if arg == "roles" and isinstance(obj_payload[arg], str):
role_list = list()
role_list.append(obj_payload[arg])
obj_payload[arg] = role_list
if remaining_args:
self.parse_remaining_args(obj, obj_payload, multilevel_obj_params, remaining_args)
return obj_payload
Expand Down Expand Up @@ -450,6 +458,8 @@ def take_action(self, parsed_args, remaining_args=None):
mandatory_params_set.difference(added_params_set))) + "\n")
except ValueError as e:
self.app.stdout.write("\nError in CLI Format - ValueError: " + str(e) + "\n")
self.app.stdout.write("\nError Message: " + str(e.message) + "\n")
self.app.stdout.write("\nPayload: " + str(payload) + "\n")
except Exception as e:
self.app.stdout.write("\nException here:" + str(e) + "\n")
if payload:
Expand Down
1 change: 1 addition & 0 deletions src/smgr_cliff_client/smgrcliapp/smgr_cli_main.py
Expand Up @@ -118,6 +118,7 @@ def initialize_app(self, argv):
self.default_config["smgr"] = dict(config.items("SERVER-MANAGER"))
self.default_config["server"] = dict(config.items("SERVER"))
self.default_config["cluster"] = dict(config.items("CLUSTER"))
self.default_config["image"] = dict(config.items("IMAGE"))
self.default_config["tag"] = dict(config.items("TAG"))
env_smgr_ip = os.environ.get('SMGR_IP')
if getattr(self.options, "smgr_ip", None):
Expand Down
90 changes: 58 additions & 32 deletions src/smgr_cliff_client/smgrcliapp/smgr_client_utils.py
Expand Up @@ -27,7 +27,6 @@
("email", "Email id for notifications"),
("base_image_id", "Base image id"),
("package_image_id", "Package id"),
("template", "Template id for cluster"),
("parameters", OrderedDict([
("router_asn", "Router asn value"),
("subnet_mask", "Subnet mask"),
Expand All @@ -53,7 +52,6 @@
("ip_address", "server ip address"),
("mac_address", "server mac address"),
("roles", "comma-separated list of roles for this server"),
("template", "Template id for server"),
("contrail", OrderedDict([
("control_data_interface", "Name of control_data_interface")
])),
Expand Down Expand Up @@ -82,6 +80,7 @@
]))
])),
("cluster_id", "cluster id the server belongs to"),
("tag", "tag dict for server"),
("tag1", "tag value for this tag"),
("tag2", "tag value for this tag"),
("tag3", "tag value for this tag"),
Expand All @@ -104,9 +103,8 @@
("id", "Specify unique image id for this image"),
("version", "Specify version for this image"),
("category", "image/package"),
("template", "Template id for this image"),
("type",
"ubuntu/centos/redhat/esxi5.1/esxi5.5/contrail-ubuntu-package/contrail-centos-package/contrail-storage-ubuntu-package"),
"ubuntu/redhat/esxi5.1/esxi5.5/contrail-ubuntu-package/contrail-storage-ubuntu-package"),
("path", "complete path where image file is located on server"),
("parameters", OrderedDict([
("kickstart", "kickstart file for base image"),
Expand Down Expand Up @@ -166,7 +164,7 @@ def send_REST_request(ip, port, obj=None, rest_api_params=None,
url = "http://%s:%s/%s" % (
ip, port, obj)
if match_key and match_value:
args_str += match_key + "=" + match_value
args_str += urllib.quote_plus(match_key) + "=" + urllib.quote_plus(match_value)
if args_str != '':
url += "?" + args_str
elif method == "GET":
Expand All @@ -182,7 +180,7 @@ def send_REST_request(ip, port, obj=None, rest_api_params=None,
elif obj:
url = "http://%s:%s/%s" % (ip, port, obj)
if match_key and match_value:
args_str += match_key + "=" + match_value
args_str += urllib.quote_plus(match_key) + "=" + urllib.quote_plus(match_value)
if force:
args_str += "&force"
if detail:
Expand All @@ -193,7 +191,7 @@ def send_REST_request(ip, port, obj=None, rest_api_params=None,
if obj:
url = "http://%s:%s/%s" % (ip, port, obj)
if match_key and match_value:
args_str += match_key + "=" + match_value
args_str += urllib.quote_plus(match_key) + "=" + urllib.quote_plus(match_value)
if force:
args_str += "&force"
if args_str != '':
Expand All @@ -202,7 +200,8 @@ def send_REST_request(ip, port, obj=None, rest_api_params=None,
return None
conn = pycurl.Curl()
conn.setopt(pycurl.URL, url)
conn.setopt(pycurl.HTTPHEADER, headers)
if obj != "image/upload":
conn.setopt(pycurl.HTTPHEADER, headers)
if method == "POST" and payload:
conn.setopt(pycurl.POST, 1)
conn.setopt(pycurl.POSTFIELDS, '%s' % json.dumps(payload))
Expand All @@ -218,7 +217,7 @@ def send_REST_request(ip, port, obj=None, rest_api_params=None,
elif method == "DELETE":
conn.setopt(pycurl.CUSTOMREQUEST, "delete")
conn.setopt(pycurl.WRITEFUNCTION, response.write)
conn.setopt(pycurl.TIMEOUT, 30)
conn.setopt(pycurl.TIMEOUT, 40)
conn.perform()
return response.getvalue()
except Exception as e:
Expand All @@ -244,7 +243,10 @@ def convert_json_to_list(obj, json_resp):
@staticmethod
def convert_json_to_table(obj, json_resp, select_item=None):
if obj != "monitoring" and obj != "inventory":
data_dict = dict(ast.literal_eval(str(json_resp)))
try:
data_dict = json.loads(str(json_resp))
except Exception as e:
return "Exception found: " + str(e)
return_table = None
if len(data_dict.keys()) == 1 and obj != "tag":
obj_type, obj_value = data_dict.popitem()
Expand All @@ -253,15 +255,16 @@ def convert_json_to_table(obj, json_resp, select_item=None):
return []
sample_dict = dict(dict_list[0])
sameple_dict_key_list = sample_dict.keys()
sameple_dict_key_list.remove("id")
sameple_dict_key_list = ['id'] + sameple_dict_key_list
if "id" in sameple_dict_key_list:
sameple_dict_key_list.remove("id")
sameple_dict_key_list = ['id'] + sameple_dict_key_list
return_table = PrettyTable(sameple_dict_key_list)
return_table.align["id"] = "l"
for d in dict_list:
d = dict(d)
dict_val_list = d.values()
dict_val_list.remove(d["id"])
dict_val_list = [d["id"]] + dict_val_list
if "id" in d and d["id"] in dict_val_list:
dict_val_list.remove(d["id"])
dict_val_list = [d["id"]] + dict_val_list
return_table.add_row(dict_val_list)
elif obj == "tag":
return_table = PrettyTable(["Tag No.", "Tag"])
Expand All @@ -272,23 +275,27 @@ def convert_json_to_table(obj, json_resp, select_item=None):
tag = data_dict[key]
return_table.add_row([tag_no, tag])
else:
dict_list = list(ast.literal_eval(json_resp))
try:
dict_list = list(json.loads(str(json_resp)))
except Exception as e:
return "Exception found: " + str(e)
data_item = None
if len(dict_list) == 1:
sample_server_dict = dict(dict_list[0])
for key, val in sample_server_dict.iteritems():
if key == "ServerMonitoringInfo" or key == "ServerInventoryInfo" and select_item in val:
data_item = val[select_item]
elif len(dict_list) == 0:
if len(dict_list) == 0:
error_msg = "No matching objects found for the query"
return error_msg
elif len(dict_list) >= 2:
sample_server_dict = {}
for test_dict in dict_list:
for key, val in test_dict.iteritems():
if key == "ServerMonitoringInfo" or key == "ServerInventoryInfo" and select_item in val:
elif len(dict_list) >= 1:
sample_server_dict = dict(dict_list[0])
for key, val in sample_server_dict.iteritems():
if key == "ServerMonitoringInfo" or key == "ServerInventoryInfo":
if select_item in val:
sample_server_dict[key] = val
data_item = val[select_item]
elif "," in select_item:
select_item_list = select_item.split(",")
data_item = {}
for item in select_item_list:
if item in val:
data_item[item] = val[item]
if not data_item:
error_msg = str(select_item) + " isn't found for the server(s) you requested"
return error_msg
Expand Down Expand Up @@ -320,8 +327,15 @@ def convert_json_to_table(obj, json_resp, select_item=None):
data_dict_list = list(data_info_dict[select_item])
for data_dict in data_dict_list:
data_dict = dict(data_dict)
for key, val in sorted(data_dict.iteritems()):
val_list.append(val)
val_list = list()
val_list.append(server_id)
for key in key_list[1:]:
val = data_dict.get(key)
if val:
val_list.append(val)
else:
val_list.append("N/A")
return_table.add_row(val_list)
else:
for x in range(len(key_list)-1):
val_list.append("N/A")
Expand Down Expand Up @@ -349,17 +363,29 @@ def convert_json_to_table(obj, json_resp, select_item=None):
data_dict_list = list(server_dict["ServerInventoryInfo"][select_item])
for data_dict in data_dict_list:
data_dict = dict(data_dict)
for key, val in sorted(data_dict.iteritems()):
val_list.append(val)
val_list = list()
val_list.append(server_id)
for key in key_list[1:]:
val = data_dict.get(key)
if val:
val_list.append(val)
else:
val_list.append("N/A")
return_table.add_row(val_list)
else:
for x in range(len(key_list) - 1):
val_list.append("N/A")
return_table.add_row(val_list)
return_table.add_row(val_list)
else:
val_list = list()
val_list.append(server_id)
if select_item in data_info_dict:
val_list.append(data_info_dict[str(select_item)])
elif "," in select_item:
select_item_list = select_item.split(",")
for item in select_item_list:
if item in data_info_dict and item in key_list:
val_list.append(data_info_dict[str(item)])
else:
val_list.append("N/A")
return_table.add_row(val_list)
Expand Down

0 comments on commit 2609a31

Please sign in to comment.