Allow glob of --host and --yaml; cut release 1.2.1
This commit is contained in:
@ -56,11 +56,11 @@ make build
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Backup all devices (multiple YAML files are automatically merged)
|
# Backup all devices (multiple YAML files are automatically merged)
|
||||||
ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml --output-dir /backup
|
ipng-router-backup --yaml "00-*.yaml" --yaml config.yaml --output-dir /backup
|
||||||
|
|
||||||
# Backup specific devices
|
# Backup specific devices
|
||||||
ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml --output-dir /backup \
|
ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml --output-dir /backup \
|
||||||
--host asw100
|
--host "asw*"
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Check output**:
|
3. **Check output**:
|
||||||
|
8
debian/changelog
vendored
8
debian/changelog
vendored
@ -1,3 +1,11 @@
|
|||||||
|
ipng-router-backup (1.2.1) stable; urgency=low
|
||||||
|
|
||||||
|
* Add glob pattern support for --yaml flag (e.g., --yaml "*.yaml")
|
||||||
|
* Add glob pattern support for --host flag (e.g., --host "asw*")
|
||||||
|
* Update documentation with glob pattern examples
|
||||||
|
|
||||||
|
-- Pim van Pelt <pim@ipng.ch> Sun, 07 Jul 2025 21:00:00 +0100
|
||||||
|
|
||||||
ipng-router-backup (1.2.0) stable; urgency=low
|
ipng-router-backup (1.2.0) stable; urgency=low
|
||||||
|
|
||||||
* Add atomic file operations with .new suffix for backup reliability
|
* Add atomic file operations with .new suffix for backup reliability
|
||||||
|
@ -79,16 +79,20 @@ Files are merged automatically using mergo. Later files override earlier ones:
|
|||||||
```bash
|
```bash
|
||||||
# Load multiple files - later files override earlier ones
|
# Load multiple files - later files override earlier ones
|
||||||
ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml --yaml overrides.yaml
|
ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml --yaml overrides.yaml
|
||||||
|
|
||||||
|
# Load files using glob patterns
|
||||||
|
ipng-router-backup --yaml "*.yaml"
|
||||||
|
ipng-router-backup --yaml "config/*.yaml"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Command Line Usage
|
## Command Line Usage
|
||||||
|
|
||||||
### Required Flags
|
### Required Flags
|
||||||
- **`--yaml`**: Path to YAML configuration file(s) (can be repeated)
|
- **`--yaml`**: Path to YAML configuration file(s) or glob patterns (can be repeated)
|
||||||
|
|
||||||
### Optional Flags
|
### Optional Flags
|
||||||
- **`--output-dir`**: Output directory (default: `/tmp`)
|
- **`--output-dir`**: Output directory (default: `/tmp`)
|
||||||
- **`--host`**: Specific hostname(s) to process (can be repeated)
|
- **`--host`**: Specific hostname(s) or glob patterns to process (can be repeated)
|
||||||
- **`--password`**: SSH password
|
- **`--password`**: SSH password
|
||||||
- **`--key-file`**: SSH private key file path
|
- **`--key-file`**: SSH private key file path
|
||||||
- **`--port`**: SSH port (default: `22`)
|
- **`--port`**: SSH port (default: `22`)
|
||||||
@ -96,14 +100,14 @@ ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml --yaml overrid
|
|||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Basic usage
|
# Basic usage with glob patterns
|
||||||
ipng-router-backup --yaml config.yaml
|
ipng-router-backup --yaml "*.yaml"
|
||||||
|
|
||||||
# Multiple files
|
# Multiple files
|
||||||
ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml
|
ipng-router-backup --yaml 00-device-types.yaml --yaml config.yaml
|
||||||
|
|
||||||
# Specific devices only
|
# Devices matching patterns
|
||||||
ipng-router-backup --yaml config.yaml --host asw100 --host core-01
|
ipng-router-backup --yaml config.yaml --host "asw*" --host "*switch*"
|
||||||
|
|
||||||
# Custom output directory
|
# Custom output directory
|
||||||
ipng-router-backup --yaml config.yaml --output-dir /backup/network
|
ipng-router-backup --yaml config.yaml --output-dir /backup/network
|
||||||
|
@ -18,7 +18,7 @@ The tool supports multiple device types with predefined command sets, SSH agent
|
|||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.BR --yaml " \fICONFIG_FILE\fR"
|
.BR --yaml " \fICONFIG_FILE\fR"
|
||||||
YAML configuration file(s) (required)
|
YAML configuration file(s) or glob patterns (required)
|
||||||
.TP
|
.TP
|
||||||
.BR --output-dir " \fIDIRECTORY\fR"
|
.BR --output-dir " \fIDIRECTORY\fR"
|
||||||
Output directory for command output files (default: /tmp)
|
Output directory for command output files (default: /tmp)
|
||||||
@ -33,7 +33,7 @@ SSH private key file path
|
|||||||
SSH port number (default: 22)
|
SSH port number (default: 22)
|
||||||
.TP
|
.TP
|
||||||
.BR --host " \fIHOSTNAME\fR"
|
.BR --host " \fIHOSTNAME\fR"
|
||||||
Specific host(s) to process (can be repeated, processes all if not specified)
|
Specific host(s) or glob patterns to process (can be repeated, processes all if not specified)
|
||||||
.TP
|
.TP
|
||||||
.BR --help
|
.BR --help
|
||||||
Show help message
|
Show help message
|
||||||
@ -72,9 +72,9 @@ Password authentication (--password option)
|
|||||||
For each device, a text file named after the hostname is created in the specified directory. Each command output is prefixed with "## COMMAND: <command_name>" for easy identification.
|
For each device, a text file named after the hostname is created in the specified directory. Each command output is prefixed with "## COMMAND: <command_name>" for easy identification.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.TP
|
.TP
|
||||||
Basic usage:
|
Basic usage with glob patterns:
|
||||||
.EX
|
.EX
|
||||||
ipng-router-backup --yaml /etc/ipng-router-backup/*.yaml
|
ipng-router-backup --yaml "*.yaml"
|
||||||
.EE
|
.EE
|
||||||
.TP
|
.TP
|
||||||
Custom output directory:
|
Custom output directory:
|
||||||
@ -87,9 +87,9 @@ Using password authentication:
|
|||||||
ipng-router-backup --yaml config.yaml --password mysecretpass
|
ipng-router-backup --yaml config.yaml --password mysecretpass
|
||||||
.EE
|
.EE
|
||||||
.TP
|
.TP
|
||||||
Process specific hosts only:
|
Process hosts matching patterns:
|
||||||
.EX
|
.EX
|
||||||
ipng-router-backup --yaml config.yaml --host asw100 --host asw120
|
ipng-router-backup --yaml config.yaml --host "asw*" --host "*switch*"
|
||||||
.EE
|
.EE
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
|
33
src/main.go
33
src/main.go
@ -6,11 +6,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Version = "1.2.0"
|
const Version = "1.2.1"
|
||||||
|
|
||||||
// Config and SSH types are now in separate packages
|
// Config and SSH types are now in separate packages
|
||||||
|
|
||||||
@ -36,8 +37,21 @@ func main() {
|
|||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Printf("IPng Networks Router Backup v%s\n", Version)
|
fmt.Printf("IPng Networks Router Backup v%s\n", Version)
|
||||||
|
|
||||||
|
// Expand glob patterns in YAML files
|
||||||
|
var expandedYamlFiles []string
|
||||||
|
for _, pattern := range yamlFiles {
|
||||||
|
matches, err := filepath.Glob(pattern)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Invalid glob pattern '%s': %v", pattern, err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
log.Fatalf("No files matched pattern '%s'", pattern)
|
||||||
|
}
|
||||||
|
expandedYamlFiles = append(expandedYamlFiles, matches...)
|
||||||
|
}
|
||||||
|
|
||||||
// Load configuration
|
// Load configuration
|
||||||
cfg, err := ConfigRead(yamlFiles)
|
cfg, err := ConfigRead(expandedYamlFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to load config: %v", err)
|
log.Fatalf("Failed to load config: %v", err)
|
||||||
}
|
}
|
||||||
@ -63,11 +77,16 @@ func main() {
|
|||||||
devicesToProcess := cfg.Devices
|
devicesToProcess := cfg.Devices
|
||||||
if len(hostFilter) > 0 {
|
if len(hostFilter) > 0 {
|
||||||
devicesToProcess = make(map[string]Device)
|
devicesToProcess = make(map[string]Device)
|
||||||
for _, hostname := range hostFilter {
|
for _, pattern := range hostFilter {
|
||||||
if deviceConfig, exists := cfg.Devices[hostname]; exists {
|
patternMatched := false
|
||||||
devicesToProcess[hostname] = deviceConfig
|
for hostname, deviceConfig := range cfg.Devices {
|
||||||
} else {
|
if matched, _ := filepath.Match(pattern, hostname); matched {
|
||||||
fmt.Printf("Warning: Host '%s' not found in config file\n", hostname)
|
devicesToProcess[hostname] = deviceConfig
|
||||||
|
patternMatched = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !patternMatched {
|
||||||
|
fmt.Printf("Warning: Host pattern '%s' did not match any devices\n", pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user