Skip to content

Commit 1ba210d

Browse files
author
Shakeel Mohamed
committed
Added Argument & Scheme classes, testdata and unit test.
1 parent 38379f5 commit 1ba210d

File tree

7 files changed

+289
-0
lines changed

7 files changed

+289
-0
lines changed

splunklib/modularinput/argument.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright 2011-2013 Splunk, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
try:
16+
import xml.etree.ElementTree as ET
17+
except ImportError:
18+
import xml.etree.cElementTree as ET
19+
20+
#TODO: extend docs
21+
22+
class Argument(object):
23+
"""Class representing an argument to a modular input kind."""
24+
def __init__(self, name):
25+
"""
26+
:param name: string identifier for this argument in Splunk
27+
"""
28+
self.name = name
29+
self.description = None
30+
self.validation = None
31+
32+
# Constant values, do not change
33+
self.dataTypeBoolean = "BOOLEAN"
34+
self.dataTypeNumber = "NUMBER"
35+
self.dataTypeString = "STRING"
36+
37+
self.dataType = self.dataTypeString
38+
39+
self.requiredOnEdit = False
40+
self.requiredOnCreate = False
41+
42+
def addToDocument(self, parent):
43+
"""Adds an <arg> SubElement to the Parent Element, typically <args>
44+
45+
:param parent: an ET.Element to be the parent of a new <arg> SubElement
46+
:return: an ET.Element object representing this argument #TODO: might not need to return here..
47+
"""
48+
arg = ET.SubElement(parent, "arg")
49+
arg.set("name", self.name)
50+
51+
if self.description:
52+
description = ET.SubElement(arg, "description")
53+
description.text = self.description
54+
55+
if self.validation:
56+
validation = ET.SubElement(arg, "validation")
57+
validation.text = self.validation
58+
59+
data_type = ET.SubElement(arg, "data_type")
60+
data_type.text = self.dataType.lower()
61+
62+
required_on_edit = ET.SubElement(arg, "required_on_edit")
63+
required_on_edit.text = str(self.requiredOnEdit).lower()
64+
65+
required_on_create = ET.SubElement(arg, "required_on_create")
66+
required_on_create.text = str(self.requiredOnCreate).lower()
67+
68+
return arg

splunklib/modularinput/scheme.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Copyright 2011-2013 Splunk, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
from splunklib.modularinput.argument import Argument
16+
17+
try:
18+
import xml.etree.cElementTree as ET
19+
except ImportError:
20+
import xml.etree.ElementTree as ET
21+
22+
#TODO: extend docs
23+
24+
class Scheme(object):
25+
"""Class representing the metadata for a modular input kind."""
26+
def __init__(self, title):
27+
"""
28+
:param title: string identifier for this Scheme in Splunk
29+
"""
30+
self.title = title
31+
self.description = None
32+
self.useExternalValidation = True
33+
self.useSingleInstance = False
34+
35+
# Constant values, do not change
36+
self.streamingModeSimple = "SIMPLE"
37+
self.streamingModeXML = "XML"
38+
39+
self.streamingMode = self.streamingModeXML
40+
41+
#List of Argument objects
42+
self.arguments = []
43+
44+
def addArgument(self, arg):
45+
"""Add the provided argument, arg, to self.arguments
46+
47+
:param arg: an Argument object to add to self.arguments
48+
"""
49+
self.arguments.append(arg)
50+
51+
def toXML(self):
52+
"""Creates an ET.Element representing this scheme, then returns it
53+
54+
:return root, an ET.Element representing this scheme
55+
"""
56+
root = ET.Element("scheme")
57+
58+
title = ET.SubElement(root, "title")
59+
title.text = self.title
60+
61+
if self.description:
62+
description = ET.SubElement(root, "description")
63+
description.text = self.description
64+
65+
use_external_validation = ET.SubElement(root, "use_external_validation")
66+
use_external_validation.text = str(self.useExternalValidation).lower()
67+
68+
use_single_instance = ET.SubElement(root, "use_single_instance")
69+
use_single_instance.text = str(self.useSingleInstance).lower()
70+
71+
streaming_mode = ET.SubElement(root, "streaming_mode")
72+
streaming_mode.text = self.streamingMode.lower()
73+
74+
endpoint = ET.SubElement(root, "endpoint")
75+
76+
args = ET.SubElement(endpoint, "args")
77+
78+
for arg in self.arguments:
79+
arg.addToDocument(args)
80+
81+
return root
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<arg name="some_name">
2+
<data_type>string</data_type>
3+
<required_on_edit>false</required_on_edit>
4+
<required_on_create>false</required_on_create>
5+
</arg>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<arg name="some_name">
2+
<description>쎼 and 쎶 and &lt;&amp;&gt; für</description>
3+
<validation>is_pos_int('some_name')</validation>
4+
<data_type>boolean</data_type>
5+
<required_on_edit>true</required_on_edit>
6+
<required_on_create>true</required_on_create>
7+
</arg>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<scheme>
3+
<title>abcd</title>
4+
<use_external_validation>true</use_external_validation>
5+
<use_single_instance>false</use_single_instance>
6+
<streaming_mode>xml</streaming_mode>
7+
<endpoint>
8+
<args>
9+
</args>
10+
</endpoint>
11+
</scheme>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<scheme>
3+
<title>abcd</title>
4+
<description>쎼 and 쎶 and &lt;&amp;&gt; für</description>
5+
<use_external_validation>false</use_external_validation>
6+
<use_single_instance>true</use_single_instance>
7+
<streaming_mode>simple</streaming_mode>
8+
<endpoint>
9+
<args>
10+
<arg name="arg1">
11+
<data_type>string</data_type>
12+
<required_on_edit>false</required_on_edit>
13+
<required_on_create>false</required_on_create>
14+
</arg>
15+
<arg name="arg2">
16+
<description>쎼 and 쎶 and &lt;&amp;&gt; für</description>
17+
<validation>is_pos_int('some_name')</validation>
18+
<data_type>number</data_type>
19+
<required_on_edit>true</required_on_edit>
20+
<required_on_create>true</required_on_create>
21+
</arg>
22+
</args>
23+
</endpoint>
24+
</scheme>

tests/modularinput/scheme_test.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2011-2013 Splunk, Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
5+
# not use this file except in compliance with the License. You may obtain
6+
# a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
# License for the specific language governing permissions and limitations
14+
# under the License.
15+
16+
from splunklib.modularinput.modularinput_testlib import unittest, xml_compare
17+
from splunklib.modularinput.scheme import Scheme
18+
from splunklib.modularinput.argument import Argument
19+
20+
try:
21+
import xml.etree.cElementTree as ET
22+
except ImportError:
23+
import xml.etree.ElementTree as ET
24+
25+
class SchemeTest(unittest.TestCase):
26+
def test_generate_xml_from_scheme_with_default_values(self):
27+
"""Checks the Scheme generated by creating a Scheme object and setting no fields on it.
28+
This test checks for sane defaults in the class."""
29+
30+
scheme = Scheme("abcd")
31+
32+
constructed = scheme.toXML()
33+
expected = ET.parse(open("data/scheme_with_defaults.xml")).getroot()
34+
35+
self.assertTrue(xml_compare(expected, constructed))
36+
37+
def test_generate_xml_from_scheme(self):
38+
"""Checks that the XML generated by a Scheme object with all its fields set and
39+
some arguments added matches what we expect."""
40+
41+
scheme = Scheme("abcd")
42+
scheme.description = u"쎼 and 쎶 and <&> für"
43+
scheme.streamingMode = scheme.streamingModeSimple
44+
scheme.useExternalValidation = "false"
45+
scheme.useSingleInstance = "true"
46+
47+
arg1 = Argument("arg1")
48+
scheme.addArgument(arg1)
49+
50+
arg2 = Argument("arg2")
51+
arg2.description = u"쎼 and 쎶 and <&> für"
52+
arg2.dataType = arg2.dataTypeNumber
53+
arg2.requiredOnCreate = "true"
54+
arg2.requiredOnEdit = "true"
55+
arg2.validation = "is_pos_int('some_name')"
56+
scheme.addArgument(arg2)
57+
58+
constructed = scheme.toXML()
59+
expected = ET.parse(open("data/scheme_without_defaults.xml")).getroot()
60+
61+
self.assertTrue(xml_compare(expected, constructed))
62+
63+
def test_generate_xml_from_argument_with_default_values(self):
64+
"""Checks that the XML produced from an Argument class that is initialized but has no additional manipulations
65+
made to it is what we expect. This is mostly a check of the default values."""
66+
67+
argument = Argument("some_name")
68+
69+
root = ET.Element("")
70+
constructed = argument.addToDocument(root)
71+
72+
expected = ET.parse(open("data/argument_with_defaults.xml")).getroot()
73+
74+
self.assertTrue(xml_compare(expected, constructed))
75+
76+
def test_generate_xml_from_argument(self):
77+
"""Checks that the XML generated by an Argument class with all its possible values set is what we expect."""
78+
argument = Argument("some_name")
79+
argument.description = u"쎼 and 쎶 and <&> für"
80+
argument.dataType = argument.dataTypeBoolean
81+
argument.validation = "is_pos_int('some_name')"
82+
argument.requiredOnEdit = "true"
83+
argument.requiredOnCreate = "true"
84+
85+
root = ET.Element("")
86+
constructed = argument.addToDocument(root)
87+
88+
expected = ET.parse(open("data/argument_without_defaults.xml")).getroot()
89+
90+
self.assertTrue(xml_compare(expected, constructed))
91+
92+
if __name__ == "__main__":
93+
unittest.main()

0 commit comments

Comments
 (0)