[PLUGIN] Using configuration data in plugins

Hi,

I developped a plugin which is using a configuration section embedding 2 parameters: graylog endpoint and service token.

i would like to retrieve those two values from a web page of my plugin.

However, I have no idea how to make it.

Does anyone know how communication between webpages and java classes works ?

Here is my code concerning the configuration part:

Settings.java

package com.example.graylog;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;

import javax.annotation.Nullable;

import static org.graylog2.plugin.streams.Stream.DEFAULT_STREAM_ID;

/**
 * This is the general configuration of the plugin (see System/Configurations)
 * It is probably linked to the IHM, just by the configuration in the web index.jsx.
 */
@JsonAutoDetect
@AutoValue
public abstract class Settings {
    
    @JsonProperty("graylog_endpoint")
    public abstract String accessGraylogEndpoint();

    @JsonProperty("example_service_token")
    public abstract String accessexampleServiceToken();

    @JsonCreator
    public static Settings create(
            @JsonProperty("graylog_endpoint") String graylog_endpoint,
            @JsonProperty("example_service_token") String example_service_token){
        return builder()
                .accessGraylogEndpoint(graylog_endpoint)
                .accessexampleServiceToken(example_service_token)
                .build();
    }

    public static Settings createDefault() {
        return builder()
                .accessGraylogEndpoint("https://127.0.0.1:9000")
                .accessexampleServiceToken("XXX")
                .build();
    }

    public static Builder builder() {
        return new AutoValue_Settings.Builder();
    }


    public abstract Builder toBuilder();

    @AutoValue.Builder
    public abstract static class Builder {

        public abstract Builder accessGraylogEndpoint(String accessGraylogEndpoint);
        public abstract Builder accessexampleServiceToken(String accessexampleServiceToken);

        public abstract Settings build();
    }
}

settings.jsx

import React, { useState } from 'react';
import { useStore } from 'stores/connect';
import { StreamsStore } from 'views/stores/StreamsStore';
import { defaultCompare } from 'logic/DefaultCompare'
// TODO remove the ref and use property show when migrating to graylog >= 5.1
import { BootstrapModalForm, Modal, Button, Input } from 'components/bootstrap';
import IfPermitted from 'components/common/IfPermitted';
import Select from 'components/common/Select';
import Spinner from 'components/common/Spinner';

const DEFAULT_CONFIG = {
    graylog_endpoint: 'https://127.0.0.1:9000',
    Example_service_token: 'XXX',
};

const _formatOption = (key, value) => {
    return { value: value, label: key };
};

const _displayOptionalConfigurationValue = (value) => {
    if (!value) {
        return '[not set]';
    }
    return value;
};

const Settings = ({ config = DEFAULT_CONFIG, updateConfig }) => {
    const [nextConfiguration, setNextConfiguration] = useState(config);
    const [showModal, setShowModal] = useState(false);
    const { streams: streamList = [] } = useStore(StreamsStore);

    const _openModal = () => {
        setShowModal(true);
    };

    const _closeModal = () => {
        setShowModal(false);
    };

    /* TODO is this necessary?
        useEffect(() => {
            setNextConfiguration({ ...config });
        }, [config]);
    */

    const _saveConfiguration = () => {
        updateConfig(nextConfiguration).then(() => {
            _closeModal();
        })
    };

    const _resetConfiguration = () => {
        setNextConfiguration(config);
        _closeModal()
    };

    const _updateConfigurationField = (field, value) => {
        const newConfiguration = {...nextConfiguration};
        newConfiguration[field] = value;
        setNextConfiguration(newConfiguration);
    };

    const _onUpdate = (field) => {
        return e => {
            _updateConfigurationField(field, e.target.value);
        };
    };

    if (!streamList) {
        return <Spinner />;
    }

    const formattedStreams = streamList
        .map(stream => _formatOption(stream.title, stream.id))
        .sort((s1, s2) => defaultCompare(s1.label.toLowerCase(), s2.label.toLowerCase()));

    const saveButtonClass = "Button-sc-e4msts-0 eNbEkd btn btn-success";

    return (
        <div>
            <h3>Example Configuration</h3>

            <p>
                Example needs two parameters:
                Graylog endpoint : The SIEM endpoint for API requesting
                Example service token: A graylog service token for API authentication
            </p>
            <dl className="deflist">
                <dt>Graylog endpoint: </dt>
                <dd>
                    {_displayOptionalConfigurationValue(config.graylog_endpoint)}
                </dd>
            </dl>
            <dl className="deflist">
                <dt>Example service token: </dt>
                <dd>
                    {_displayOptionalConfigurationValue(config.Example_service_token)}
                </dd>
            </dl>

            <IfPermitted permissions="clusterconfigentry:edit">
                <Button bsStyle="info" bsSize="xs" onClick={_openModal}>
                    Edit configuration
                </Button>
            </IfPermitted>

            <Modal show={showModal} onHide={_closeModal}>
                <Modal.Header closeButton>
                    <Modal.Title>Update Example Configuration</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <fieldset>
                        <Input
                            id="graylog_endpoint"
                            type="text"
                            label="Graylog endpoint"
                            name="graylog_endpoint"
                            help="Graylog endpoint for API requesting."
                            value={nextConfiguration.graylog_endpoint}
                            onChange={_onUpdate('graylog_endpoint')}
                        />
                        <Input
                            id="Example_service_token"
                            type="text"
                            label="Example service token"
                            name="Example_service_token"
                            help="Example service token for API authentication."
                            value={nextConfiguration.Example_service_token}
                            onChange={_onUpdate('Example_service_token')}
                        />
                    </fieldset>
                </Modal.Body>
                <Modal.Footer>
                    <Button  onClick={_resetConfiguration}>
                        Close
                    </Button>
                    <Button className={saveButtonClass} onClick={_saveConfiguration}>
                        Save Changes
                    </Button>
                </Modal.Footer>
            </Modal>

        </div>
    );
};

export default Settings;

index.jsx

import packageJson from '../../package.json';
import { PluginManifest, PluginStore } from 'graylog-web-plugin/plugin';
import SamplePage from 'pages/SamplePage';
import Settings from "./components/settings";

const metadata = {
    name: packageJson.name
}

PluginStore.register(new PluginManifest(metadata, {
  /* 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. */

  systemConfigurations: [
    {
      component: Settings,
      configType: 'com.example.graylog.Settings',
    },
  ],

  routes: [
        {path: '/example', component: SamplePage},

    ],

    navigation: [
        {
            path: '/example', description: 'Example'
        },
    ],
}));

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.