Skip to content

Commit

Permalink
Merge pull request #1024 from allmightyspiff/1019
Browse files Browse the repository at this point in the history
#1019 - Ability to set ticket priority
  • Loading branch information
allmightyspiff committed Aug 27, 2018
2 parents cdaebcc + 45030b0 commit 1765af9
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 47 deletions.
10 changes: 10 additions & 0 deletions SoftLayer/CLI/ticket/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@

TEMPLATE_MSG = "***** SoftLayer Ticket Content ******"

# https://softlayer.github.io/reference/services/SoftLayer_Ticket_Priority/getPriorities/
PRIORITY_MAP = [
'No Priority',
'Severity 1 - Critical Impact / Service Down',
'Severity 2 - Significant Business Impact',
'Severity 3 - Minor Business Impact',
'Severity 4 - Minimal Business Impact'
]


def get_ticket_results(mgr, ticket_id, update_count=1):
"""Get output about a ticket.
Expand All @@ -24,6 +33,7 @@ def get_ticket_results(mgr, ticket_id, update_count=1):

table.add_row(['id', ticket['id']])
table.add_row(['title', ticket['title']])
table.add_row(['priority', PRIORITY_MAP[ticket.get('priority', 0)]])
if ticket.get('assignedUser'):
user = ticket['assignedUser']
table.add_row([
Expand Down
27 changes: 11 additions & 16 deletions SoftLayer/CLI/ticket/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,38 @@

@click.command()
@click.option('--title', required=True, help="The title of the ticket")
@click.option('--subject-id',
type=int,
required=True,
@click.option('--subject-id', type=int, required=True,
help="""The subject id to use for the ticket,
issue 'slcli ticket subjects' to get the list""")
@click.option('--body', help="The ticket body")
@click.option('--hardware',
'hardware_identifier',
@click.option('--hardware', 'hardware_identifier',
help="The identifier for hardware to attach")
@click.option('--virtual',
'virtual_identifier',
@click.option('--virtual', 'virtual_identifier',
help="The identifier for a virtual server to attach")
@click.option('--priority', 'priority', type=click.Choice(['1', '2', '3', '4']), default=None,
help="""Ticket priority, from 1 (Critical) to 4 (Minimal Impact).
Only settable with Advanced and Premium support. See https://www.ibm.com/cloud/support""")
@environment.pass_env
def cli(env, title, subject_id, body, hardware_identifier, virtual_identifier):
def cli(env, title, subject_id, body, hardware_identifier, virtual_identifier, priority):
"""Create a support ticket."""
ticket_mgr = SoftLayer.TicketManager(env.client)

if body is None:
body = click.edit('\n\n' + ticket.TEMPLATE_MSG)

created_ticket = ticket_mgr.create_ticket(
title=title,
body=body,
subject=subject_id)
subject=subject_id,
priority=priority)

if hardware_identifier:
hardware_mgr = SoftLayer.HardwareManager(env.client)
hardware_id = helpers.resolve_id(hardware_mgr.resolve_ids,
hardware_identifier,
'hardware')
hardware_id = helpers.resolve_id(hardware_mgr.resolve_ids, hardware_identifier, 'hardware')
ticket_mgr.attach_hardware(created_ticket['id'], hardware_id)

if virtual_identifier:
vs_mgr = SoftLayer.VSManager(env.client)
vs_id = helpers.resolve_id(vs_mgr.resolve_ids,
virtual_identifier,
'VS')
vs_id = helpers.resolve_id(vs_mgr.resolve_ids, virtual_identifier, 'VS')
ticket_mgr.attach_virtual_server(created_ticket['id'], vs_id)

env.fout(ticket.get_ticket_results(ticket_mgr, created_ticket['id']))
20 changes: 9 additions & 11 deletions SoftLayer/CLI/ticket/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,30 @@


@click.command()
@click.option('--open / --closed', 'is_open',
help="Display only open or closed tickets",
default=True)
@click.option('--open / --closed', 'is_open', default=True,
help="Display only open or closed tickets")
@environment.pass_env
def cli(env, is_open):
"""List tickets."""
ticket_mgr = SoftLayer.TicketManager(env.client)
table = formatting.Table([
'id', 'assigned_user', 'title', 'last_edited', 'status', 'updates', 'priority'
])

tickets = ticket_mgr.list_tickets(open_status=is_open,
closed_status=not is_open)

table = formatting.Table(['id', 'assigned_user', 'title',
'last_edited', 'status'])

tickets = ticket_mgr.list_tickets(open_status=is_open, closed_status=not is_open)
for ticket in tickets:
user = formatting.blank()
if ticket.get('assignedUser'):
user = "%s %s" % (ticket['assignedUser']['firstName'],
ticket['assignedUser']['lastName'])
user = "%s %s" % (ticket['assignedUser']['firstName'], ticket['assignedUser']['lastName'])

table.add_row([
ticket['id'],
user,
click.wrap_text(ticket['title']),
ticket['lastEditDate'],
ticket['status']['name'],
ticket.get('updateCount', 0),
ticket.get('priority', 0)
])

env.fout(table)
29 changes: 13 additions & 16 deletions SoftLayer/managers/ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def list_tickets(self, open_status=True, closed_status=True):
:param boolean open_status: include open tickets
:param boolean closed_status: include closed tickets
"""
mask = ('id, title, assignedUser[firstName, lastName],'
'createDate,lastEditDate,accountId,status')
mask = """mask[id, title, assignedUser[firstName, lastName], priority,
createDate, lastEditDate, accountId, status, updateCount]"""

call = 'getTickets'
if not all([open_status, closed_status]):
Expand All @@ -53,25 +53,28 @@ def get_ticket(self, ticket_id):
:returns: dict -- information about the specified ticket
"""
mask = ('id, title, assignedUser[firstName, lastName],status,'
'createDate,lastEditDate,updates[entry,editor],updateCount')
mask = """mask[id, title, assignedUser[firstName, lastName],status,
createDate,lastEditDate,updates[entry,editor],updateCount, priority]"""
return self.ticket.getObject(id=ticket_id, mask=mask)

def create_ticket(self, title=None, body=None, subject=None):
def create_ticket(self, title=None, body=None, subject=None, priority=None):
"""Create a new ticket.
:param string title: title for the new ticket
:param string body: body for the new ticket
:param integer subject: id of the subject to be assigned to the ticket
:param integer priority: Value from 1 (highest) to 4 (lowest)
"""

current_user = self.account.getCurrentUser()
new_ticket = {
'subjectId': subject,
'contents': body,
'assignedUserId': current_user['id'],
'title': title,
}
if priority is not None:
new_ticket['priority'] = int(priority)

created_ticket = self.ticket.createStandardTicket(new_ticket, body)
return created_ticket

Expand All @@ -83,18 +86,12 @@ def update_ticket(self, ticket_id=None, body=None):
"""
return self.ticket.addUpdate({'entry': body}, id=ticket_id)

def upload_attachment(self, ticket_id=None, file_path=None,
file_name=None):
def upload_attachment(self, ticket_id=None, file_path=None, file_name=None):
"""Upload an attachment to a ticket.
:param integer ticket_id: the id of the ticket to
upload the attachment to
:param string file_path:
The path of the attachment to be uploaded
:param string file_name:
The name of the attachment shown
in the ticket
:param integer ticket_id: the id of the ticket to upload the attachment to
:param string file_path: The path of the attachment to be uploaded
:param string file_name: The name of the attachment shown in the ticket
:returns: dict -- The uploaded attachment
"""
file_content = None
Expand Down
105 changes: 101 additions & 4 deletions tests/CLI/modules/ticket_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import mock

from SoftLayer.CLI import exceptions
from SoftLayer.CLI import formatting
from SoftLayer.CLI import ticket
from SoftLayer.managers import TicketManager
from SoftLayer import testing


Expand All @@ -20,10 +23,12 @@ def test_list(self):
'assigned_user': 'John Smith',
'id': 102,
'last_edited': '2013-08-01T14:16:47-07:00',
'priority': 0,
'status': 'Open',
'title': 'Cloud Instance Cancellation - 08/01/13'}]
'title': 'Cloud Instance Cancellation - 08/01/13',
'updates': 0}]
self.assert_no_fail(result)
self.assertEqual(json.loads(result.output), expected)
self.assertEqual(expected, json.loads(result.output))

def test_detail(self):
result = self.run_command(['ticket', 'detail', '1'])
Expand All @@ -32,6 +37,7 @@ def test_detail(self):
'created': '2013-08-01T14:14:04-07:00',
'edited': '2013-08-01T14:16:47-07:00',
'id': 100,
'priority': 'No Priority',
'status': 'Closed',
'title': 'Cloud Instance Cancellation - 08/01/13',
'update 1': 'a bot says something',
Expand All @@ -53,8 +59,23 @@ def test_create(self):
'assignedUserId': 12345,
'title': 'Test'}, 'ticket body')

self.assert_called_with('SoftLayer_Ticket', 'createStandardTicket',
args=args)
self.assert_called_with('SoftLayer_Ticket', 'createStandardTicket', args=args)

def test_create_with_priority(self):
result = self.run_command(['ticket', 'create', '--title=Test',
'--subject-id=1000',
'--body=ticket body',
'--priority=1'])

self.assert_no_fail(result)

args = ({'subjectId': 1000,
'contents': 'ticket body',
'assignedUserId': 12345,
'title': 'Test',
'priority': 1}, 'ticket body')

self.assert_called_with('SoftLayer_Ticket', 'createStandardTicket', args=args)

def test_create_and_attach(self):
result = self.run_command(['ticket', 'create', '--title=Test',
Expand Down Expand Up @@ -204,3 +225,79 @@ def test_ticket_upload(self):
args=({"filename": "a_file_name",
"data": b"ticket attached data"},),
identifier=1)

def test_init_ticket_results(self):
ticket_mgr = TicketManager(self.client)
ticket_table = ticket.get_ticket_results(ticket_mgr, 100)
self.assert_called_with('SoftLayer_Ticket', 'getObject', identifier=100)
self.assertIsInstance(ticket_table, formatting.KeyValueTable)

ticket_object = ticket_table.to_python()
self.assertEqual('No Priority', ticket_object['priority'])
self.assertEqual(100, ticket_object['id'])

def test_init_ticket_results_asigned_user(self):
mock = self.set_mock('SoftLayer_Ticket', 'getObject')
mock.return_value = {
"id": 100,
"title": "Simple Title",
"priority": 1,
"assignedUser": {
"firstName": "Test",
"lastName": "User"
},
"status": {
"name": "Closed"
},
"createDate": "2013-08-01T14:14:04-07:00",
"lastEditDate": "2013-08-01T14:16:47-07:00",
"updates": [{'entry': 'a bot says something'}]
}

ticket_mgr = TicketManager(self.client)
ticket_table = ticket.get_ticket_results(ticket_mgr, 100)
self.assert_called_with('SoftLayer_Ticket', 'getObject', identifier=100)
self.assertIsInstance(ticket_table, formatting.KeyValueTable)

ticket_object = ticket_table.to_python()
self.assertEqual('Severity 1 - Critical Impact / Service Down', ticket_object['priority'])
self.assertEqual('Test User', ticket_object['user'])

def test_ticket_summary(self):
mock = self.set_mock('SoftLayer_Account', 'getObject')
mock.return_value = {
'openTicketCount': 1,
'closedTicketCount': 2,
'openBillingTicketCount': 3,
'openOtherTicketCount': 4,
'openSalesTicketCount': 5,
'openSupportTicketCount': 6,
'openAccountingTicketCount': 7
}
expected = [
{'Status': 'Open',
'count': [
{'Type': 'Accounting', 'count': 7},
{'Type': 'Billing', 'count': 3},
{'Type': 'Sales', 'count': 5},
{'Type': 'Support', 'count': 6},
{'Type': 'Other', 'count': 4},
{'Type': 'Total', 'count': 1}]},
{'Status': 'Closed', 'count': 2}
]
result = self.run_command(['ticket', 'summary'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Account', 'getObject')
self.assertEqual(expected, json.loads(result.output))

def test_ticket_update(self):
result = self.run_command(['ticket', 'update', '100', '--body=Testing'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Ticket', 'addUpdate', args=({'entry': 'Testing'},), identifier=100)

@mock.patch('click.edit')
def test_ticket_update_no_body(self, edit_mock):
edit_mock.return_value = 'Testing1'
result = self.run_command(['ticket', 'update', '100'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Ticket', 'addUpdate', args=({'entry': 'Testing1'},), identifier=100)

0 comments on commit 1765af9

Please sign in to comment.