Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/new features from sc4snmp #26

Merged
merged 3 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 78 additions & 15 deletions backend/SC4SNMP_UI_backend/common/conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,31 @@ def ui2backend(self, document: dict, **kwargs):
class ProfileConversion(Conversion):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__backend2ui_conditional_operations = {
"lt": "less than",
"gt": "greater than",
"equal": "equal",
"in": "in"
}
self.__ui2backend_conditional_operations = {}
for key, value in self.__backend2ui_conditional_operations.items():
self.__ui2backend_conditional_operations[value] = key

self.__backend2ui_profile_types = {
"field": "smart"
}
self.__ui2backend_profile_types = {}
for key, value in self.__backend2ui_profile_types.items():
self.__ui2backend_profile_types[value] = key

def __string_value_to_numeric(self, value: str):
try:
if value.isnumeric():
return int(value)
elif value.replace(".", "").isnumeric():
return float(value)
except ValueError:
return value

def _backend2ui_map(self, document: dict, **kwargs):
profile_name = None
Expand All @@ -61,26 +86,48 @@ def _backend2ui_map(self, document: dict, **kwargs):
new_vb = {
"family": vb[0],
"category": vb[1] if len(vb) >= 2 else "",
"index": str(vb[2]) if len(vb) == 3 else "",
"index": '.'.join(vb[2:]) if len(vb) >= 3 else "",
}
var_binds.append(new_vb)

if "condition" in document[profile_name]:
backend_condition = document[profile_name]["condition"]
condition_type = backend_condition["type"]
field = backend_condition["field"] if condition_type == "field" else ""
condition_type = self.__backend2ui_profile_types[backend_condition["type"]]
omrozowicz-splunk marked this conversation as resolved.
Show resolved Hide resolved
field = backend_condition["field"] if backend_condition["type"] == "field" else ""
patterns = [{"pattern": p} for p in backend_condition["patterns"]] \
if condition_type == "field" else None
if backend_condition["type"] == "field" else []
conditions = {
"condition": condition_type,
"field": field,
"patterns": patterns
"patterns": patterns,
"conditions": []
}
elif "conditions" in document[profile_name]:
conditional = []
for back_condition in document[profile_name]["conditions"]:
field = back_condition["field"]
operation = self.__backend2ui_conditional_operations[back_condition["operation"]]
value = []
if operation == "in":
for v in back_condition["value"]:
value.append(str(v))
else:
value.append(str(back_condition["value"]))
conditional.append(
{"field": field, "operation": operation, "value": value}
)
conditions = {
"condition": "conditional",
"field": "",
"patterns": [],
"conditions": conditional
}
else:
conditions = {
"condition": "None",
"condition": "standard",
"field": "",
"patterns": None
"patterns": [],
"conditions": []
}
result = {
"_id": str(document["_id"]),
Expand All @@ -92,16 +139,30 @@ def _backend2ui_map(self, document: dict, **kwargs):
return result

def _ui2backend_map(self, document: dict, **kwargs):
if document['conditions']['condition'] == "field":
conditions = {
conditions = None
condition = None
if document['conditions']['condition'] == "smart":
condition = {
'type': 'field',
'field': document['conditions']['field'],
'patterns': [el['pattern'] for el in document['conditions']['patterns']]
}
elif document['conditions']['condition'] == "None":
conditions = None
else:
conditions = {
elif document['conditions']['condition'] == "conditional":
conditions = []
for ui_condition in document['conditions']['conditions']:
field = ui_condition["field"]
operation = self.__ui2backend_conditional_operations[ui_condition["operation"]]
if operation == "in":
value = []
for v in ui_condition["value"]:
value.append(self.__string_value_to_numeric(v))
else:
value = self.__string_value_to_numeric(ui_condition["value"][0])
conditions.append(
{"field": field, "operation": operation, "value": value}
)
elif document['conditions']['condition'] != "standard":
condition = {
'type': document['conditions']['condition']
}
var_binds = []
Expand All @@ -110,7 +171,7 @@ def _ui2backend_map(self, document: dict, **kwargs):
if len(var_b['category']) > 0:
single_var_bind.append(var_b['category'])
if len(var_b['index']) > 0:
single_var_bind.append(int(var_b['index']))
single_var_bind += var_b['index'].split(".")
var_binds.append(single_var_bind)

item = {
Expand All @@ -119,8 +180,10 @@ def _ui2backend_map(self, document: dict, **kwargs):
'varBinds': var_binds
}
}
if condition is not None:
item[document['profileName']].update({'condition': condition})
if conditions is not None:
item[document['profileName']].update({'condition': conditions})
item[document['profileName']].update({'conditions': conditions})
return item


Expand Down
4 changes: 2 additions & 2 deletions backend/SC4SNMP_UI_backend/common/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ def add_group_to_inventory(self, group_name: str, group_port: str, group_object=
deleted_inventory_record = list(self._mongo_inventory.find({'address': group_name, "delete": True}))
group = list(self._mongo_groups.find({group_name: {"$exists": 1}}))
if len(group) == 0:
group_added = False
message = f"There is no group {group_name} configured. Record was not added."
group_added = True
message = f"Group {group_name} doesn't exist in the configuration. Treating {group_name} as a hostname."
elif len(existing_inventory_record) > 0:
group_added = False
message = f"Group {group_name} has already been added to the inventory. Record was not added."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ function Header(){
const handleRequestOpenProfile = () => {
ProfCtx.setProfileName("");
ProfCtx.setFrequency(1);
ProfCtx.setVarBinds(null);
ProfCtx.setConditions(null);
ProfCtx.setVarBinds([]);
ProfCtx.setCondition("None");
ProfCtx.setConditionField("");
ProfCtx.setConditionPatterns([]);
ProfCtx.setConditional([]);
ProfCtx.setAddOpen(true);
ProfCtx.setIsEdit(false);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import Number from '@splunk/react-ui/Number';
import Text from '@splunk/react-ui/Text';
import { createDOMID } from '@splunk/ui-utils/id';
import P from '@splunk/react-ui/Paragraph';
import VarbindsCreator from "./VarbindsCreator";
import Conditions from "./Conditions";
import VarBinds from "./VarBinds";
import Condition from "./Condition";
import axios from "axios";
import ProfileContext from "../../store/profile-contxt";
import validateProfiles from "../validation/ValidateProfiles";
Expand All @@ -21,16 +21,7 @@ function AddProfileModal(props) {
const ProfCtx = useContext(ProfileContext);
const ValCtx = useContext(ProfilesValidationContxt);
const ErrCtx = useContext(ErrorsModalContext);
const [newSubmitPatterns, setNewSubmitPatterns] = useState(false);
const [newSubmitVarBinds, setNewSubmitVarBinds] = useState(false);

const newSubmitPatternsHandler = () =>{
setNewSubmitPatterns(!newSubmitPatterns);
};

const newSubmitVarBindsHandler = () =>{
setNewSubmitVarBinds(!newSubmitVarBinds);
};
const [newSubmit, setNewSubmit] = useState(false);


const handleProfileName = useCallback((e, { value: val }) => {
Expand All @@ -41,14 +32,6 @@ function AddProfileModal(props) {
ProfCtx.setFrequency(val);
}, []);

const handleVarBinds = (value) => {
ProfCtx.setVarBinds(value);
}

const handleConditions = (value) => {
ProfCtx.setConditions(value);
}

const postProfile = (profileObj) => {
axios.post(`http://${backendHost}/profiles/add`, profileObj)
.then((response) => {
Expand Down Expand Up @@ -91,11 +74,16 @@ function AddProfileModal(props) {
const handleApply = useCallback(
(e) => {

let profileObj = {
const profileObj = {
profileName: ProfCtx.profileName,
frequency: ProfCtx.frequency,
varBinds: ProfCtx.varBinds,
conditions: ProfCtx.conditions
conditions: {
condition: ProfCtx.condition,
field: ProfCtx.conditionField,
patterns: ProfCtx.conditionPatterns,
conditions: ProfCtx.conditional
}
};

const validation = validateProfiles(profileObj);
Expand All @@ -112,16 +100,16 @@ function AddProfileModal(props) {
ProfCtx.addModalToggle?.current?.focus();
}else{
// form is invalid
setNewSubmitPatterns(prevNewSubmitPatterns => {return !prevNewSubmitPatterns;});
setNewSubmitVarBinds(prevNewSubmitVarBinds => {return !prevNewSubmitVarBinds;});
setNewSubmit(prevNewSubmitPatterns => {return !prevNewSubmitPatterns;});
const errors = validation[1];
for (const property in errors) {
if (errors[property].length > 0 || Object.keys(errors[property]).length > 0){
ValCtx.setErrors(property, errors[property]);
const errorKeys = Object.keys(errors);
errorKeys.forEach((errorKey) => {
if (errors[errorKey].length > 0 || Object.keys(errors[errorKey]).length > 0){
ValCtx.setErrors(errorKey, errors[errorKey]);
}else {
ValCtx.resetErrors(property);
ValCtx.resetErrors(errorKey);
};
};
})
};

},
Expand Down Expand Up @@ -150,14 +138,15 @@ function AddProfileModal(props) {
</div>
</StyledControlGroup>

<Conditions onConditionsCreator={handleConditions} value={ProfCtx.conditions} errorField={ValCtx.conditionFieldErrors}
errorPatterns={ValCtx.conditionPatternsErrors} setErrorPatterns={ValCtx.setConditionPatternsErrors}
validationMessage={validationMessage} validationGroup={validationGroup} newSubmit={newSubmitPatterns}/>
<Condition newSubmit={newSubmit}/>

<StyledControlGroup label="VarBinds">
<VarbindsCreator onVarbindsCreator={handleVarBinds} value={ProfCtx.varBinds} error={ValCtx.varBindsErrors} setError={ValCtx.setVarBindsErrors}
validationMessage={validationMessage} validationGroup={validationGroup}
newSubmit={newSubmitVarBinds}/>
<div style={validationGroup}>
<VarBinds newSubmit={newSubmit}/>
{((ValCtx.varBindsExistErrors) ?
<P key={createDOMID()} style={validationMessage}>{ValCtx.varBindsExistErrors}</P>
: null)}
</div>
</StyledControlGroup>

</StyledModalBody>
Expand Down
74 changes: 74 additions & 0 deletions frontend/packages/manager/src/components/profiles/Condition.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, {useState, useRef, useCallback, useContext, useEffect} from 'react';
import { createDOMID } from '@splunk/ui-utils/id';
import ProfileContext from "../../store/profile-contxt";
import {StyledControlGroup} from "../../styles/inventory/InventoryStyle";
import Select from "@splunk/react-ui/Select";
import Text from "@splunk/react-ui/Text";
import P from "@splunk/react-ui/Paragraph";
import FieldPatterns from "./FieldPatterns";
import {validationGroup, validationMessage} from "../../styles/ValidationStyles";
import ProfilesValidationContxt from "../../store/profiles-validation-contxt";
import Conditional from "./Conditional";

function Condition(props){
const ProfCtx = useContext(ProfileContext);
const ValCtx = useContext(ProfilesValidationContxt);

const handleFieldChange = useCallback((e, { value: val }) => {
ProfCtx.setConditionField(val);
}, []);

const handleChange = useCallback((e, { value: val }) => {
ProfCtx.setCondition(val);
}, []);

return(
<div>
<StyledControlGroup label="Profile type"
labelFor="customized-select-after">
<Select value={ProfCtx.condition} onChange={handleChange} filter>
<Select.Option label="standard" value="standard"/>
<Select.Option label="base" value="base"/>
<Select.Option label="smart" value="smart"/>
<Select.Option label="walk" value="walk"/>
<Select.Option label="conditional" value="conditional"/>
</Select>
</StyledControlGroup>
{
ProfCtx.condition === 'smart' ? (
<div>
<StyledControlGroup label="Field">
<div style={validationGroup}>
<Text value={ProfCtx.conditionField} onChange={handleFieldChange} error={((ValCtx.conditionFieldErrors) ? true : false)}/>
{((ValCtx.conditionFieldErrors) ? ValCtx.conditionFieldErrors.map((el) =>
<P key={createDOMID()} style={validationMessage}>{el}</P>) : <P/>)}
</div>
</StyledControlGroup>
<StyledControlGroup label="Patterns">
<div style={validationGroup}>
<FieldPatterns newSubmit={props.newSubmit}/>
{((ValCtx.patternsExistErrors) ?
<P key={createDOMID()} style={validationMessage}>{ValCtx.patternsExistErrors}</P>
: null)}
</div>
</StyledControlGroup>
</div>) : null
}

{
ProfCtx.condition === 'conditional' ? (
<StyledControlGroup label="Conditions">
<div style={validationGroup}>
<Conditional newSubmit={props.newSubmit}/>
{((ValCtx.conditionalExistErrors) ?
<P key={createDOMID()} style={validationMessage}>{ValCtx.conditionalExistErrors}</P>
: null)}
</div>
</StyledControlGroup>
) : null
}
</div>
)
}

export default Condition;
Loading