Skip to content

Commit

Permalink
fix: fix command argument parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
ziccardi committed Jul 14, 2023
1 parent 2ca95b6 commit 686b94d
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 30 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[![Coverage Status](https://coveralls.io/repos/github/ziccardi/jnrpe/badge.svg?branch=master)](https://coveralls.io/github/ziccardi/jnrpe?branch=master)
[![CodeQL](https://github.com/ziccardi/jnrpe/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ziccardi/jnrpe/actions/workflows/codeql-analysis.yml)

# JNRPE - Java [**Nagios**](https://www.nagios.org/) Remote Plugin Executor

JNRPE allows the execution of both native and Java Nagios plugins without the overhead of a new JVM instance for each
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,10 @@ private CommandDefinitionProxy(XMLCommand xmlCommand) {
.map(
arg ->
String.format(
"%s%s '%s'",
"%s%s %s",
arg.getName().length() == 1 ? "-" : "--", arg.getName(), arg.getValue()))
.reduce("", (acc, arg) -> String.join(" ", arg));
.reduce("", (acc, arg) -> String.join(" ", acc, arg))
.trim();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ private Optional<IJNRPEConfig> parseConfig() throws InvalidConfigurationExceptio

Optional<IConfigSource> optionalConfigSource = configSourceServiceLoader.findFirst();

if (optionalConfigSource.isPresent()) {
if (optionalConfigSource.isPresent()
&& optionalConfigSource.get().getConfigType().equalsIgnoreCase("xml")) {
try {
var xmlConf = parseConf(optionalConfigSource.get().getConfigStream());

Expand All @@ -65,7 +66,6 @@ private Optional<IJNRPEConfig> parseConfig() throws InvalidConfigurationExceptio
}

XMLConfiguration parseConf(InputStream configStream) throws Exception {

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
import it.jnrpe.services.config.InvalidConfigurationException;
import it.jnrpe.services.config.yaml.internal.YAMLJNRPEConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import java.util.ServiceLoader;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.error.YAMLException;

public class YamlJnrpeConfigProvider implements IConfigProvider {

Expand All @@ -34,16 +35,15 @@ public String getProviderName() {
return "YAML";
}

public Optional<IJNRPEConfig> getConfig() {
if (config.isEmpty()) {
try {
config = parseConfig();
} catch (Exception e) {
EventManager.error("Unable to parse YAML configuration: %s", e.getMessage());
}
}
protected YAMLJNRPEConfig parseConf(InputStream in) throws InvalidConfigurationException {
try {
Yaml yaml = new Yaml();

return config;
return yaml.loadAs(in, YAMLJNRPEConfig.class);
} catch (YAMLException ce) {
throw new InvalidConfigurationException(
"unable to parse the configuration: %s", ce.getMessage());
}
}

private Optional<IJNRPEConfig> parseConfig() throws IOException {
Expand All @@ -61,35 +61,36 @@ private Optional<IJNRPEConfig> parseConfig() throws IOException {

Optional<IConfigSource> optionalConfigSource = configSourceServiceLoader.findFirst();

if (optionalConfigSource.isPresent()) {
if (optionalConfigSource.isPresent()
&& optionalConfigSource.get().getConfigType().equalsIgnoreCase("YAML")) {
Yaml yaml = new Yaml();
var yamlConfigDescription = new TypeDescription(YAMLJNRPEConfig.class, YAMLJNRPEConfig.class);
yamlConfigDescription.addPropertyParameters("server", YAMLJNRPEConfig.ServerConfig.class);

var serverConfigDescription =
new TypeDescription(IServerConfig.class, YAMLJNRPEConfig.ServerConfig.class);
// yamlConfigDescription.addPropertyParameters("bindings", ArrayList.class);
serverConfigDescription.putListPropertyType("binding", YAMLJNRPEConfig.Binding.class);

yaml.addTypeDescription(yamlConfigDescription);
yaml.addTypeDescription(serverConfigDescription);
yaml.addTypeDescription(new TypeDescription(IBinding.class, YAMLJNRPEConfig.Binding.class));
try {
new ConfigValidator().validate(yaml.load(optionalConfigSource.get().getConfigStream()));

return Optional.of(
new YamlJNRPEConfigProxy(parseConf(optionalConfigSource.get().getConfigStream())));
} catch (InvalidConfigurationException ice) {
EventManager.error("YAML Config parsing error: %s", ice.getMessage());
return Optional.empty();
}

return Optional.of(
new YamlJNRPEConfigProxy(
yaml.loadAs(optionalConfigSource.get().getConfigStream(), YAMLJNRPEConfig.class)));
}

EventManager.warn("No config services have been provided");
return Optional.empty();
}

public Optional<IJNRPEConfig> getConfig() {
if (config.isEmpty()) {
try {
config = parseConfig();
} catch (Exception e) {
EventManager.error("Unable to parse YAML configuration: %s", e.getMessage());
}
}

return config;
}

@Override
public String generateSampleConfig() {
return """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,25 @@ public void testValidConfig() throws Exception {
var jnrpeConf = new XMLJNRPEConfigurationProxy(conf);
assertNotNull(jnrpeConf.getServer());
assertNotNull(jnrpeConf.getCommands());
assertNotNull(jnrpeConf.getServer().getBindings());
assertEquals(1, jnrpeConf.getServer().getBindings().size());
assertEquals("127.0.0.1", jnrpeConf.getServer().getBindings().get(0).getIp());
assertEquals(5666, jnrpeConf.getServer().getBindings().get(0).getPort());
assertFalse(jnrpeConf.getServer().getBindings().get(0).isSsl());
assertEquals(1, jnrpeConf.getServer().getBindings().get(0).getAllow().size());
assertEquals("127.0.0.1", jnrpeConf.getServer().getBindings().get(0).getAllow().get(0));
assertNotNull(jnrpeConf.getCommands());
assertEquals(2, jnrpeConf.getCommands().getDefinitions().size());
assertEquals("check_disk_C", jnrpeConf.getCommands().getDefinitions().get(0).getName());
assertEquals("CHECK_DISK", jnrpeConf.getCommands().getDefinitions().get(0).getPlugin());
assertEquals(
"--path C: --warning $ARG1$ --critical $ARG2$",
jnrpeConf.getCommands().getDefinitions().get(0).getArgs());
assertEquals("check_disk_E", jnrpeConf.getCommands().getDefinitions().get(1).getName());
assertEquals("CHECK_DISK", jnrpeConf.getCommands().getDefinitions().get(1).getPlugin());
assertEquals(
"--path E: --warning $ARG1$ --critical $ARG2$",
jnrpeConf.getCommands().getDefinitions().get(1).getArgs());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*******************************************************************************
* Copyright (C) 2023, Massimiliano Ziccardi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package it.jnrpe.services.config.yaml;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;

import it.jnrpe.services.config.InvalidConfigurationException;
import java.io.ByteArrayInputStream;
import org.junit.jupiter.api.Test;

public class YamlJnrpeConfigProviderTest {
@Test
public void testValidConfig() throws Exception {
String xmlText =
"""
server:
# Configure the IP and the PORT where JNRPE will listen.
# Use 0.0.0.0 as address to bind all addresses on the same port
bindings:
-
ip: "127.0.0.1"
port: 5666
ssl: false
allow:
-
"127.0.0.1"
commands:
definitions:
-
name: check_disk_C
plugin: CHECK_DISK
args: "--path C: --warning $ARG1$ --critical $ARG2$"
-
name: check_disk_E
plugin: CHECK_DISK
args: "--path E: --warning $ARG1$ --critical $ARG2$"
""";
try (var bin = new ByteArrayInputStream(xmlText.getBytes())) {
var conf = new YamlJnrpeConfigProvider().parseConf(bin);
var jnrpeConf = new YamlJNRPEConfigProxy(conf);
assertNotNull(jnrpeConf.getServer());
assertNotNull(jnrpeConf.getCommands());
assertNotNull(jnrpeConf.getServer().getBindings());
assertEquals(1, jnrpeConf.getServer().getBindings().size());
assertEquals("127.0.0.1", jnrpeConf.getServer().getBindings().get(0).getIp());
assertEquals(5666, jnrpeConf.getServer().getBindings().get(0).getPort());
assertFalse(jnrpeConf.getServer().getBindings().get(0).isSsl());
assertEquals(1, jnrpeConf.getServer().getBindings().get(0).getAllow().size());
assertEquals("127.0.0.1", jnrpeConf.getServer().getBindings().get(0).getAllow().get(0));
assertNotNull(jnrpeConf.getCommands());
assertEquals(2, jnrpeConf.getCommands().getDefinitions().size());
assertEquals("check_disk_C", jnrpeConf.getCommands().getDefinitions().get(0).getName());
assertEquals("CHECK_DISK", jnrpeConf.getCommands().getDefinitions().get(0).getPlugin());
assertEquals(
"--path C: --warning $ARG1$ --critical $ARG2$",
jnrpeConf.getCommands().getDefinitions().get(0).getArgs());
assertEquals("check_disk_E", jnrpeConf.getCommands().getDefinitions().get(1).getName());
assertEquals("CHECK_DISK", jnrpeConf.getCommands().getDefinitions().get(1).getPlugin());
assertEquals(
"--path E: --warning $ARG1$ --critical $ARG2$",
jnrpeConf.getCommands().getDefinitions().get(1).getArgs());
}
}

@Test
public void testMalformedConfig() throws Exception {
String xmlText =
"""
This configuration is malformed.
server:
# Configure the IP and the PORT where JNRPE will listen.
# Use 0.0.0.0 as address to bind all addresses on the same port
bindings:
-
ip: "127.0.0.1"
port: 5666
ssl: false
allow:
-
"127.0.0.1"
commands:
definitions:
-
name: check_disk_C
plugin: CHECK_DISK
args: "--path C: --warning $ARG1$ --critical $ARG2$"
-
name: check_disk_E
plugin: CHECK_DISK
args: "--path E: --warning $ARG1$ --critical $ARG2$"
""";
try (var bin = new ByteArrayInputStream(xmlText.getBytes())) {
Exception exception =
assertThrows(
InvalidConfigurationException.class,
() -> new YamlJnrpeConfigProvider().parseConf(bin));
assertTrue(exception.getMessage().startsWith("unable to parse the configuration: "));
}
}
}

0 comments on commit 686b94d

Please sign in to comment.