Skip to content

Commit

Permalink
VersionBumpValidator - 16837 - Fixed issue where validator failed if …
Browse files Browse the repository at this point in the history
…plugin contained no actions or triggers (#187)
  • Loading branch information
igorski-r7 authored May 10, 2024
1 parent 1e683b3 commit beba72e
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ be on your way to contributing!

## Changelog

* 2.47.19 - `VersionBumpValidator` - Fixed issue where validator failed if plugin contained no actions or triggers
* 2.47.18 - `HelpInputOutputValidator` | `SpecPropertiesValidator` - Update to enable `placeholder` and `tooltip` validation | `RuntimeValidator` - Added SDK version validation
* 2.47.17 - `SpecPropertiesValidator` - Added new excludeProduct field validator
* 2.47.16 - `HelpInputOutputValidator` - Update error message from `icon-plugin` to `insight-plugin` | `DockerValidator` - Print full error message and change instances of `icon-plugin` to `insight-plugin`
Expand Down
2 changes: 1 addition & 1 deletion icon_validator/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "2.47.18"
VERSION = "2.47.19"
19 changes: 10 additions & 9 deletions icon_validator/rules/plugin_validators/version_bump_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,28 +192,29 @@ def validate_no_input_removed(self, remote: dict, local: dict):

def validate_no_action_removed(self, remote: dict, local: dict):
# input: complete spec dictionary
for action in remote[SpecConstants.ACTIONS]:
for action in remote.get(SpecConstants.ACTIONS, []):
if action not in local[SpecConstants.ACTIONS]:
raise ValidationException(f"Action {action} has been removed from spec without major version increment."
f"{self.MAJOR_INSTRUCTIONS_STRING}")

def validate_no_trigger_removed(self, remote: dict, local: dict):
# input: complete spec dictionary
for trigger in remote[SpecConstants.TRIGGERS]:
for trigger in remote.get(SpecConstants.TRIGGERS, []):
if trigger not in local[SpecConstants.TRIGGERS]:
raise ValidationException(f"Trigger {trigger} has been removed from {RepoConstants.PLUGIN_SPEC} without"
f" a major version increment.{self.MAJOR_INSTRUCTIONS_STRING}")

def validate_actions(self, remote: dict, local: dict):
# input: complete spec dictionary
self.validate_no_action_removed(remote, local)
for action_key, remote_action_dict in remote[SpecConstants.ACTIONS].items():
local_dict = local[SpecConstants.ACTIONS][action_key]
if local_dict.get(SpecConstants.TITLE) != remote_action_dict.get(SpecConstants.TITLE):
raise ValidationException(f"Action {action_key} title has changed without a major version increment."
f"{self.MAJOR_INSTRUCTIONS_STRING}")
if SpecConstants.ACTIONS in remote and SpecConstants.ACTIONS in local:
self.validate_no_action_removed(remote, local)
for action_key, remote_action_dict in remote[SpecConstants.ACTIONS].items():
local_dict = local[SpecConstants.ACTIONS][action_key]
if local_dict.get(SpecConstants.TITLE) != remote_action_dict.get(SpecConstants.TITLE):
raise ValidationException(f"Action {action_key} title has changed without a major version increment."
f"{self.MAJOR_INSTRUCTIONS_STRING}")

self.validate_inner_fields(remote_action_dict, local_dict)
self.validate_inner_fields(remote_action_dict, local_dict)

def validate_triggers(self, remote: dict, local: dict):
# input: complete spec dictionary
Expand Down
74 changes: 74 additions & 0 deletions unit_test/plugin_examples/good_plugin_no_actions/plugin.spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
plugin_spec_version: v2
extension: plugin
products: [insightconnect]
name: rss
title: RSS
description: The RSS plugin allows you to monitor an RSS feed
version: 1.0.6
connection_version: 1
vendor: rapid7
support: community
support_versions: ["2024-04-25"]
status: []
sdk:
type: slim
version: 5.4.7
user: nobody
key_features:
- Monitor an RSS feed
requirements:
- The URL for the feed you want to monitor
links:
- "[Feedparser](https://github.com/kurtmckee/feedparser)"
references:
- "[Feedparser](https://github.com/kurtmckee/feedparser)"
- "[Input Templating](https://docs.rapid7.com/insightconnect/format-strings-with-templates/)"
- "[Python Script plugin](https://docs.rapid7.com/insightconnect/python-2-or-3-script/)"
version_history:
- "1.0.6 - `Poll`: Fixed issue where trigger would return all entries on startup"
- "1.0.5 - Update links to Rapid7 documentation in `help.md` to use new [Rapid7 documentation URL](https://docs.rapid7.com/insightconnect/)"
- "1.0.4 - Change Frequency input description in Poll Feed trigger | Add example inputs"
- "1.0.3 - New spec and help.md format for the Extension Library"
- "1.0.2 - Fixed issue where Poll Feed was logging unnecessary information"
- "1.0.1 - Support web server mode"
- "1.0.0 - Update to v2 Python plugin architecture | Add granular object output"
- "0.1.1 - SSL bug fix in SDK"
- "0.1.0 - Initial plugin"
resources:
source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/rss
license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE
tags:
- rss
- atom
- feed
hub_tags:
use_cases: [data_utility, threat_detection_and_response, alerting_and_notifications]
keywords: [rss, atom, feeds]
features: []
language: python
connection:
url:
title: URL
description: Feed URL
type: string
required: true
example: https://example.com/rss/current
triggers:
poll:
title: Poll Feed
description: Poll feed for latest event
input:
frequency:
title: Frequency
description: How frequently (in seconds) to poll for new entries
type: integer
required: true
default: 15
example: 15
output:
results:
title: Results
description: RSS data
type: object
required: true
example: '{"title": "First item title", "title_detail": {"type": "text/plain", "language": null, "base": "", "value": "First item title"}, "links": [{"rel": "alternate", "type": "text/html", "href": "http://example.org/item/1"}, {"url": "", "rel": "enclosure"}], "link": "http://example.org/item/1", "summary": "Watch out for\n<span>\nnasty tricks</span>", "summary_detail": {"type": "text/html", "language": null, "base": "", "value": "Watch out for\n<span>\nnasty tricks</span>"}, "authors": [{"email": "[email protected]"}], "author": "[email protected]", "author_detail": {"email": "[email protected]"}, "tags": [{"term": "Miscellaneous", "scheme": null, "label": null}], "comments": "http://example.org/comments/1", "id": "http://example.org/guid/1", "guidislink": false, "published": "Thu, 05 Sep 2002 0:00:01 GMT"}'
9 changes: 9 additions & 0 deletions unit_test/test_validate_plugin/test_validate_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class TestPluginValidate(unittest.TestCase):
GOOD_PLUGIN_DIRECTORY = "plugin_examples/good_plugin"
GOOD_PLUGIN_WITH_TASK_DIRECTORY = "plugin_examples/good_plugin_with_task"
GOOD_PLUGIN_SDK_NOT_LATEST = "plugin_examples/good_plugin_with_task_sdk_not_latest"
GOOD_PLUGIN_NO_ACTIONS = "plugin_examples/good_plugin_no_actions"

@parameterized.expand([
('2023-12-24 12:56:15+05:00', '2023-12-24T12:56:15+05:00'),
Expand Down Expand Up @@ -791,6 +792,14 @@ def test_runtime_version_validator_failing(self) -> None:
result = validate(directory_to_test, file_to_test, False, True, [RuntimeValidator()])
self.assertEqual(result, 1)

def test_version_bump_validator_plugin_no_actions(self)->None:
directory_to_test = self.GOOD_PLUGIN_NO_ACTIONS
file_to_test = "plugin.spec.yaml"
remote_spec = MockRepoSpecResponse.mock_patch_remote_spec_major_version(directory_to_test)
VersionBumpValidator.get_remote_spec = MagicMock(return_value=remote_spec)
result = validate(directory_to_test, file_to_test, False, True, [VersionBumpValidator()])
self.assertEqual(result, 0)

@staticmethod
def replace_requirements(path, text):
f = open(path, 'w')
Expand Down

0 comments on commit beba72e

Please sign in to comment.