Skip to content

Commit 6f125e8

Browse files
Merge pull request #1316 from allmightyspiff/issues900
Support for STDIN on creating and updating tickets.
2 parents c1a3696 + 2193048 commit 6f125e8

File tree

4 files changed

+103
-16
lines changed

4 files changed

+103
-16
lines changed

SoftLayer/CLI/ticket/create.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
@click.command()
1313
@click.option('--title', required=True, help="The title of the ticket")
1414
@click.option('--subject-id', type=int, required=True,
15-
help="""The subject id to use for the ticket,
16-
issue 'slcli ticket subjects' to get the list""")
15+
help="""The subject id to use for the ticket, run 'slcli ticket subjects' to get the list""")
1716
@click.option('--body', help="The ticket body")
1817
@click.option('--hardware', 'hardware_identifier',
1918
help="The identifier for hardware to attach")
@@ -24,11 +23,31 @@
2423
Only settable with Advanced and Premium support. See https://www.ibm.com/cloud/support""")
2524
@environment.pass_env
2625
def cli(env, title, subject_id, body, hardware_identifier, virtual_identifier, priority):
27-
"""Create a support ticket."""
28-
ticket_mgr = SoftLayer.TicketManager(env.client)
26+
"""Create a Infrastructure support ticket.
27+
28+
Example::
29+
30+
Will create the ticket with `Some text`.
31+
32+
slcli ticket create --body="Some text" --subject-id 1522 --hardware 12345 --title "My New Ticket"
2933
34+
Will create the ticket with text from STDIN
35+
36+
cat sometfile.txt | slcli ticket create --subject-id 1003 --virtual 111111 --title "Reboot Me"
37+
38+
Will open the default text editor, and once closed, use that text to create the ticket
39+
40+
slcli ticket create --subject-id 1482 --title "Vyatta Questions..."
41+
"""
42+
ticket_mgr = SoftLayer.TicketManager(env.client)
3043
if body is None:
31-
body = click.edit('\n\n' + ticket.TEMPLATE_MSG)
44+
stdin = click.get_text_stream('stdin')
45+
# Means there is text on the STDIN buffer, read it and add to the ticket
46+
if not stdin.isatty():
47+
body = stdin.read()
48+
# This is an interactive terminal, open a text editor
49+
else:
50+
body = click.edit('\n\n' + ticket.TEMPLATE_MSG)
3251
created_ticket = ticket_mgr.create_ticket(
3352
title=title,
3453
body=body,

SoftLayer/CLI/ticket/update.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,35 @@
1111

1212
@click.command()
1313
@click.argument('identifier')
14-
@click.option('--body', help="The entry that will be appended to the ticket")
14+
@click.option('--body', help="Text to add to the ticket. STDIN or the default text editor will be used otherwise.")
1515
@environment.pass_env
1616
def cli(env, identifier, body):
17-
"""Adds an update to an existing ticket."""
17+
"""Adds an update to an existing ticket.
18+
19+
Example::
20+
21+
Will update the ticket with `Some text`.
22+
23+
slcli ticket update 123456 --body="Some text"
24+
25+
Will update the ticket with text from STDIN
26+
27+
cat sometfile.txt | slcli ticket update 123456
28+
29+
Will open the default text editor, and once closed, use that text to update the ticket
30+
31+
slcli ticket update 123456
32+
"""
1833
mgr = SoftLayer.TicketManager(env.client)
1934

2035
ticket_id = helpers.resolve_id(mgr.resolve_ids, identifier, 'ticket')
21-
2236
if body is None:
23-
body = click.edit('\n\n' + ticket.TEMPLATE_MSG)
24-
37+
stdin = click.get_text_stream('stdin')
38+
# Means there is text on the STDIN buffer, read it and add to the ticket
39+
if not stdin.isatty():
40+
body = stdin.read()
41+
# This is an interactive terminal, open a text editor
42+
else:
43+
body = click.edit('\n\n' + ticket.TEMPLATE_MSG)
2544
mgr.update_ticket(ticket_id=ticket_id, body=body)
2645
env.fout("Ticket Updated!")

docs/cli/tickets.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
Support Tickets
44
===============
55

6+
The SoftLayer ticket API is used to create "classic" or Infrastructure Support cases.
7+
These tickets will still show up in your web portal, but for the more unified case management API,
8+
see the `Case Management API <https://cloud.ibm.com/apidocs/case-management#introduction>`_
9+
10+
.. note:: Windows Git-Bash users might run into issues with `ticket create` and `ticket update` if --body isn't used, as it doesn't report that it is a real TTY to python, so the default editor can not be launched.
11+
612
.. click:: SoftLayer.CLI.ticket.create:cli
713
:prog: ticket create
814
:show-nested:

tests/CLI/modules/ticket_tests.py

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@
1313
from SoftLayer import testing
1414

1515

16+
class FakeTTY():
17+
"""A fake object to fake STD input"""
18+
def __init__(self, isatty=False, read="Default Output"):
19+
"""Sets isatty and read"""
20+
self._isatty = isatty
21+
self._read = read
22+
23+
def isatty(self):
24+
"""returns self.isatty"""
25+
return self._isatty
26+
27+
def read(self):
28+
"""returns self.read"""
29+
return self._read
30+
31+
1632
class TicketTests(testing.TestCase):
1733

1834
def test_list(self):
@@ -99,18 +115,33 @@ def test_create_and_attach(self):
99115
identifier=100)
100116

101117
@mock.patch('click.edit')
102-
def test_create_no_body(self, edit_mock):
118+
@mock.patch('click.get_text_stream')
119+
def test_create_no_body(self, isatty_mock, edit_mock):
120+
fake_tty = FakeTTY(True, "TEST")
121+
isatty_mock.return_value = fake_tty
103122
edit_mock.return_value = 'ticket body'
104-
result = self.run_command(['ticket', 'create', '--title=Test',
105-
'--subject-id=1000'])
123+
result = self.run_command(['ticket', 'create', '--title=Test', '--subject-id=1000'])
106124
self.assert_no_fail(result)
107125

108126
args = ({'subjectId': 1000,
109127
'assignedUserId': 12345,
110128
'title': 'Test'}, 'ticket body')
111129

112-
self.assert_called_with('SoftLayer_Ticket', 'createStandardTicket',
113-
args=args)
130+
self.assert_called_with('SoftLayer_Ticket', 'createStandardTicket', args=args)
131+
132+
@mock.patch('click.get_text_stream')
133+
def test_create_no_body_stdin(self, isatty_mock):
134+
fake_tty = FakeTTY(False, "TEST TICKET BODY")
135+
isatty_mock.return_value = fake_tty
136+
result = self.run_command(['ticket', 'create', '--title=Test', '--subject-id=1000'])
137+
print(result.output)
138+
self.assert_no_fail(result)
139+
140+
args = ({'subjectId': 1000,
141+
'assignedUserId': 12345,
142+
'title': 'Test'}, 'TEST TICKET BODY')
143+
144+
self.assert_called_with('SoftLayer_Ticket', 'createStandardTicket', args=args)
114145

115146
def test_subjects(self):
116147
list_expected_ids = [1001, 1002, 1003, 1004, 1005]
@@ -294,12 +325,24 @@ def test_ticket_update(self):
294325
self.assert_called_with('SoftLayer_Ticket', 'addUpdate', args=({'entry': 'Testing'},), identifier=100)
295326

296327
@mock.patch('click.edit')
297-
def test_ticket_update_no_body(self, edit_mock):
328+
@mock.patch('click.get_text_stream')
329+
def test_ticket_update_no_body(self, isatty_mock, edit_mock):
330+
fake_tty = FakeTTY(True, "TEST TICKET BODY")
331+
isatty_mock.return_value = fake_tty
298332
edit_mock.return_value = 'Testing1'
299333
result = self.run_command(['ticket', 'update', '100'])
300334
self.assert_no_fail(result)
301335
self.assert_called_with('SoftLayer_Ticket', 'addUpdate', args=({'entry': 'Testing1'},), identifier=100)
302336

337+
@mock.patch('click.get_text_stream')
338+
def test_ticket_update_no_body_stdin(self, isatty_mock):
339+
fake_tty = FakeTTY(False, "TEST TICKET BODY")
340+
isatty_mock.return_value = fake_tty
341+
result = self.run_command(['ticket', 'update', '100'])
342+
self.assert_no_fail(result)
343+
self.assert_called_with('SoftLayer_Ticket', 'addUpdate',
344+
args=({'entry': 'TEST TICKET BODY'},), identifier=100)
345+
303346
def test_ticket_json(self):
304347
result = self.run_command(['--format=json', 'ticket', 'detail', '1'])
305348
expected = {'Case_Number': 'CS123456',

0 commit comments

Comments
 (0)