Skip to content

Commit

Permalink
Enable passing input file, output file, and mibs dir on command line … (
Browse files Browse the repository at this point in the history
#1028)

* Enable passing input file, output file, and mib dirs on command line for the generate command

---------

Signed-off-by: dnck <cookdj0128@gmail.com>
  • Loading branch information
dnck committed Nov 10, 2023
1 parent f587fce commit 6c92a3f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
15 changes: 13 additions & 2 deletions generator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ make generator mibs
```
## Preparation

It is recommended to have a directory per device family which contains the mibs dir for the device family,
It is recommended to have a directory per device family which contains the mibs dir for the device family,
a logical link to the generator executable and the generator.yml configuration file. This is to avoid name space collisions
in the MIB definition. Keep only the required MIBS in the mibs directory for the devices.
Then merge all the resulting snmp.yml files into one main file that will be used by the snmp_exporter collector.
Expand All @@ -35,6 +35,17 @@ by the snmp_exporter executable to collect data from the snmp enabled devices.

Additional command are available for debugging, use the `help` command to see them.

After building, you can pass a directories of mibs, a path to the `generator.yml`
file and the intended path of your output file e.g. `snmp.yml` to the `generate`
command like so,
```bash
./generator generate \
-m /tmp/deviceFamilyMibs \
-m /tmp/sharedMibs \
-g /tmp/generator.yml \
-o /tmp/snmp.yml
```

### MIB Parsing options

The parsing of MIBs can be controlled using the `--snmp.mibopts` flag. The available values depend on the net-snmp version used to build the generator.
Expand Down Expand Up @@ -173,7 +184,7 @@ modules:
# If one of the target OIDs is used in a lookup, the filter will apply ALL tables using this lookup
# For a network switch, this could be used to collect a subset of interfaces such as uplinks
# For a router, this could be used to collect all real ports but not vlans and other virtual interfaces
# Specifying ifAlias or ifName if they are used in lookups with ifIndex will apply to the filter to
# Specifying ifAlias or ifName if they are used in lookups with ifIndex will apply to the filter to
# all the OIDs that depend on the lookup, such as ifSpeed, ifInHcOctets, etc.
# This feature applies to any table(s) OIDs using a common index
- targets:
Expand Down
6 changes: 4 additions & 2 deletions generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func generateConfig(nodes *Node, nameToNode map[string]*Node, logger log.Logger)
return fmt.Errorf("unable to determine absolute path for output")
}

content, err := os.ReadFile("generator.yml")
content, err := os.ReadFile(*generatorYmlPath)
if err != nil {
return fmt.Errorf("error reading yml config: %s", err)
}
Expand Down Expand Up @@ -98,7 +98,9 @@ var (
failOnParseErrors = kingpin.Flag("fail-on-parse-errors", "Exit with a non-zero status if there are MIB parsing errors").Default("false").Bool()
snmpMIBOpts = kingpin.Flag("snmp.mibopts", "Toggle various defaults controlling MIB parsing, see snmpwalk --help").String()
generateCommand = kingpin.Command("generate", "Generate snmp.yml from generator.yml")
outputPath = generateCommand.Flag("output-path", "Path to to write resulting config file").Default("snmp.yml").Short('o').String()
userMibsDir = generateCommand.Flag("mibs-dir", "Paths to mibs directory").Default("").Short('m').Strings()
generatorYmlPath = generateCommand.Flag("generator-path", "Path to the input generator.yml file").Default("generator.yml").Short('g').String()
outputPath = generateCommand.Flag("output-path", "Path to write the snmp_exporter's config file").Default("snmp.yml").Short('o').String()
parseErrorsCommand = kingpin.Command("parse_errors", "Debug: Print the parse errors output by NetSNMP")
dumpCommand = kingpin.Command("dump", "Debug: Dump the parsed and prepared MIBs")
)
Expand Down
21 changes: 17 additions & 4 deletions generator/net_snmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import (
"io"
"os"
"sort"
"strings"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
Expand Down Expand Up @@ -152,20 +153,32 @@ var (
}
)

// getMibsDir joins the user-specified MIB directories into a single string; if the user didn't pass any,
// the default netsnmp mibs directory is returned.
func getMibsDir(paths []string) string {
if len(paths) == 1 && paths[0] == "" {
return C.GoString(C.netsnmp_get_mib_directory())
}
return strings.Join(paths, ":")
}

// Initialize NetSNMP. Returns MIB parse errors.
//
// Warning: This function plays with the stderr file descriptor.
func initSNMP(logger log.Logger) (string, error) {
// Load all the MIBs.
os.Setenv("MIBS", "ALL")
// Help the user find their MIB directories.
level.Info(logger).Log("msg", "Loading MIBs", "from", C.GoString(C.netsnmp_get_mib_directory()))
err := os.Setenv("MIBS", "ALL")
if err != nil {
return "", err
}
mibsDir := getMibsDir(*userMibsDir)
level.Info(logger).Log("msg", "Loading MIBs", "from", mibsDir)
C.netsnmp_set_mib_directory(C.CString(mibsDir))
if *snmpMIBOpts != "" {
C.snmp_mib_toggle_options(C.CString(*snmpMIBOpts))
}
// We want the descriptions.
C.snmp_set_save_descriptions(1)

// Make stderr go to a pipe, as netsnmp tends to spew a
// lot of errors on startup that there's no apparent
// way to disable or redirect.
Expand Down

0 comments on commit 6c92a3f

Please sign in to comment.