Skip to content

Commit 5833bdb

Browse files
author
Frederick Ross
committed
Simplify restrictToHost handling.
Now any attempt to update restrictToHost on an existing input immediately throws an IllegalOperationException. If there is a restrictToHost parameter, it is set internally to be updated so that Splunk 5.0 and 5.0.1 don't reset the restrictToHost parameter on the input. Updated the test suite correspondingly.
1 parent 86918c4 commit 5833bdb

File tree

2 files changed

+27
-70
lines changed

2 files changed

+27
-70
lines changed

splunklib/client.py

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,40 +1914,32 @@ def update(self, **kwargs):
19141914
:return: The input this method was called on.
19151915
:rtype: class:`Input`
19161916
"""
1917-
if self.kind not in ['tcp', 'splunktcp', 'tcp/raw', 'tcp/cooked']:
1918-
result = super(Input, self).update(**kwargs)
1919-
return result
1917+
# UDP and TCP inputs require special handling due to their restrictToHost
1918+
# field. For all other inputs kinds, we can dispatch to the superclass method.
1919+
if self.kind not in ['tcp', 'splunktcp', 'tcp/raw', 'tcp/cooked', 'udp']:
1920+
return super(Input, self).update(**kwargs)
19201921
else:
1921-
# TCP inputs have a property 'restrictToHost' which requires special care.
1922-
1923-
# There is a bug in Splunk < 5.0. Don't bother trying to update restrictToHost.
1924-
if 'restrictToHost' in kwargs and self.service.splunk_version < (5,):
1925-
raise IllegalOperationException("Updating restrictToHost has no effect before Splunk 5.0")
1926-
1927-
# In Splunk 4.x, if you update without restrictToHost as one of the fields,
1928-
# restrictToHost keeps its previous state. In 5.0, it is set to empty string.
1929-
# Thus, we must pass it every time. This doesn't actually introduce a race
1930-
# condition because if someone else has set restrictToHost to a new value on this
1931-
# TCP input, our update request will fail, since our reference to it still uses
1932-
# the old path.
1922+
# The behavior of restrictToHost is inconsistent across input kinds and versions of Splunk.
1923+
# In Splunk 4.x, the name of the entity is only the port, independent of the value of
1924+
# restrictToHost. In Splunk 5.0 this changed so the name will be of the form <restrictToHost>:<port>.
1925+
# In 5.0 and 5.0.1, if you don't supply the restrictToHost value on every update, it will
1926+
# remove the host restriction from the input. As of 5.0.2 you simply can't change restrictToHost
1927+
# on an existing input.
1928+
1929+
# The logic to handle all these cases:
1930+
# - Throw an exception if the user tries to set restrictToHost on an existing input
1931+
# for *any* version of Splunk.
1932+
# - Set the existing restrictToHost value on the update args internally so we don't
1933+
# cause it to change in Splunk 5.0 and 5.0.1.
19331934
to_update = kwargs.copy()
1934-
to_update['restrictToHost'] = kwargs.get('restrictToHost', self._state.content.get('restrictToHost', ''))
1935+
1936+
if 'restrictToHost' in kwargs:
1937+
raise IllegalOperationException("Cannot set restrictToHost on an existing input with the SDK.")
1938+
elif 'restrictToHost' in self._state.content:
1939+
to_update['restrictToHost'] = self._state.content['restrictToHost']
19351940

19361941
# Do the actual update operation.
1937-
result = super(Input, self).update(**to_update)
1938-
1939-
# Now we must update the path in case it changed.
1940-
# The pieces we break it into are:
1941-
# https://localhost:8089/services/data/inputs/tcp/raw/ boris: 10000
1942-
# |------------------ base_path -----------------------| | host || port|
1943-
assert self.path.endswith('/')
1944-
base_path = self.path.rsplit('/', 2)[0]
1945-
host = to_update['restrictToHost'] + ':' if to_update['restrictToHost'] != '' else ''
1946-
port = self.name.split(':', 1)[-1]
1947-
self.path = base_path + '/' + host + port
1948-
# We don't have to update self.name, since it's part of the data
1949-
# fetched from splunkd.
1950-
return result
1942+
return super(Input, self).update(**to_update)
19511943

19521944

19531945
# Inputs is a "kinded" collection, which is a heterogenous collection where

tests/test_input.py

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,6 @@ def test_cannot_create_with_restrictToHost_in_name(self):
6262
lambda: self.service.inputs.create('tcp', 'boris:10000')
6363
)
6464

65-
def test_remove_host_restriction(self):
66-
if self.service.splunk_version < (5,):
67-
# We can't set restrictToHost before 5.0 due to a bug in splunkd.
68-
return
69-
input = self.service.inputs.create('tcp', str(self.base_port), restrictToHost='boris')
70-
input.update(restrictToHost='')
71-
input.refresh()
72-
self.check_entity(input)
73-
input.delete()
74-
7565
def test_create_tcp_ports_with_restrictToHost(self):
7666
for kind in ['tcp', 'splunktcp']: # Multiplexed UDP ports are not supported
7767
# Make sure we can create two restricted inputs on the same port
@@ -105,39 +95,14 @@ def test_unrestricted_to_restricted_collision(self):
10595
)
10696
unrestricted.delete()
10797

108-
def test_update_restrictToHost(self):
98+
def test_update_restrictToHost_fails(self):
10999
for kind in ['tcp', 'splunktcp']: # No UDP, since it's broken in Splunk
110100
boris = self.create_tcp_input(self.base_port, kind, restrictToHost='boris')
111101

112-
# No matter what version we're actually running against,
113-
# we can check that on Splunk < 5.0, we get an exception
114-
# from trying to update restrictToHost.
115-
with self.fake_splunk_version((4,3)):
116-
self.assertRaises(
117-
client.IllegalOperationException,
118-
lambda: boris.update(restrictToHost='hilda')
119-
)
120-
121-
# And now back to real tests...
122-
if self.service.splunk_version >= (5,):
123-
boris.update(restrictToHost='hilda')
124-
boris.refresh()
125-
self.assertEqual('hilda:' + str(self.base_port), boris.name)
126-
boris.refresh()
127-
self.check_entity(boris)
128-
boris.delete()
129-
130-
def test_update_nonrestrictToHost(self):
131-
for kind in ['tcp', 'splunktcp']: # No UDP since it's broken in Splunk
132-
input = self.create_tcp_input(self.base_port, kind, restrictToHost='boris')
133-
134-
try:
135-
input.update(host='meep')
136-
input.refresh()
137-
self.assertTrue(input.name.startswith('boris'))
138-
except:
139-
input.delete()
140-
raise
102+
self.assertRaises(
103+
client.IllegalOperationException,
104+
lambda: boris.update(restrictToHost='hilda')
105+
)
141106

142107
class TestRead(testlib.SDKTestCase):
143108
def test_read(self):

0 commit comments

Comments
 (0)