def find_service_by_arguments(manager, account, service_id, path, show_simple_props = False):
    
    if service_id is not None:
        show_service_instance = manager.get_service_by_id(account, service_id)
        if show_service_instance.has_key("GetServiceByIdResult") and len(show_service_instance["GetServiceByIdResult"]) == 1:
            for k in show_service_instance["GetServiceByIdResult"]:
                service_to_return = AtomiaService(show_simple_props = show_simple_props)
                service_to_return.from_simplexml(k)
                return service_to_return if service_to_return.logical_id is not None else None
        
    elif path is not None:
        show_service_locator = json.loads(path)
        if len(show_service_locator) > 0:
            parent_service_for_criteria = None
            for count in show_service_locator:
                if isinstance(count.values()[0], dict) or count.values()[0] == '':
                    service_search_criteria_list = []
                    search_properties = []
                    if parent_service_for_criteria is not None:
                        tmp_ssc = AtomiaServiceSearchCriteria(str(count.keys()[0]), '', parent_service_for_criteria)
                    else:
                        tmp_ssc = AtomiaServiceSearchCriteria(str(count.keys()[0]), '')
                        
                    service_search_criteria_list.append(tmp_ssc.to_xml_friendly_object('atom:ServiceSearchCriteria', 'ServiceSearchCriteria'))
                    if isinstance(count.values()[0], dict):
                        for propk in count.values()[0]:
                            tmp_property = AtomiaServiceSearchCriteriaProperty(str(propk), str(count.values()[0][propk]))
                            search_properties.append(tmp_property.to_xml_friendly_object('arr:KeyValueOfstringstring', 'KeyValueOfstringstring'))
                    test = manager.find_services_by_path_with_paging(service_search_criteria_list, account, search_properties=search_properties)
                    if test.itervalues().next() is not None and test.itervalues().next().children() is not None and len(test.itervalues().next().children()) > 0:
                        for k in test.itervalues().next().children():
                            parent_service_for_criteria = AtomiaService(show_simple_props = show_simple_props)
                            parent_service_for_criteria.from_simplexml(k)
                            break
                    else:
                        parent_service_for_criteria = None
                        break
        
                elif count.values()[0] is not None:
                    parent_service_for_criteria = manager.get_service_by_id(account, str(count.values()[0])) 
                    parent_service_for_criteria_pretty = AtomiaService(show_simple_props = show_simple_props)
                    parent_service_for_criteria_pretty.from_simplexml(parent_service_for_criteria.itervalues().next())
                    
                    if parent_service_for_criteria_pretty.logical_id is None:
                        parent_service_for_criteria = None
                    else:
                        parent_service_for_criteria = parent_service_for_criteria_pretty
                else:
                    raise InputError("Wrong input format of service locator for: " + str(count.keys()[0]))
                
            return parent_service_for_criteria
    else:
        return None
def service_modify(args, manager, managernative):
    
    if args.servicedata is not None:
        service_description = json.loads(args.servicedata)
        if isinstance(service_description, dict):
            if service_description.has_key('properties'):
                if isinstance(service_description['properties'], dict):
                    service_properties = service_description['properties']
                else:
                    raise InputError("Invalid format of properties argument.")
            else:
                raise InputError("properties is required argument for this action")
        else:
            raise InputError("Invalid format of service argument.")
    else:
        raise InputError("service is required argument for this action.")
    
    current_service = find_service_by_arguments(manager, args.account, args.service, args.path)
    if current_service is None:
        raise Exception("Could not find service to be modified.")
    
    
    
    if current_service.properties is not None and len(current_service.properties) > 0:
        non_existing_props_list = list(set(service_properties.keys())-set(map(lambda x: x.name, current_service.properties)))
        if len(non_existing_props_list) > 0:
            raise Exception("Non-existing property: " + non_existing_props_list[0])
        else:
            for list_count in current_service.properties:
                if (service_properties.has_key(list_count.name)):
                    list_count.prop_string_value = service_properties[list_count.name]

        if args.noresource:
            modify_service_result = managernative.modify_service_native([current_service.to_xml_friendly_object()], False)
        else:
            modify_service_result = manager.modify_service([current_service.to_xml_friendly_object()], args.account)
        
        if modify_service_result.has_key("ModifyServiceResult") and len(modify_service_result["ModifyServiceResult"]) == 1:
            for k in modify_service_result["ModifyServiceResult"]:
                modified_service = AtomiaService()
                modified_service.from_simplexml(k)
                modified_service.print_me(False, True)
                return modified_service
        else:
            raise Exception("Could not modify service: " + current_service.name)
def service_list(args, manager):
    current_service = find_service_by_arguments(manager, args.account,
                                                args.parent, args.path,
                                                args.simpleProps)
    if current_service is not None:
        child_services_result = manager.list_existing_service(
            [current_service.to_xml_friendly_object()], args.account)
    else:
        if args.service is not None or args.path is not None:
            raise Exception("Could not find the parent service.")
        else:
            child_services_result = manager.list_existing_service(
                None, args.account)

    list_result_list = []
    if child_services_result.has_key(
            "ListExistingServicesResult"
    ) and child_services_result["ListExistingServicesResult"].children(
    ) is not None and len(child_services_result["ListExistingServicesResult"].
                          children()) > 0:
        for j in child_services_result["ListExistingServicesResult"].children(
        ):
            child_service = AtomiaService(show_simple_props=args.simpleProps)
            child_service.from_simplexml(j)
            list_result_list.append(child_service.to_print_friendly(False))

        result = json_repr(list_result_list)
        ''' filter results '''
        if args.filter is not None:
            from jsonpath_rw import jsonpath
            result = jsonpath.jsonpath(json.loads(result), args.filter)

            if args.first is True:
                if result:
                    result = result[0]
                    print json_repr(result).strip('"')
                else:
                    print ""
            else:
                print json_repr(result)
        else:
            print result
    ''' else:
         raise Exception("No child services found for the service with logical id: " + current_service.logical_id) '''
    return list_result_list
def service_list(args, manager):
    current_service = find_service_by_arguments(manager, args.account, args.parent, args.path, args.simpleProps)
    if current_service is not None:
        child_services_result = manager.list_existing_service([current_service.to_xml_friendly_object()], args.account)
    else:
        if args.service is not None or args.path is not None:
            raise Exception("Could not find the parent service.")
        else:
            child_services_result = manager.list_existing_service(None, args.account)
            
    list_result_list = []
    if child_services_result.has_key("ListExistingServicesResult") and child_services_result["ListExistingServicesResult"].children() is not None and len(child_services_result["ListExistingServicesResult"].children()) > 0:
        for j in child_services_result["ListExistingServicesResult"].children():
            child_service = AtomiaService(show_simple_props = args.simpleProps)
            child_service.from_simplexml(j)
            list_result_list.append(child_service.to_print_friendly(False))
        
        result = json_repr(list_result_list)
        
        ''' filter results '''
        if args.filter is not None:
            from jsonpath_rw import jsonpath
            result = jsonpath.jsonpath(json.loads(result), args.filter)
            
            if args.first is True:
                if result:
                    result = result[0]
                    print json_repr(result).strip('"')
                else:
                    print ""
            else: 
                print json_repr(result)
        else:
            print result
    ''' else:
         raise Exception("No child services found for the service with logical id: " + current_service.logical_id) '''
    return list_result_list
def service_modify(args, manager, managernative):

    if args.servicedata is not None:
        service_description = json.loads(args.servicedata)
        if isinstance(service_description, dict):
            if service_description.has_key('properties'):
                if isinstance(service_description['properties'], dict):
                    service_properties = service_description['properties']
                else:
                    raise InputError("Invalid format of properties argument.")
            else:
                raise InputError(
                    "properties is required argument for this action")
        else:
            raise InputError("Invalid format of service argument.")
    else:
        raise InputError("service is required argument for this action.")

    current_service = find_service_by_arguments(manager, args.account,
                                                args.service, args.path)
    if current_service is None:
        raise Exception("Could not find service to be modified.")

    if current_service.properties is not None and len(
            current_service.properties) > 0:
        non_existing_props_list = list(
            set(service_properties.keys()) -
            set(map(lambda x: x.name, current_service.properties)))
        if len(non_existing_props_list) > 0:
            raise Exception("Non-existing property: " +
                            non_existing_props_list[0])
        else:
            for list_count in current_service.properties:
                if (service_properties.has_key(list_count.name)):
                    list_count.prop_string_value = service_properties[
                        list_count.name]

        if args.noresource:
            modify_service_result = managernative.modify_service_native(
                [current_service.to_xml_friendly_object()], False)
        else:
            modify_service_result = manager.modify_service(
                [current_service.to_xml_friendly_object()], args.account)

        if modify_service_result.has_key("ModifyServiceResult") and len(
                modify_service_result["ModifyServiceResult"]) == 1:
            for k in modify_service_result["ModifyServiceResult"]:
                modified_service = AtomiaService()
                modified_service.from_simplexml(k)
                modified_service.print_me(False, True)
                return modified_service
        else:
            raise Exception("Could not modify service: " +
                            current_service.name)
def service_add(args, manager, managernative):
    if args.accountdata is not None:
        account_data = json.loads(args.accountdata)
    else:
        account_data = None

    if args.servicedata is not None:
        service_description = json.loads(args.servicedata)
        if isinstance(service_description, dict):
            if service_description.has_key('name'):
                service_name = service_description['name']
            else:
                raise InputError("service argument must contain key name")
            
            if service_description.has_key('properties'):
                if isinstance(service_description['properties'], dict):
                    service_properties = service_description['properties']
                else:
                    service_properties = None
            else:
                service_properties = None
        else:
            raise InputError("Invalid format of find_options argument.")
    else:
        raise InputError("service is required argument for this action.")
    
    parent_service = find_service_by_arguments(manager, args.account, args.parent, args.path)
    
    if parent_service is not None:
        created_service_result = manager.create_service(service_name, [parent_service.to_xml_friendly_object()], args.account)
    else:
        created_service_result = manager.create_service(service_name, None, args.account)
    
    if created_service_result.has_key("CreateServiceResult") and len(created_service_result["CreateServiceResult"]) == 1:
        for j in created_service_result["CreateServiceResult"]:
            created_service = AtomiaService()
            created_service.from_simplexml(j)
            
            if service_properties is not None and created_service.properties is not None and len(created_service.properties) > 0:
                for list_count in created_service.properties:
                    if (service_properties.has_key(list_count.name)):
                        if (service_properties[list_count.name] == 'null' or service_properties[list_count.name] == 'NULL'):
                            list_count.prop_string_value = None
                        else:
                            list_count.prop_string_value = service_properties[list_count.name] 

            if args.noresource:
                if args.packagedata is not None:
                    package_data = json.loads(args.packagedata)
                    if isinstance(package_data, dict) and package_data.has_key('package_id') and package_data.has_key('package_name'):
                            package_arg = [ AtomiaPackage(package_id=package_data['package_id'], package_name=package_data['package_name']).to_xml_friendly_object() ]
                    else:
                        raise InputError("packagedata argument must contain key package_id and package_name")
                else:
                    package_arg = None

                if args.resourcename is None:
                    raise Exception("When specifying --noresource you have to specify --resourcename as well")
                elif parent_service is not None:
                    add_service_result = managernative.add_service_native([created_service.to_xml_friendly_object()], [parent_service.to_xml_friendly_object()], args.resourcename, None, args.account, package_arg, False)
                else:
                    add_service_result = managernative.add_service_native([created_service.to_xml_friendly_object()], None, args.resourcename, None, args.account, package_arg, False)
            else:
                if parent_service is not None:
                    add_service_result = manager.add_service([created_service.to_xml_friendly_object()], [parent_service.to_xml_friendly_object()], args.account)
                else:
                    add_service_result = manager.add_service([created_service.to_xml_friendly_object()], None, args.account)
            
            if add_service_result.has_key("AddServiceResult") and len(add_service_result["AddServiceResult"]) == 1:
                for k in add_service_result["AddServiceResult"]:
                    added_service = AtomiaService()
                    added_service.from_simplexml(k)
                    added_service.print_me(args.filter, args.first, False, True)
                    return added_service
            else:
                raise Exception("Could not add service: " + created_service.name)
            
    else:
        raise Exception("Could not create service: " + service_name)
def service_find(args, manager):
    
    if args.query is not None:
        find_options = json.loads(args.query)
        if isinstance(find_options, dict):
            if find_options.has_key('name'):
                service_name = find_options['name']
            else:
                raise InputError("find_options argument must contain key name")
            
            relative_path = find_options['path'] if find_options.has_key('path') else ''
            result_page = find_options['page'] if find_options.has_key('page') else '0'
            result_count = find_options['count'] if find_options.has_key('count') else '100'
            
            if find_options.has_key('properties'):
                if isinstance(find_options['properties'], dict):
                    service_properties = find_options['properties']
                else:
                    raise InputError("Invalid format of the properties key")
            else:
                service_properties = None
        else:
            raise InputError("Invalid format of query argument.")
    else:
        raise InputError("query is required argument for this action.")
    
    parent_service = find_service_by_arguments(manager, args.account, args.parent, args.path, args.simpleProps)
    
    service_search_criteria_list = []
    search_properties = []
    if parent_service is not None:
        tmp_ssc = AtomiaServiceSearchCriteria(service_name, relative_path, parent_service)
    else:
        tmp_ssc = AtomiaServiceSearchCriteria(service_name, relative_path)
    
    service_search_criteria_list.append(tmp_ssc.to_xml_friendly_object('atom:ServiceSearchCriteria', 'ServiceSearchCriteria'))
    
    if service_properties is not None:
        for propk in service_properties:
            tmp_property = AtomiaServiceSearchCriteriaProperty(str(propk), str(service_properties[propk]))
            search_properties.append(tmp_property.to_xml_friendly_object('arr:KeyValueOfstringstring', 'KeyValueOfstringstring'))
    
    find_action_res = manager.find_services_by_path_with_paging(service_search_criteria_list, args.account, search_properties=search_properties, page_number=result_page, page_size = result_count)
    
    find_result_list = []
    if find_action_res.itervalues().next() is not None and find_action_res.itervalues().next().children() is not None:
        
        for k in find_action_res.itervalues().next().children():
            find_action_result = AtomiaService(show_simple_props = args.simpleProps)
            find_action_result.from_simplexml(k)
            find_result_list.append(find_action_result.to_print_friendly(False, True))
        
        result = json_repr(find_result_list)
        
        ''' filter results '''
        if args.filter is not None:
            import jsonpath
            result = jsonpath.jsonpath(json.loads(result), args.filter)
            
            if args.first is True:
                if result:
                    result = result[0]
                    print json_repr(result).strip('"')
                else:
                    print ""
            else: 
                print json_repr(result)
        else:
            print result
    ''' else:
        raise Exception("Could not find service: " + service_name) '''
    return find_result_list
def find_service_by_arguments(manager,
                              account,
                              service_id,
                              path,
                              show_simple_props=False):

    if service_id is not None:
        show_service_instance = manager.get_service_by_id(account, service_id)
        if show_service_instance.has_key("GetServiceByIdResult") and len(
                show_service_instance["GetServiceByIdResult"]) == 1:
            for k in show_service_instance["GetServiceByIdResult"]:
                service_to_return = AtomiaService(
                    show_simple_props=show_simple_props)
                service_to_return.from_simplexml(k)
                return service_to_return if service_to_return.logical_id is not None else None

    elif path is not None:
        show_service_locator = json.loads(path)
        if len(show_service_locator) > 0:
            parent_service_for_criteria = None
            for count in show_service_locator:
                if isinstance(count.values()[0],
                              dict) or count.values()[0] == '':
                    service_search_criteria_list = []
                    search_properties = []
                    if parent_service_for_criteria is not None:
                        tmp_ssc = AtomiaServiceSearchCriteria(
                            str(count.keys()[0]), '',
                            parent_service_for_criteria)
                    else:
                        tmp_ssc = AtomiaServiceSearchCriteria(
                            str(count.keys()[0]), '')

                    service_search_criteria_list.append(
                        tmp_ssc.to_xml_friendly_object(
                            'atom:ServiceSearchCriteria',
                            'ServiceSearchCriteria'))
                    if isinstance(count.values()[0], dict):
                        for propk in count.values()[0]:
                            tmp_property = AtomiaServiceSearchCriteriaProperty(
                                str(propk), str(count.values()[0][propk]))
                            search_properties.append(
                                tmp_property.to_xml_friendly_object(
                                    'arr:KeyValueOfstringstring',
                                    'KeyValueOfstringstring'))
                    test = manager.find_services_by_path_with_paging(
                        service_search_criteria_list,
                        account,
                        search_properties=search_properties)
                    if test.itervalues(
                    ).next() is not None and test.itervalues().next().children(
                    ) is not None and len(
                            test.itervalues().next().children()) > 0:
                        for k in test.itervalues().next().children():
                            parent_service_for_criteria = AtomiaService(
                                show_simple_props=show_simple_props)
                            parent_service_for_criteria.from_simplexml(k)
                            break
                    else:
                        parent_service_for_criteria = None
                        break

                elif count.values()[0] is not None:
                    parent_service_for_criteria = manager.get_service_by_id(
                        account, str(count.values()[0]))
                    parent_service_for_criteria_pretty = AtomiaService(
                        show_simple_props=show_simple_props)
                    parent_service_for_criteria_pretty.from_simplexml(
                        parent_service_for_criteria.itervalues().next())

                    if parent_service_for_criteria_pretty.logical_id is None:
                        parent_service_for_criteria = None
                    else:
                        parent_service_for_criteria = parent_service_for_criteria_pretty
                else:
                    raise InputError(
                        "Wrong input format of service locator for: " +
                        str(count.keys()[0]))

            return parent_service_for_criteria
    else:
        return None
def service_add(args, manager, managernative):
    if args.accountdata is not None:
        account_data = json.loads(args.accountdata)
    else:
        account_data = None

    if args.servicedata is not None:
        service_description = json.loads(args.servicedata)
        if isinstance(service_description, dict):
            if service_description.has_key('name'):
                service_name = service_description['name']
            else:
                raise InputError("service argument must contain key name")

            if service_description.has_key('properties'):
                if isinstance(service_description['properties'], dict):
                    service_properties = service_description['properties']
                else:
                    service_properties = None
            else:
                service_properties = None
        else:
            raise InputError("Invalid format of find_options argument.")
    else:
        raise InputError("service is required argument for this action.")

    parent_service = find_service_by_arguments(manager, args.account,
                                               args.parent, args.path)

    if parent_service is not None:
        created_service_result = manager.create_service(
            service_name, [parent_service.to_xml_friendly_object()],
            args.account)
    else:
        created_service_result = manager.create_service(
            service_name, None, args.account)

    if created_service_result.has_key("CreateServiceResult") and len(
            created_service_result["CreateServiceResult"]) == 1:
        for j in created_service_result["CreateServiceResult"]:
            created_service = AtomiaService()
            created_service.from_simplexml(j)

            if service_properties is not None and created_service.properties is not None and len(
                    created_service.properties) > 0:
                for list_count in created_service.properties:
                    if (service_properties.has_key(list_count.name)):
                        if (service_properties[list_count.name] == 'null' or
                                service_properties[list_count.name] == 'NULL'):
                            list_count.prop_string_value = None
                        else:
                            list_count.prop_string_value = service_properties[
                                list_count.name]

            if args.noresource:
                if args.packagedata is not None:
                    package_data = json.loads(args.packagedata)
                    if isinstance(package_data, dict) and package_data.has_key(
                            'package_id') and package_data.has_key(
                                'package_name'):
                        package_arg = [
                            AtomiaPackage(
                                package_id=package_data['package_id'],
                                package_name=package_data['package_name']).
                            to_xml_friendly_object()
                        ]
                    else:
                        raise InputError(
                            "packagedata argument must contain key package_id and package_name"
                        )
                else:
                    package_arg = None

                if args.resourcename is None:
                    raise Exception(
                        "When specifying --noresource you have to specify --resourcename as well"
                    )
                elif parent_service is not None:
                    add_service_result = managernative.add_service_native(
                        [created_service.to_xml_friendly_object()],
                        [parent_service.to_xml_friendly_object()],
                        args.resourcename, None, args.account, package_arg,
                        False)
                else:
                    add_service_result = managernative.add_service_native(
                        [created_service.to_xml_friendly_object()], None,
                        args.resourcename, None, args.account, package_arg,
                        False)
            else:
                if parent_service is not None:
                    add_service_result = manager.add_service(
                        [created_service.to_xml_friendly_object()],
                        [parent_service.to_xml_friendly_object()],
                        args.account)
                else:
                    add_service_result = manager.add_service(
                        [created_service.to_xml_friendly_object()], None,
                        args.account)

            if add_service_result.has_key("AddServiceResult") and len(
                    add_service_result["AddServiceResult"]) == 1:
                for k in add_service_result["AddServiceResult"]:
                    added_service = AtomiaService()
                    added_service.from_simplexml(k)
                    added_service.print_me(args.filter, args.first, False,
                                           True)
                    return added_service
            else:
                raise Exception("Could not add service: " +
                                created_service.name)

    else:
        raise Exception("Could not create service: " + service_name)
def service_find(args, manager):

    if args.query is not None:
        find_options = json.loads(args.query)
        if isinstance(find_options, dict):
            if find_options.has_key('name'):
                service_name = find_options['name']
            else:
                raise InputError("find_options argument must contain key name")

            relative_path = find_options['path'] if find_options.has_key(
                'path') else ''
            result_page = find_options['page'] if find_options.has_key(
                'page') else '0'
            result_count = find_options['count'] if find_options.has_key(
                'count') else '100'

            if find_options.has_key('properties'):
                if isinstance(find_options['properties'], dict):
                    service_properties = find_options['properties']
                else:
                    raise InputError("Invalid format of the properties key")
            else:
                service_properties = None
        else:
            raise InputError("Invalid format of query argument.")
    else:
        raise InputError("query is required argument for this action.")

    parent_service = find_service_by_arguments(manager, args.account,
                                               args.parent, args.path,
                                               args.simpleProps)

    service_search_criteria_list = []
    search_properties = []
    if parent_service is not None:
        tmp_ssc = AtomiaServiceSearchCriteria(service_name, relative_path,
                                              parent_service)
    else:
        tmp_ssc = AtomiaServiceSearchCriteria(service_name, relative_path)

    service_search_criteria_list.append(
        tmp_ssc.to_xml_friendly_object('atom:ServiceSearchCriteria',
                                       'ServiceSearchCriteria'))

    if service_properties is not None:
        for propk in service_properties:
            tmp_property = AtomiaServiceSearchCriteriaProperty(
                str(propk), str(service_properties[propk]))
            search_properties.append(
                tmp_property.to_xml_friendly_object(
                    'arr:KeyValueOfstringstring', 'KeyValueOfstringstring'))

    find_action_res = manager.find_services_by_path_with_paging(
        service_search_criteria_list,
        args.account,
        search_properties=search_properties,
        page_number=result_page,
        page_size=result_count)

    find_result_list = []
    if find_action_res.itervalues().next(
    ) is not None and find_action_res.itervalues().next().children(
    ) is not None:

        for k in find_action_res.itervalues().next().children():
            find_action_result = AtomiaService(
                show_simple_props=args.simpleProps)
            find_action_result.from_simplexml(k)
            find_result_list.append(
                find_action_result.to_print_friendly(False, True))

        result = json_repr(find_result_list)
        ''' filter results '''
        if args.filter is not None:
            import jsonpath
            result = jsonpath.jsonpath(json.loads(result), args.filter)

            if args.first is True:
                if result:
                    result = result[0]
                    print json_repr(result).strip('"')
                else:
                    print ""
            else:
                print json_repr(result)
        else:
            print result
    ''' else:
        raise Exception("Could not find service: " + service_name) '''
    return find_result_list