First commit

This commit is contained in:
yo
2024-02-20 19:50:45 +01:00
commit c7af8bd960
15 changed files with 767 additions and 0 deletions

8
src/deb/control/control Normal file
View File

@ -0,0 +1,8 @@
Package: [[name]]
Version: [[version]]
Architecture: all
Maintainer: johan <johan@nosd.in>
Section: web
Priority: optional
Depends: graylog-server | graylog-radio
Description: [[description]]

View File

@ -0,0 +1,8 @@
package in.nosd.graylog;
/**
* This is the plugin. Your class should implement one of the existing plugin
* interfaces. (i.e. AlarmCallback, MessageInput, MessageOutput)
*/
public class GetListValueByRegex {
}

View File

@ -0,0 +1,127 @@
package in.nosd.graylog;
import org.graylog.plugins.pipelineprocessor.EvaluationContext;
import org.graylog.plugins.pipelineprocessor.ast.expressions.Expression;
import org.graylog.plugins.pipelineprocessor.ast.functions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.regex.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.fasterxml.jackson.databind.node.ValueNode;
import com.google.common.collect.ImmutableList;
import com.google.common.reflect.TypeToken;
import static org.graylog.plugins.pipelineprocessor.ast.functions.ParameterDescriptor.object;
import static org.graylog.plugins.pipelineprocessor.ast.functions.ParameterDescriptor.type;
import static org.graylog.plugins.pipelineprocessor.ast.functions.ParameterDescriptor.string;
public class GetListValueByRegexFunction extends AbstractFunction<List<String>> {
Logger LOG = LoggerFactory.getLogger(Function.class);
public static final String NAME = "get_list_val_by_regex";
private static final String LIST_ARG = "list";
private static final String PATTERN_ARG = "pattern";
@SuppressWarnings("unchecked")
private static final Class<List<String>> LIST_RETURN_TYPE = (Class<List<String>>) new TypeToken<List<String>>() {
}.getRawType();
private final ParameterDescriptor<Object, List<String>> listParam;
private final ParameterDescriptor<String, String> patternParam;
public GetListValueByRegexFunction() {
listParam = ParameterDescriptor.object(LIST_ARG, LIST_RETURN_TYPE)
.transform(this::transformToList)
.description("The list of string to search regex in.")
.build();
patternParam = ParameterDescriptor.string(PATTERN_ARG)
.description("The regex pattern to search in string list. Special characters needs to be double escaped.")
.build();
}
private List<String> transformToList(Object value) {
if (value instanceof Collection<?>) {
return ((Collection<?>) value).stream()
.map(GetListValueByRegexFunction::convertValue)
// Non-text JSON nodes will return null, and type conversions are intentionally not done,
// since only string inputs are supported.
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
if (value == null) {
LOG.debug("get_list_val_by_regex: parameter \"list\" is null");
return Collections.singletonList("");
}
return Collections.singletonList(value.toString());
}
private static String convertValue(Object o) {
if (o instanceof ValueNode node) {
return node.textValue();
}
return o.toString();
}
@Override
public Object preComputeConstantArgument(FunctionArgs functionArgs, String s, Expression expression) {
return expression.evaluateUnsafe(EvaluationContext.emptyContext());
}
@Override
public List<String> evaluate(FunctionArgs functionArgs, EvaluationContext evaluationContext) {
final List<String> list = listParam.required(functionArgs, evaluationContext);
final String regexPattern = patternParam.required(functionArgs, evaluationContext);
List<String> resultList = new ArrayList<String>();
List<String> blankList = new ArrayList<String>();
Pattern pattern;
if (!(list instanceof List)) {
LOG.error("get_list_val_by_regex: parameter \"list\" is of wrong type");
return blankList;
}
try {
pattern = Pattern.compile(regexPattern);
}
catch(PatternSyntaxException e) {
LOG.error("get_list_val_by_regex: invalid pattern {}", regexPattern);
return blankList;
}
Matcher match;
for (String s : list) {
LOG.debug("get_list_val_by_regex: in loop, processing '{}'", s);
match = pattern.matcher(s);
if (match.matches()) {
LOG.debug("get_list_val_by_regex match: {}", s);
resultList.add(s);
}
}
if (resultList.size() > 0) {
return resultList;
}
LOG.debug("get_list_val_by_regex: No results");
return blankList;
}
@Override
public FunctionDescriptor<List<String>> descriptor() {
return FunctionDescriptor.<List<String>>builder()
.name(NAME)
.description("Search values matching a regex in a string list, and return matching strings in form of a list. Match should be complete (no partial).")
.params(ImmutableList.of(listParam, patternParam))
.returnType(LIST_RETURN_TYPE)
.build();
}
}

View File

@ -0,0 +1,57 @@
package in.nosd.graylog;
import org.graylog2.plugin.PluginMetaData;
import org.graylog2.plugin.ServerStatus;
import org.graylog2.plugin.Version;
import java.net.URI;
import java.util.Collections;
import java.util.Set;
/**
* Implement the PluginMetaData interface here.
*/
public class GetListValueByRegexMetaData implements PluginMetaData {
private static final String PLUGIN_PROPERTIES = "in.nosd.graylog.graylog-plugin-getlistvaluebyregex/graylog-plugin.properties";
@Override
public String getUniqueId() {
return "in.nosd.graylog.GetListValueByRegexPlugin";
}
@Override
public String getName() {
return "GetListValueByRegex";
}
@Override
public String getAuthor() {
return "johan <johan@nosd.in>";
}
@Override
public URI getURL() {
return URI.create("https://github.com/git.nosd.in/yo/graylog-plugin-getlistvaluebyregex.git");
}
@Override
public Version getVersion() {
return Version.fromPluginProperties(getClass(), PLUGIN_PROPERTIES, "version", Version.from(0, 0, 0, "unknown"));
}
@Override
public String getDescription() {
// TODO Insert correct plugin description
return "Description of GetListValueByRegex plugin";
}
@Override
public Version getRequiredVersion() {
return Version.fromPluginProperties(getClass(), PLUGIN_PROPERTIES, "graylog.version", Version.from(0, 0, 0, "unknown"));
}
@Override
public Set<ServerStatus.Capability> getRequiredCapabilities() {
return Collections.emptySet();
}
}

View File

@ -0,0 +1,60 @@
package in.nosd.graylog;
import com.google.inject.Binder;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.MapBinder;
import org.graylog.plugins.pipelineprocessor.ast.functions.Function;
import org.graylog2.plugin.PluginConfigBean;
import org.graylog2.plugin.PluginModule;
import java.util.Collections;
import java.util.Set;
/**
* Extend the PluginModule abstract class here to add you plugin to the system.
*/
public class GetListValueByRegexModule extends PluginModule {
/**
* Returns all configuration beans required by this plugin.
*
* Implementing this method is optional. The default method returns an empty {@link Set}.
*/
@Override
public Set<? extends PluginConfigBean> getConfigBeans() {
return Collections.emptySet();
}
@Override
protected void configure() {
/*
* Register your plugin types here.
*
* Examples:
*
* addMessageInput(Class<? extends MessageInput>);
* addMessageFilter(Class<? extends MessageFilter>);
* addMessageOutput(Class<? extends MessageOutput>);
* addPeriodical(Class<? extends Periodical>);
* addAlarmCallback(Class<? extends AlarmCallback>);
* addInitializer(Class<? extends Service>);
* addRestResource(Class<? extends PluginRestResource>);
*
*
* Add all configuration beans returned by getConfigBeans():
*
* addConfigBeans();
*/
addMessageProcessorFunction(GetListValueByRegexFunction.NAME, GetListValueByRegexFunction.class);
}
private void addMessageProcessorFunction(String name, Class<? extends Function<?>> functionClass) {
addMessageProcessorFunction(binder(), name, functionClass);
}
private MapBinder<String, Function<?>> processorFunctionBinder(Binder binder) {
return MapBinder.newMapBinder(binder, TypeLiteral.get(String.class), new TypeLiteral<Function<?>>() {});
}
private void addMessageProcessorFunction(Binder binder, String name, Class<? extends Function<?>> functionClass) {
processorFunctionBinder(binder).addBinding(name).to(functionClass);
}
}

View File

@ -0,0 +1,23 @@
package in.nosd.graylog;
import org.graylog2.plugin.Plugin;
import org.graylog2.plugin.PluginMetaData;
import org.graylog2.plugin.PluginModule;
import java.util.Collection;
import java.util.Collections;
/**
* Implement the Plugin interface here.
*/
public class GetListValueByRegexPlugin implements Plugin {
@Override
public PluginMetaData metadata() {
return new GetListValueByRegexMetaData();
}
@Override
public Collection<PluginModule> modules () {
return Collections.<PluginModule>singletonList(new GetListValueByRegexModule());
}
}

View File

@ -0,0 +1 @@
in.nosd.graylog.GetListValueByRegexPlugin

View File

@ -0,0 +1,12 @@
# The plugin version
version=${project.version}
# The required Graylog server version
graylog.version=${graylog.version}
# When set to true (the default) the plugin gets a separate class loader
# when loading the plugin. When set to false, the plugin shares a class loader
# with other plugins that have isolated=false.
#
# Do not disable this unless this plugin depends on another plugin!
isolated=true

26
src/web/index.jsx Normal file
View File

@ -0,0 +1,26 @@
import 'webpack-entry';
import { PluginManifest, PluginStore } from 'graylog-web-plugin/plugin';
import packageJson from '../../package.json';
const manifest = new PluginManifest(packageJson, {
/* This is the place where you define which entities you are providing to the web interface.
Right now you can add routes and navigation elements to it.
Examples: */
// Adding a route to /sample, rendering YourReactComponent when called:
// routes: [
// { path: '/sample', component: YourReactComponent, permissions: 'inputs:create' },
// ],
// Adding an element to the top navigation pointing to /sample named "Sample":
// navigation: [
// { path: '/sample', description: 'Sample' },
// ]
});
PluginStore.register(manifest);