Compare commits
200 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd019bc407 | |||
| febc2680f4 | |||
| caf2397349 | |||
| 172ca8712e | |||
| bda16bcbb5 | |||
| b5d069112f | |||
| f56393c84c | |||
| 55ef8e1733 | |||
| 075fc16ec9 | |||
| 0d6a13c1cf | |||
| e57939f858 | |||
| d45b1562fc | |||
| 7fe07f86a9 | |||
| 14c81a00a7 | |||
| 3eced64453 | |||
| c284d928fd | |||
| dd9da9452b | |||
| 11d5121954 | |||
| 66d622b474 | |||
| 47b2aabd9f | |||
| b91cf18b04 | |||
| 305b504ca1 | |||
| 7be2679b91 | |||
| 3c6e3ed914 | |||
| 02bc040e2a | |||
| 9f1f36215a | |||
| ff75f4bbcd | |||
| 5f40713e98 | |||
| cd5f7611a9 | |||
| b542711078 | |||
| 52dbc353e5 | |||
| 6bef0c3e5b | |||
| 4d705d78fb | |||
| 62d47ecfa7 | |||
| 32444ff82e | |||
| a5a7c05640 | |||
| bfb81e11b2 | |||
| fd4c83f9c0 | |||
| fe27c6396a | |||
| c89dde186a | |||
| 18a64de0de | |||
| 99c622b69f | |||
| 95e85e8b45 | |||
| 1a48c7bca5 | |||
| 5d21764ef1 | |||
| c7302f0e17 | |||
| fb1c8ec4fb | |||
| fe9462dac0 | |||
| d8453d1fb0 | |||
| 65c46a1e26 | |||
| f859b5961f | |||
| 25ddd65f25 | |||
| bcba6b2086 | |||
| 753b03861f | |||
| 80a45cd595 | |||
| 551c8ad441 | |||
| 3823b1bf44 | |||
| f777c78aad | |||
| bb693dbb97 | |||
| 7beda281e0 | |||
| 1143d2850b | |||
| 8900bd70a4 | |||
| 6db5f73bc0 | |||
| a163c11129 | |||
| 2b4d191271 | |||
| 417088c32b | |||
| 4fa5efa5b6 | |||
| a0bf51636c | |||
| 684edd7985 | |||
| 3acb20a40f | |||
| 0007c8696a | |||
| cf2baf3601 | |||
| e6b9f8e6e6 | |||
| 2eefc59cf7 | |||
| 98d8b8e8f2 | |||
| 1ad50ebcf8 | |||
| c483a1056f | |||
| 3b9f569310 | |||
| 843be7968b | |||
| d477d850ac | |||
| 8eb3229af7 | |||
| d89a208bbd | |||
| 0d28d6afcf | |||
| 7c42a9a7cd | |||
| 31339fb4d8 | |||
| c642e827f5 | |||
| a328239021 | |||
| 4ee60184bf | |||
| 161ad31577 | |||
| 7c5f4a95da | |||
| 4981acbf9d | |||
| 932d5c380f | |||
| f84d76badf | |||
| 6ee6e10621 | |||
| 127d38c076 | |||
| 0218dee76d | |||
| 67a1eab908 | |||
| c618ca33f8 | |||
| 6e7d912fa2 | |||
| b90d1958b2 | |||
| c187fbb735 | |||
| c3de4386ab | |||
| e20141043c | |||
| 11ec1a98d8 | |||
| 8788d473a5 | |||
| edc669b340 | |||
| 086835453b | |||
| 5d3c265ce9 | |||
| 8c633fd4b2 | |||
| a664edaed7 | |||
| e88773e289 | |||
| 5c2bfcc940 | |||
| aee513f786 | |||
| 6b99cfa196 | |||
| c24e8086e9 | |||
| c12bbe3bee | |||
| 33febd662e | |||
| 5635c1edd0 | |||
| e169778c82 | |||
| c838bfe815 | |||
| e81a5def47 | |||
| 18884c640d | |||
| ee2256bfb2 | |||
| 82d79c520a | |||
| c30ae2ac3e | |||
| fc738597ff | |||
| aebef21eb4 | |||
| c660e97434 | |||
| d35fdc890d | |||
| 6fe1f26c71 | |||
| 5b5568910d | |||
| 3425330890 | |||
| b5f7c3fd72 | |||
| 01efeab13f | |||
| 9a663f4260 | |||
| 7c635c36e0 | |||
| fff33849da | |||
| 3391ffa4e6 | |||
| b7d1be495e | |||
| 2daf2f130d | |||
| d120c2ca8f | |||
| 02fd04930d | |||
| 10b0abe707 | |||
| 291a954e9c | |||
| e43eecf383 | |||
| ea676fe0da | |||
| e73bd9ff3b | |||
| fd9426181f | |||
| c25edc5d78 | |||
| aebfbda64e | |||
| 5fe0629b0f | |||
| 7d6acd77b5 | |||
| 9d646297c7 | |||
| bf8d261cf3 | |||
| 686cd0019a | |||
| b7b002bd72 | |||
| b8a63f39f5 | |||
| feacb83274 | |||
| 2aeb435167 | |||
| 51f5084dd0 | |||
| cf04e4456a | |||
| 25dc6225b3 | |||
| a300f696d3 | |||
| 8161aaa0a9 | |||
| a6bfabe22f | |||
| a5466fc121 | |||
| fbf2d9cbbc | |||
| 437642608b | |||
| a4214b2b3f | |||
| 6ccb75f4fa | |||
| b8a82b2836 | |||
| 78428a49fc | |||
| 42bc11bf1a | |||
| 44e3d534f6 | |||
| 1fbe3282c8 | |||
| 10a6342233 | |||
| a35db2e05d | |||
| 7c4868ee4b | |||
| affdd0abfd | |||
| 7224661c71 | |||
| e353ed0225 | |||
| 37bd69b675 | |||
| 14bca64657 | |||
| d9baf44199 | |||
| 6de94d038f | |||
| a04d1db077 | |||
| 62942540b5 | |||
| 904a579994 | |||
| 4b382bddd9 | |||
| 5e7c52997c | |||
| f7676e73ba | |||
| 2ca5f193e4 | |||
| 9ffa2e473e | |||
| 9fd60b6bf7 | |||
| 951bf97eb2 | |||
| a2a89011fe | |||
| d893a2684e | |||
| ee83586072 | |||
| 02321870b5 | |||
| 3e9138e05a |
9
.changes/0.2.4.md
Executable file
9
.changes/0.2.4.md
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
## 0.2.4 - 2023-02-18
|
||||||
|
### Added
|
||||||
|
* Notifications now display errors and the output of the failed command.
|
||||||
|
* CI configs for GitHub and Woodpecker
|
||||||
|
* Added `version` subcommand
|
||||||
|
### Changed
|
||||||
|
* Console logging can be disabled by setting `console-disabled` in the `logging` object
|
||||||
|
## Fixed
|
||||||
|
* If Host was not defined for an incomplete `hosts` object, any commands would fail as they could not look up the values in the SSH config files.
|
||||||
6
.changes/header.tpl.md
Executable file
6
.changes/header.tpl.md
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
# Changelog
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
||||||
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
1
.changes/unreleased/.gitkeep
Executable file
1
.changes/unreleased/.gitkeep
Executable file
@@ -0,0 +1 @@
|
|||||||
|
*.yaml
|
||||||
16
.changes/v0.10.0.md
Executable file
16
.changes/v0.10.0.md
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
## v0.10.0 - 2025-03-08
|
||||||
|
### Added
|
||||||
|
* Hooks: improved logging when executing
|
||||||
|
* User commands: adding SSH keys using config key `userSshPubKeys`
|
||||||
|
* directives: added support for fetching values using directive `%{externalSource:key}%`
|
||||||
|
### Changed
|
||||||
|
* Commands: if dir is not specified, run in config dir
|
||||||
|
* FileDirective: use the config directory if path is not absolute
|
||||||
|
* Host: changes to case of some keys
|
||||||
|
* Notifications: added external directive to sensitive keys
|
||||||
|
### Fixed
|
||||||
|
* LocalFetcher: return fetch error
|
||||||
|
* Lists: load file key before attempting to load from current file
|
||||||
|
* fix: host not in config file, but in ssh config, properly added to hosts struct
|
||||||
|
* SSH: password authentication bugs
|
||||||
|
* User commands: change user password works
|
||||||
8
.changes/v0.10.1.md
Executable file
8
.changes/v0.10.1.md
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
## v0.10.1 - 2025-03-11
|
||||||
|
### Added
|
||||||
|
* UserCommands: add ssh public keys when running locally
|
||||||
|
* UserCommands: add field CreateUserHome
|
||||||
|
### Changed
|
||||||
|
* UserCommands: create temp file when modifing password over SSH
|
||||||
|
* UserCommands: change field name
|
||||||
|
* Vault: keys are now referenced by `name`, and the actual data by `data`
|
||||||
6
.changes/v0.10.2.md
Executable file
6
.changes/v0.10.2.md
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
## v0.10.2 - 2025-03-19
|
||||||
|
### Added
|
||||||
|
* Notifications: http service added
|
||||||
|
* Variable support. Can be referenced with `%{var:nameOfVar}%` in select string fields.
|
||||||
|
### Changed
|
||||||
|
* vault: initialize vault before validating config
|
||||||
21
.changes/v0.11.0.md
Normal file
21
.changes/v0.11.0.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
## v0.11.0 - 2025-11-24
|
||||||
|
### Added
|
||||||
|
* feat: Package operation `versionCheck` supports regular expressions (see [regexp](https://pkg.go.dev/regexp) package for docs)
|
||||||
|
* Command lists: added `cmdLists.[name].notify` object
|
||||||
|
* Testing setup with Docker
|
||||||
|
* CLI: add global flag --hostsConfig that allows hosts to be dynamic in relation to the main config
|
||||||
|
* CLI: Exec subcommand `hosts`. See documentation for more details.
|
||||||
|
* CLI: added `exec hosts` subcommand `list`
|
||||||
|
* Add support for hosts in parallel
|
||||||
|
### Changed
|
||||||
|
* Commands: `host` can now be `localhost` or `127.0.0.1` to run commands locally
|
||||||
|
* lists loaded from external files only if no list config present in current file
|
||||||
|
* `PackageManager.Parse` renamed to `ParseRemotePackageManagerVersionOutput`. This now returns arrays of PackageManagerCommon.Package and errors.
|
||||||
|
* Internal: refactoring and renaming functions
|
||||||
|
* Commands: moved output-prefixed keys to the `commands.[name].output` object
|
||||||
|
* Change internal method name for better understanding
|
||||||
|
* Improved error message for remote version package output
|
||||||
|
### Fixed
|
||||||
|
* Command Lists: hooks now run correctly when commands finish
|
||||||
|
* Log file passed using `--log-file` correctly used
|
||||||
|
* Cmd Type `script` now correctly appends arguments
|
||||||
8
.changes/v0.3.0.md
Executable file
8
.changes/v0.3.0.md
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
## v0.3.0 - 2023-01-07
|
||||||
|
### Added
|
||||||
|
* Getting environment variables and passwords from Vault (not tested yet)
|
||||||
|
* Vault configuration to config (not tested yet)
|
||||||
|
* Ability to run scripts from file on local machine on the remote host
|
||||||
|
* Ability to get ouput in the notification of a list for individual commands or all commands
|
||||||
|
### Changed
|
||||||
|
* Make SSH connections close after all commands have been run; reuse previous connections if needed
|
||||||
3
.changes/v0.3.1.md
Executable file
3
.changes/v0.3.1.md
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
## v0.3.1 - 2023-07-20
|
||||||
|
### Changed
|
||||||
|
* If an SSH session failed to be created, the command would fail. This would be caused when restarting the SSH host. The SSH connection is attempted to be created again. If successful, the command is executed normally.
|
||||||
13
.changes/v0.4.0.md
Executable file
13
.changes/v0.4.0.md
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
## v0.4.0 - 2023-09-08
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Added `scriptEnvFile` to command object that allows one to specify an environment file (or any file really) when a `scriptFile` is run. Inspired by the practice of keeping environment variables and scripts or commands seperate.
|
||||||
|
* Basis for listing commands
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* BREAKING: Notifications object now takes the form of service.id, where service can be "mail" or "matrix" and id is a unique id for the service.
|
||||||
|
* BREAKING: Since the change to the notifications object, cmd-lists' inner map key 'notifications' must be of the form service.id. id must be defined for that service. See notifications docs for aviliable services.
|
||||||
|
* Config parser is now the simpler Koanf - Keys are now case-sensitive
|
||||||
|
* Log size limited to 50 Mb
|
||||||
9
.changes/v0.5.0.md
Executable file
9
.changes/v0.5.0.md
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
## v0.5.0 - 2024-11-19
|
||||||
|
### Added
|
||||||
|
* Lists can now go in a file. See docs for more information.
|
||||||
|
* commands.[name].type: script now opens `scriptEnvFile`.
|
||||||
|
* Hooks for Commands.[name]. Error, success, and final. [#12]
|
||||||
|
### Changed
|
||||||
|
* GetKnownHosts is now a method of Host
|
||||||
|
### Fixed
|
||||||
|
* make command logger be used for errors, not just when running the command
|
||||||
4
.changes/v0.6.0.md
Executable file
4
.changes/v0.6.0.md
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
## v0.6.0 - 2025-01-04
|
||||||
|
### Added
|
||||||
|
* Command Type Package - allows one to perform package operations [docs](https://backy.cybershell.xyz/config/packages/)
|
||||||
|
* Exec subcommand `host` allows for parallel execution of commands on hosts. [See docs](https://backy.cybershell.xyz/cli/exec)
|
||||||
3
.changes/v0.6.1.md
Executable file
3
.changes/v0.6.1.md
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
## v0.6.1 - 2025-01-04
|
||||||
|
### Fixed
|
||||||
|
* When running a list, hooks now run explicitly after the command executes. Fixed panic due to improper logic.
|
||||||
16
.changes/v0.7.0.md
Executable file
16
.changes/v0.7.0.md
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
## v0.7.0 - 2025-02-11
|
||||||
|
### Added
|
||||||
|
* [feat]: package `packageOperation` option `checkVersion` implemented
|
||||||
|
* user management added - see docs
|
||||||
|
* Support for remote config sources. Only config file and list can be used for now.
|
||||||
|
* Cache functionality - still a WIP
|
||||||
|
* Flag `--s3-endpoint` for config file fetching from S3
|
||||||
|
### Changed
|
||||||
|
* Internal refactoring of config setup
|
||||||
|
* Formatting and sending for notifications
|
||||||
|
* name of `configfetcher` to `remotefetcher`
|
||||||
|
* Flags that took comma-separated lists now have to be passed multiple times for each argument.
|
||||||
|
* Hosts passed to `exec host` now checked against default SSH config files
|
||||||
|
### Fixed
|
||||||
|
* Parsing of remote URLs when determining list config file path
|
||||||
|
* Incorrect error notification template value
|
||||||
3
.changes/v0.7.1.md
Executable file
3
.changes/v0.7.1.md
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
## v0.7.1 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* Incorrect local config file loading logic caused files to not be detected
|
||||||
3
.changes/v0.7.2.md
Executable file
3
.changes/v0.7.2.md
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
## v0.7.2 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* CI configs
|
||||||
3
.changes/v0.7.3.md
Executable file
3
.changes/v0.7.3.md
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
## v0.7.3 - 2025-02-14
|
||||||
|
### Changed
|
||||||
|
* GoReleaser configs
|
||||||
5
.changes/v0.7.4.md
Executable file
5
.changes/v0.7.4.md
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
## v0.7.4 - 2025-02-14
|
||||||
|
### Changed
|
||||||
|
* CI configs
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
5
.changes/v0.7.5.md
Executable file
5
.changes/v0.7.5.md
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
## v0.7.5 - 2025-02-14
|
||||||
|
### Changed
|
||||||
|
* CI configs
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
4
.changes/v0.7.6.md
Executable file
4
.changes/v0.7.6.md
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
## v0.7.6 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
|
* CI configs
|
||||||
4
.changes/v0.7.7.md
Executable file
4
.changes/v0.7.7.md
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
## v0.7.7 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
|
* CI configs
|
||||||
4
.changes/v0.7.8.md
Executable file
4
.changes/v0.7.8.md
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
## v0.7.8 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* Github CI config
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
6
.changes/v0.8.0.md
Executable file
6
.changes/v0.8.0.md
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
## v0.8.0 - 2025-02-15
|
||||||
|
### Changed
|
||||||
|
* Breaking: `cmd-lists` key changed to `cmdLists`
|
||||||
|
* Properly load list config
|
||||||
|
* Config file loading properly errors
|
||||||
|
* CI Configs
|
||||||
12
.changes/v0.9.0.md
Executable file
12
.changes/v0.9.0.md
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
## v0.9.0 - 2025-02-28
|
||||||
|
### Added
|
||||||
|
* `list` command with subcommands `cmds` and `lists`
|
||||||
|
* Deprecation and unsupported warnings for old config keys
|
||||||
|
* CLI flag `--cmdStdOut` to output command's stdout/stderr to stdout
|
||||||
|
* Command type `remoteScript`. See docs for more info.
|
||||||
|
### Changed
|
||||||
|
* change to enums for Command type
|
||||||
|
* Cache now stores resources by URL hash for ease-of-lookup
|
||||||
|
* Changed PackageOperation to enums
|
||||||
|
### Fixed
|
||||||
|
* Local command's `dir` full path is now found with home directory
|
||||||
3
.changes/v0.9.1.md
Executable file
3
.changes/v0.9.1.md
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
## v0.9.1 - 2025-03-01
|
||||||
|
### Changed
|
||||||
|
* Use EnvVar AWS_PROFILE to get S3 profile
|
||||||
26
.changie.yaml
Executable file
26
.changie.yaml
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
changesDir: .changes
|
||||||
|
unreleasedDir: unreleased
|
||||||
|
headerPath: header.tpl.md
|
||||||
|
changelogPath: CHANGELOG.md
|
||||||
|
versionExt: md
|
||||||
|
versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}'
|
||||||
|
kindFormat: '### {{.Kind}}'
|
||||||
|
changeFormat: '* {{.Body}}'
|
||||||
|
kinds:
|
||||||
|
- label: Added
|
||||||
|
auto: minor
|
||||||
|
- label: Changed
|
||||||
|
auto: major
|
||||||
|
- label: Deprecated
|
||||||
|
auto: minor
|
||||||
|
- label: Removed
|
||||||
|
auto: major
|
||||||
|
- label: Fixed
|
||||||
|
auto: patch
|
||||||
|
- label: Security
|
||||||
|
auto: patch
|
||||||
|
newlines:
|
||||||
|
afterChangelogHeader: 1
|
||||||
|
beforeChangelogVersion: 1
|
||||||
|
endOfVersion: 1
|
||||||
|
envPrefix: CHANGIE_
|
||||||
1
.frontmatter/database/mediaDb.json
Executable file
1
.frontmatter/database/mediaDb.json
Executable file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
.frontmatter/database/taxonomyDb.json
Executable file
1
.frontmatter/database/taxonomyDb.json
Executable file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
40
.github/workflows/release.yml
vendored
Executable file
40
.github/workflows/release.yml
vendored
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
name: goreleaser
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
# run only against tags
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
# issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
goreleaser:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- run: git fetch --force --tags
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
cache: true
|
||||||
|
# More assembly might be required: Docker logins, GPG, etc. It all depends
|
||||||
|
# on your needs.
|
||||||
|
- uses: olegtarasov/get-tag@v2.1.4
|
||||||
|
id: tagName
|
||||||
|
with:
|
||||||
|
# tagRegex: "foobar-(.*)" # Optional. Returns specified group text as tag name. Full tag string is returned if regex is not defined.
|
||||||
|
tagRegexGroup: 1 # Optional. Default is 1.
|
||||||
|
- uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
distribution: goreleaser
|
||||||
|
version: 2.7.0
|
||||||
|
args: release --release-notes=".changes/${{ env.GIT_TAG_NAME }}.md" -f .goreleaser/github.yml --clean
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GORELEASER_TOKEN }}
|
||||||
|
GIT_TAG_NAME: ${{ steps.tagName.outputs.tag }}
|
||||||
8
.gitignore
vendored
Normal file → Executable file
8
.gitignore
vendored
Normal file → Executable file
@@ -1,2 +1,10 @@
|
|||||||
|
!.changie.yaml
|
||||||
|
!.changes/**
|
||||||
|
|
||||||
dist/
|
dist/
|
||||||
|
.codegpt
|
||||||
|
|
||||||
|
*.log
|
||||||
|
/*.sh
|
||||||
|
/*.yaml
|
||||||
|
/*.yml
|
||||||
|
|||||||
7
.gitmodules
vendored
Executable file
7
.gitmodules
vendored
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
[submodule "docs/themes/hugo-theme-relearn"]
|
||||||
|
path = docs/themes/hugo-theme-relearn
|
||||||
|
url = https://github.com/McShelby/hugo-theme-relearn.git
|
||||||
|
|
||||||
|
[submodule "docs/themes/plausible-hugo"]
|
||||||
|
path = docs/themes/plausible-hugo
|
||||||
|
url = https://github.com/divinerites/plausible-hugo.git
|
||||||
43
.goreleaser/gitea.yml
Executable file
43
.goreleaser/gitea.yml
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
version: 2
|
||||||
|
before:
|
||||||
|
hooks:
|
||||||
|
# You may remove this if you don't use go modules.
|
||||||
|
- go mod tidy
|
||||||
|
builds:
|
||||||
|
- env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
goos:
|
||||||
|
- freebsd
|
||||||
|
- linux
|
||||||
|
goarch:
|
||||||
|
- "386"
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
|
||||||
|
archives:
|
||||||
|
- formats: tar.gz
|
||||||
|
# this name template makes the OS and Arch compatible with the results of uname.
|
||||||
|
name_template: >-
|
||||||
|
{{ .ProjectName }}_{{ .Version }}_
|
||||||
|
{{- title .Os }}_
|
||||||
|
{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
{{- if .Arm }}v{{ .Arm }}{{ end }}
|
||||||
|
# use zip for windows archives
|
||||||
|
format_overrides:
|
||||||
|
- goos: windows
|
||||||
|
formats: [zip]
|
||||||
|
checksum:
|
||||||
|
name_template: 'checksums.txt'
|
||||||
|
snapshot:
|
||||||
|
version_template: "{{ incpatch .Version }}-next"
|
||||||
|
changelog:
|
||||||
|
disable: false
|
||||||
|
|
||||||
|
gitea_urls:
|
||||||
|
api: https://git.andrewnw.xyz/api/v1
|
||||||
|
download: https://git.andrewnw.xyz
|
||||||
|
# The lines beneath this are called `modelines`. See `:help modeline`
|
||||||
|
# Feel free to remove those if you don't want/use them.
|
||||||
|
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||||
41
.goreleaser/github.yml
Executable file
41
.goreleaser/github.yml
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
# Make sure to check the documentation at https://goreleaser.com
|
||||||
|
version: 2
|
||||||
|
before:
|
||||||
|
hooks:
|
||||||
|
# You may remove this if you don't use go modules.
|
||||||
|
- go mod tidy
|
||||||
|
builds:
|
||||||
|
- env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
goos:
|
||||||
|
- freebsd
|
||||||
|
- linux
|
||||||
|
goarch:
|
||||||
|
- "386"
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
|
||||||
|
archives:
|
||||||
|
- formats: tar.gz
|
||||||
|
# this name template makes the OS and Arch compatible with the results of uname.
|
||||||
|
name_template: >-
|
||||||
|
{{ .ProjectName }}_{{ .Version }}_
|
||||||
|
{{- title .Os }}_
|
||||||
|
{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
{{- if .Arm }}v{{ .Arm }}{{ end }}
|
||||||
|
# use zip for windows archives
|
||||||
|
format_overrides:
|
||||||
|
- goos: windows
|
||||||
|
formats: [zip]
|
||||||
|
checksum:
|
||||||
|
name_template: 'checksums.txt'
|
||||||
|
snapshot:
|
||||||
|
version_template: "{{ incpatch .Version }}-next"
|
||||||
|
changelog:
|
||||||
|
sort: asc
|
||||||
|
filters:
|
||||||
|
exclude:
|
||||||
|
- '^docs:'
|
||||||
|
- '^test:'
|
||||||
8
.goreleaser.yaml → .goreleaser/vern.yml
Normal file → Executable file
8
.goreleaser.yaml → .goreleaser/vern.yml
Normal file → Executable file
@@ -1,5 +1,3 @@
|
|||||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
|
||||||
# Make sure to check the documentation at https://goreleaser.com
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
# You may remove this if you don't use go modules.
|
# You may remove this if you don't use go modules.
|
||||||
@@ -19,7 +17,7 @@ archives:
|
|||||||
- format: binary
|
- format: binary
|
||||||
# this name template makes the OS and Arch compatible with the results of uname.
|
# this name template makes the OS and Arch compatible with the results of uname.
|
||||||
name_template: >-
|
name_template: >-
|
||||||
{{ .ProjectName }}
|
{{ .ProjectName }}_{{ .Version }}_
|
||||||
{{- title .Os }}_
|
{{- title .Os }}_
|
||||||
{{- if eq .Arch "amd64" }}x86_64
|
{{- if eq .Arch "amd64" }}x86_64
|
||||||
{{- else if eq .Arch "386" }}i386
|
{{- else if eq .Arch "386" }}i386
|
||||||
@@ -41,8 +39,8 @@ changelog:
|
|||||||
- '^test:'
|
- '^test:'
|
||||||
|
|
||||||
gitea_urls:
|
gitea_urls:
|
||||||
api: https://git.andrewnw.xyz/api/v1
|
api: https://git.vern.cc/api/v1
|
||||||
download: https://git.andrewnw.xyz
|
download: https://git.vern.cc
|
||||||
# The lines beneath this are called `modelines`. See `:help modeline`
|
# The lines beneath this are called `modelines`. See `:help modeline`
|
||||||
# Feel free to remove those if you don't want/use them.
|
# Feel free to remove those if you don't want/use them.
|
||||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||||
13
.vscode/settings.json
vendored
Normal file → Executable file
13
.vscode/settings.json
vendored
Normal file → Executable file
@@ -1,5 +1,14 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"Cmds"
|
"Cmds",
|
||||||
]
|
"remotefetcher",
|
||||||
|
"knadh",
|
||||||
|
"koanf",
|
||||||
|
"mattn",
|
||||||
|
"maunium",
|
||||||
|
"mautrix",
|
||||||
|
"nikoksr",
|
||||||
|
"Strs"
|
||||||
|
],
|
||||||
|
"CodeGPT.apiKey": "CodeGPT Plus Beta"
|
||||||
}
|
}
|
||||||
19
.woodpecker/gitea.yml
Executable file
19
.woodpecker/gitea.yml
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
steps:
|
||||||
|
golang:
|
||||||
|
image: golang:1.23
|
||||||
|
commands:
|
||||||
|
- go install github.com/goreleaser/goreleaser/v2@v2.7.0
|
||||||
|
- goreleaser release -f .goreleaser/gitea.yml --release-notes=".changes/$(go run backy.go version -V).md"
|
||||||
|
environment:
|
||||||
|
GITEA_TOKEN:
|
||||||
|
from_secret: gitea_token
|
||||||
|
|
||||||
|
when:
|
||||||
|
event: tag
|
||||||
|
# release:
|
||||||
|
# image: goreleaser/goreleaser
|
||||||
|
# commands:
|
||||||
|
|
||||||
|
when:
|
||||||
|
- event: tag
|
||||||
|
branch: master
|
||||||
14
.woodpecker/go-lint.yml
Executable file
14
.woodpecker/go-lint.yml
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
steps:
|
||||||
|
build:
|
||||||
|
image: golang
|
||||||
|
commands:
|
||||||
|
- go build
|
||||||
|
- go test
|
||||||
|
release:
|
||||||
|
image: golangci/golangci-lint:v1.64.7
|
||||||
|
commands:
|
||||||
|
- golangci-lint run -v --timeout 5m
|
||||||
|
|
||||||
|
when:
|
||||||
|
- event: push
|
||||||
|
branch: develop
|
||||||
36
.woodpecker/publish-docs.yml
Executable file
36
.woodpecker/publish-docs.yml
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
steps:
|
||||||
|
build:
|
||||||
|
image: hugomods/hugo:debian-ci-0.147.2
|
||||||
|
commands:
|
||||||
|
- git submodule foreach 'git fetch origin; git checkout $(git describe --tags `git rev-list --tags --max-count=1`);'
|
||||||
|
- cd docs
|
||||||
|
- hugo mod get -u github.com/divinerites/plausible-hugo
|
||||||
|
- hugo mod get -u github.com/McShelby/hugo-theme-relearn@8.2.0
|
||||||
|
- hugo
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
image: codingkoopa/git-rsync-openssh
|
||||||
|
commands:
|
||||||
|
- cd docs
|
||||||
|
- echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||||
|
- mkdir ~/.ssh && chmod -R 700 ~/.ssh
|
||||||
|
# - apt update -y && apt install openssh-client rsync -y
|
||||||
|
- echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts
|
||||||
|
- echo -e '#!/bin/sh\necho "$SSH_PASSPHRASE"' | tr -d '\r' > ~/.ssh/.print_ssh_password
|
||||||
|
# - cat ~/.ssh/.print_ssh_password
|
||||||
|
- chmod 700 ~/.ssh/.print_ssh_password
|
||||||
|
- eval $(ssh-agent -s)
|
||||||
|
- echo "$SSH_DEPLOY_KEY" | tr -d '\r' | DISPLAY=":0.0" SSH_ASKPASS=~/.ssh/.print_ssh_password setsid ssh-add -
|
||||||
|
- rsync -atv --delete --progress public/ backy@backy.cybershell.xyz:docs
|
||||||
|
- rsync -atv --delete --progress vangen/ backy@backy.cybershell.xyz:vangen-go
|
||||||
|
environment:
|
||||||
|
SSH_HOST_KEY:
|
||||||
|
from_secret: ssh_host_key
|
||||||
|
SSH_DEPLOY_KEY:
|
||||||
|
from_secret: ssh_deploy_key
|
||||||
|
SSH_PASSPHRASE:
|
||||||
|
from_secret: ssh_passphrase
|
||||||
|
|
||||||
|
when:
|
||||||
|
- branch: master
|
||||||
|
- path: 'docs/**'
|
||||||
197
CHANGELOG.md
Executable file
197
CHANGELOG.md
Executable file
@@ -0,0 +1,197 @@
|
|||||||
|
# Changelog
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
||||||
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.11.0 - 2025-11-24
|
||||||
|
### Added
|
||||||
|
* feat: Package operation `versionCheck` supports regular expressions (see [regexp](https://pkg.go.dev/regexp) package for docs)
|
||||||
|
* Command lists: added `cmdLists.[name].notify` object
|
||||||
|
* Testing setup with Docker
|
||||||
|
* CLI: add global flag --hostsConfig that allows hosts to be dynamic in relation to the main config
|
||||||
|
* CLI: Exec subcommand `hosts`. See documentation for more details.
|
||||||
|
* CLI: added `exec hosts` subcommand `list`
|
||||||
|
* Add support for hosts in parallel
|
||||||
|
### Changed
|
||||||
|
* Commands: `host` can now be `localhost` or `127.0.0.1` to run commands locally
|
||||||
|
* lists loaded from external files only if no list config present in current file
|
||||||
|
* `PackageManager.Parse` renamed to `ParseRemotePackageManagerVersionOutput`. This now returns arrays of PackageManagerCommon.Package and errors.
|
||||||
|
* Internal: refactoring and renaming functions
|
||||||
|
* Commands: moved output-prefixed keys to the `commands.[name].output` object
|
||||||
|
* Change internal method name for better understanding
|
||||||
|
* Improved error message for remote version package output
|
||||||
|
### Fixed
|
||||||
|
* Command Lists: hooks now run correctly when commands finish
|
||||||
|
* Log file passed using `--log-file` correctly used
|
||||||
|
* Cmd Type `script` now correctly appends arguments
|
||||||
|
|
||||||
|
## v0.10.2 - 2025-03-19
|
||||||
|
### Added
|
||||||
|
* Notifications: http service added
|
||||||
|
* Variable support. Can be referenced with `%{var:nameOfVar}%` in select string fields.
|
||||||
|
### Changed
|
||||||
|
* vault: initialize vault before validating config
|
||||||
|
|
||||||
|
## v0.10.1 - 2025-03-11
|
||||||
|
### Added
|
||||||
|
* UserCommands: add ssh public keys when running locally
|
||||||
|
* UserCommands: add field CreateUserHome
|
||||||
|
### Changed
|
||||||
|
* UserCommands: create temp file when modifing password over SSH
|
||||||
|
* UserCommands: change field name
|
||||||
|
* Vault: keys are now referenced by `name`, and the actual data by `data`
|
||||||
|
|
||||||
|
## v0.10.0 - 2025-03-08
|
||||||
|
### Added
|
||||||
|
* Hooks: improved logging when executing
|
||||||
|
* User commands: adding SSH keys using config key `userSshPubKeys`
|
||||||
|
* directives: added support for fetching values using directive `%{externalSource:key}%`
|
||||||
|
### Changed
|
||||||
|
* Commands: if dir is not specified, run in config dir
|
||||||
|
* FileDirective: use the config directory if path is not absolute
|
||||||
|
* Host: changes to case of some keys
|
||||||
|
* Notifications: added external directive to sensitive keys
|
||||||
|
### Fixed
|
||||||
|
* LocalFetcher: return fetch error
|
||||||
|
* Lists: load file key before attempting to load from current file
|
||||||
|
* fix: host not in config file, but in ssh config, properly added to hosts struct
|
||||||
|
* SSH: password authentication bugs
|
||||||
|
* User commands: change user password works
|
||||||
|
|
||||||
|
## v0.9.1 - 2025-03-01
|
||||||
|
### Changed
|
||||||
|
* Use EnvVar AWS_PROFILE to get S3 profile
|
||||||
|
|
||||||
|
## v0.9.0 - 2025-02-28
|
||||||
|
### Added
|
||||||
|
* `list` command with subcommands `cmds` and `lists`
|
||||||
|
* Deprecation and unsupported warnings for old config keys
|
||||||
|
* CLI flag `--cmdStdOut` to output command's stdout/stderr to stdout
|
||||||
|
* Command type `remoteScript`. See docs for more info.
|
||||||
|
### Changed
|
||||||
|
* change to enums for Command type
|
||||||
|
* Cache now stores resources by URL hash for ease-of-lookup
|
||||||
|
* Changed PackageOperation to enums
|
||||||
|
### Fixed
|
||||||
|
* Local command's `dir` full path is now found with home directory
|
||||||
|
|
||||||
|
## v0.8.0 - 2025-02-15
|
||||||
|
### Changed
|
||||||
|
* Breaking: `cmd-lists` key changed to `cmdLists`
|
||||||
|
* Properly load list config
|
||||||
|
* Config file loading properly errors
|
||||||
|
* CI Configs
|
||||||
|
|
||||||
|
## v0.7.8 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* Github CI config
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
|
|
||||||
|
## v0.7.7 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
|
* CI configs
|
||||||
|
|
||||||
|
## v0.7.6 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
|
* CI configs
|
||||||
|
|
||||||
|
## v0.7.5 - 2025-02-14
|
||||||
|
### Changed
|
||||||
|
* CI configs
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
|
|
||||||
|
## v0.7.4 - 2025-02-14
|
||||||
|
### Changed
|
||||||
|
* CI configs
|
||||||
|
### Fixed
|
||||||
|
* v0.7.1: Incorrect local config file loading logic caused files to not be detected
|
||||||
|
|
||||||
|
## v0.7.3 - 2025-02-14
|
||||||
|
### Changed
|
||||||
|
* GoReleaser configs
|
||||||
|
|
||||||
|
## v0.7.2 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* CI configs
|
||||||
|
|
||||||
|
## v0.7.1 - 2025-02-14
|
||||||
|
### Fixed
|
||||||
|
* Incorrect local config file loading logic caused files to not be detected
|
||||||
|
|
||||||
|
## v0.7.0 - 2025-02-11
|
||||||
|
### Added
|
||||||
|
* [feat]: package `packageOperation` option `checkVersion` implemented
|
||||||
|
* user management added - see docs
|
||||||
|
* Support for remote config sources. Only config file and list can be used for now.
|
||||||
|
* Cache functionality - still a WIP
|
||||||
|
* Flag `--s3-endpoint` for config file fetching from S3
|
||||||
|
### Changed
|
||||||
|
* Internal refactoring of config setup
|
||||||
|
* Formatting and sending for notifications
|
||||||
|
* name of `configfetcher` to `remotefetcher`
|
||||||
|
* Flags that took comma-separated lists now have to be passed multiple times for each argument.
|
||||||
|
* Hosts passed to `exec host` now checked against default SSH config files
|
||||||
|
### Fixed
|
||||||
|
* Parsing of remote URLs when determining list config file path
|
||||||
|
* Incorrect error notification template value
|
||||||
|
|
||||||
|
## v0.6.1 - 2025-01-04
|
||||||
|
### Fixed
|
||||||
|
* When running a list, hooks now run explicitly after the command executes. Fixed panic due to improper logic.
|
||||||
|
## v0.6.0 - 2025-01-04
|
||||||
|
### Added
|
||||||
|
* Command Type Package - allows one to perform package operations [docs](https://backy.cybershell.xyz/config/packages/)
|
||||||
|
* Exec subcommand `host` allows for parallel execution of commands on hosts. [See docs](https://backy.cybershell.xyz/cli/exec)
|
||||||
|
|
||||||
|
## v0.5.0 - 2024-11-19
|
||||||
|
### Added
|
||||||
|
* Lists can now go in a file. See docs for more information.
|
||||||
|
* commands.[name].type: script now opens `scriptEnvFile`.
|
||||||
|
* Hooks for Commands.[name]. Error, success, and final. [#12]
|
||||||
|
### Changed
|
||||||
|
* GetKnownHosts is now a method of Host
|
||||||
|
### Fixed
|
||||||
|
* make command logger be used for errors, not just when running the command
|
||||||
|
|
||||||
|
## v0.4.0 - 2023-09-08
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Added `scriptEnvFile` to command object that allows one to specify an environment file (or any file really) when a `scriptFile` is run. Inspired by the practice of keeping environment variables and scripts or commands seperate.
|
||||||
|
* Basis for listing commands
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* BREAKING: Notifications object now takes the form of service.id, where service can be "mail" or "matrix" and id is a unique id for the service.
|
||||||
|
* BREAKING: Since the change to the notifications object, cmd-lists' inner map key 'notifications' must be of the form service.id. id must be defined for that service. See notifications docs for aviliable services.
|
||||||
|
* Config parser is now the simpler Koanf - Keys are now case-sensitive
|
||||||
|
* Log size limited to 50 Mb
|
||||||
|
|
||||||
|
## v0.3.1 - 2023-07-20
|
||||||
|
### Changed
|
||||||
|
* If an SSH session failed to be created, the command would fail. This would be caused when restarting the SSH host. The SSH connection is attempted to be created again. If successful, the command is executed normally.
|
||||||
|
|
||||||
|
## v0.3.0 - 2023-01-07
|
||||||
|
### Added
|
||||||
|
* Getting environment variables and passwords from Vault (not tested yet)
|
||||||
|
* Vault configuration to config (not tested yet)
|
||||||
|
* Ability to run scripts from file on local machine on the remote host
|
||||||
|
* Ability to get ouput in the notification of a list for individual commands or all commands
|
||||||
|
### Changed
|
||||||
|
* Make SSH connections close after all commands have been run; reuse previous connections if needed
|
||||||
|
|
||||||
|
## 0.2.4 - 2023-02-18
|
||||||
|
### Added
|
||||||
|
* Notifications now display errors and the output of the failed command.
|
||||||
|
* CI configs for GitHub and Woodpecker
|
||||||
|
* Added `version` subcommand
|
||||||
|
### Changed
|
||||||
|
* Console logging can be disabled by setting `console-disabled` in the `logging` object
|
||||||
|
## Fixed
|
||||||
|
* If Host was not defined for an incomplete `hosts` object, any commands would fail as they could not look up the values in the SSH config files.
|
||||||
5
Makefile
5
Makefile
@@ -1,5 +0,0 @@
|
|||||||
build:
|
|
||||||
go build
|
|
||||||
|
|
||||||
gorealeaser-build:
|
|
||||||
goreleaser release --snapshot --rm-dist
|
|
||||||
31
README.md
Normal file → Executable file
31
README.md
Normal file → Executable file
@@ -1,16 +1,11 @@
|
|||||||
|
|
||||||
# Backy - an application to manage backups
|
# Backy - an application to manage backups
|
||||||
|
|
||||||
This app is in development, and is currently not stable. Expect core functionality to possiblly break.
|
See the [install documentation](https://backy.cybershell.xyz/getting-started/install/index.html)
|
||||||
|
|
||||||
## Installing
|
## Security
|
||||||
|
|
||||||
To install:
|
The latest version is currently the only supported version.
|
||||||
|
|
||||||
`go install git.andrewnw.xyz/CyberShell/backy@master`
|
|
||||||
|
|
||||||
This assumes you already have a working Go environment, if not please see [this page](https://golang.org/doc/install) first.
|
|
||||||
|
|
||||||
You can also download binaries [here](https://git.andrewnw.xyz/CyberShell/backy/releases) and [here](https://github.com/CybersShell/backy/releases).
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -25,21 +20,3 @@ You can also download binaries [here](https://git.andrewnw.xyz/CyberShell/backy/
|
|||||||
- Run in cron mode
|
- Run in cron mode
|
||||||
|
|
||||||
- For any command, especially backup commands
|
- For any command, especially backup commands
|
||||||
|
|
||||||
To run a config:
|
|
||||||
|
|
||||||
`backy backup`
|
|
||||||
|
|
||||||
Or to use a specific file:
|
|
||||||
```backy backup -f /path/to/file```
|
|
||||||
|
|
||||||
If you leave the config path blank, the following paths will be searched in order:
|
|
||||||
|
|
||||||
- `./backy.yml`
|
|
||||||
- `./backy.yaml`
|
|
||||||
- `~/.config/backy.yml`
|
|
||||||
- `~/.config/backy.yaml`
|
|
||||||
|
|
||||||
Create a file at `~/.config/backy.yml`.
|
|
||||||
|
|
||||||
See the config file in the examples directory to configure it.
|
|
||||||
|
|||||||
27
backy.code-workspace
Executable file
27
backy.code-workspace
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"name": "backy",
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"cSpell.words": [
|
||||||
|
"Autorestic",
|
||||||
|
"changie",
|
||||||
|
"Cmds",
|
||||||
|
"CMDSTDOUT",
|
||||||
|
"goreleaser",
|
||||||
|
"knadh",
|
||||||
|
"koanf",
|
||||||
|
"mattn",
|
||||||
|
"maunium",
|
||||||
|
"mautrix",
|
||||||
|
"nikoksr",
|
||||||
|
"packagemanagercommon",
|
||||||
|
"rawbytes",
|
||||||
|
"remotefetcher",
|
||||||
|
"Strs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
3
cmd/.gitignore
vendored
Normal file → Executable file
3
cmd/.gitignore
vendored
Normal file → Executable file
@@ -1 +1,2 @@
|
|||||||
*.yaml
|
*.yaml
|
||||||
|
*.yml
|
||||||
29
cmd/backup.go
Normal file → Executable file
29
cmd/backup.go
Normal file → Executable file
@@ -12,11 +12,10 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
backupCmd = &cobra.Command{
|
backupCmd = &cobra.Command{
|
||||||
Use: "backup [--lists==list1,list2]",
|
Use: "backup [--lists=list1 --lists list2 ... | -l list1 -l list2 ...]",
|
||||||
Short: "Runs commands defined in config file.",
|
Short: "Runs commands defined in config file. Use -l flag multiple times to run multiple lists.",
|
||||||
Long: `Backup executes commands defined in config file.
|
Long: "Backup executes commands defined in config file.\nUse the --lists or -l flag to execute the specified lists. If not flag is not given, all lists will be executed.",
|
||||||
Use the --lists flag to execute the specified commands.`,
|
Run: Backup,
|
||||||
Run: Backup,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,14 +23,26 @@ var (
|
|||||||
var cmdLists []string
|
var cmdLists []string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
parseS3Config()
|
||||||
|
|
||||||
backupCmd.Flags().StringSliceVarP(&cmdLists, "lists", "l", nil, "Accepts comma-separated names of command lists to execute.")
|
backupCmd.Flags().StringArrayVarP(&cmdLists, "lists", "l", nil, "Accepts comma-separated names of command lists to execute.")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Backup(cmd *cobra.Command, args []string) {
|
func Backup(cmd *cobra.Command, args []string) {
|
||||||
backyConfOpts := backy.NewOpts(cfgFile, backy.AddCommandLists(cmdLists))
|
backyConfOpts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.AddCommandLists(cmdLists),
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.EnableCommandStdOut(cmdStdOut),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
|
||||||
backyConfOpts.InitConfig()
|
backyConfOpts.InitConfig()
|
||||||
config := backy.ReadConfig(backyConfOpts)
|
backyConfOpts.ParseConfigurationFile()
|
||||||
config.RunBackyConfig("")
|
|
||||||
|
backyConfOpts.RunListConfig("")
|
||||||
|
for _, host := range backyConfOpts.Hosts {
|
||||||
|
if host.SshClient != nil {
|
||||||
|
host.SshClient.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
cmd/backup_test.go
Executable file
54
cmd/backup_test.go
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "bufio"
|
||||||
|
// "encoding/json"
|
||||||
|
// "os"
|
||||||
|
// "os/exec"
|
||||||
|
// "strings"
|
||||||
|
// "testing"
|
||||||
|
|
||||||
|
// "github.com/stretchr/testify/assert"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// // TestConfigOptions tests the configuration options for the backy package.
|
||||||
|
// func Test_ErrorHook(t *testing.T) {
|
||||||
|
// configFile := "-f ../../tests/ErrorHook.yml"
|
||||||
|
// logFile := "--log-file=ErrorHook.log"
|
||||||
|
// backyCommand := exec.Command("go", "run", "../../backy.go", configFile, logFile, "backup")
|
||||||
|
// backyCommand.Stderr = os.Stdout
|
||||||
|
// backyCommand.Stdout = os.Stdout
|
||||||
|
// err := backyCommand.Run()
|
||||||
|
// assert.Nil(t, err)
|
||||||
|
// os.Remove("ErrorHook.log")
|
||||||
|
// logFileData, logFileErr := os.ReadFile("ErrorHook.log")
|
||||||
|
// if logFileErr != nil {
|
||||||
|
// assert.FailNow(t, logFileErr.Error())
|
||||||
|
|
||||||
|
// }
|
||||||
|
// var JsonData []map[string]interface{}
|
||||||
|
// jsonScanner := bufio.NewScanner(strings.NewReader(string(logFileData)))
|
||||||
|
|
||||||
|
// for jsonScanner.Scan() {
|
||||||
|
// var jsonDataLine map[string]interface{}
|
||||||
|
// err = json.Unmarshal(jsonScanner.Bytes(), &jsonDataLine)
|
||||||
|
// assert.Nil(t, err)
|
||||||
|
// JsonData = append(JsonData, jsonDataLine)
|
||||||
|
// }
|
||||||
|
// for _, v := range JsonData {
|
||||||
|
// _, ok := v["error"]
|
||||||
|
// if !ok {
|
||||||
|
// assert.FailNow(t, "error does not exist\n")
|
||||||
|
// // return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // t.Logf("%s", logFileData)
|
||||||
|
// // t.Logf("%v", JsonData)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestBackupErrorHook(t *testing.T) {
|
||||||
|
// logFile = "ErrorHook.log"
|
||||||
|
|
||||||
|
// configFile = "../tests/ErrorHook.yml"
|
||||||
|
|
||||||
|
// }
|
||||||
2
cmd/config.go
Normal file → Executable file
2
cmd/config.go
Normal file → Executable file
@@ -20,7 +20,7 @@ package cmd
|
|||||||
|
|
||||||
// func config(cmd *cobra.Command, args []string) {
|
// func config(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
// opts := backy.NewOpts(cfgFile, backy.UseCron())
|
// opts := backy.NewConfigOptions(configFile, backy.cronEnabled())
|
||||||
// opts.InitConfig()
|
// opts.InitConfig()
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|||||||
17
cmd/cron.go
Normal file → Executable file
17
cmd/cron.go
Normal file → Executable file
@@ -8,17 +8,24 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
cronCmd = &cobra.Command{
|
cronCmd = &cobra.Command{
|
||||||
Use: "cron command ...",
|
Use: "cron [flags]",
|
||||||
Short: "Runs commands defined in config file.",
|
Short: "Starts a scheduler that runs lists defined in config file.",
|
||||||
Long: `Cron executes commands at the time defined in config file.`,
|
Long: `Cron starts a scheduler that executes command lists at the time defined in config file.`,
|
||||||
Run: cron,
|
Run: cron,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func cron(cmd *cobra.Command, args []string) {
|
func cron(cmd *cobra.Command, args []string) {
|
||||||
|
parseS3Config()
|
||||||
|
|
||||||
|
opts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.EnableCron(),
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.EnableCommandStdOut(cmdStdOut),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
|
||||||
opts := backy.NewOpts(cfgFile, backy.UseCron())
|
|
||||||
opts.InitConfig()
|
opts.InitConfig()
|
||||||
|
opts.ParseConfigurationFile()
|
||||||
|
|
||||||
backy.ReadConfig(opts).Cron()
|
opts.Cron()
|
||||||
}
|
}
|
||||||
|
|||||||
33
cmd/exec.go
Normal file → Executable file
33
cmd/exec.go
Normal file → Executable file
@@ -14,21 +14,30 @@ import (
|
|||||||
var (
|
var (
|
||||||
execCmd = &cobra.Command{
|
execCmd = &cobra.Command{
|
||||||
Use: "exec command ...",
|
Use: "exec command ...",
|
||||||
Short: "Runs commands defined in config file.",
|
Short: "Runs commands defined in config file in order given.",
|
||||||
Long: `Exec executes commands defined in config file.`,
|
Long: `Exec executes commands defined in config file in order given.`,
|
||||||
Run: execute,
|
Run: execute,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func execute(cmd *cobra.Command, args []string) {
|
func init() {
|
||||||
|
execCmd.AddCommand(hostExecCommand, hostsExecCommand)
|
||||||
if len(args) < 1 {
|
|
||||||
logging.ExitWithMSG("Please provide a command to run. Pass --help to see options.", 0, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := backy.NewOpts(cfgFile, backy.AddCommands(args))
|
|
||||||
opts.InitConfig()
|
|
||||||
// opts.InitMongo()
|
|
||||||
backy.ReadConfig(opts).ExecuteCmds()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func execute(cmd *cobra.Command, args []string) {
|
||||||
|
parseS3Config()
|
||||||
|
|
||||||
|
if len(args) < 1 {
|
||||||
|
logging.ExitWithMSG("Please provide a command to run. Pass --help to see options.", 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.AddCommands(args),
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.EnableCommandStdOut(cmdStdOut),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
opts.InitConfig()
|
||||||
|
opts.ParseConfigurationFile()
|
||||||
|
opts.ExecuteCmds()
|
||||||
|
}
|
||||||
|
|||||||
81
cmd/host.go
Executable file
81
cmd/host.go
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/backy"
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
hostExecCommand = &cobra.Command{
|
||||||
|
Use: "host [--command=command1 --command=command2 ... | -c command1 -c command2 ...] [--hosts=host1 --hosts=hosts2 ... | -m host1 -m host2 ...] ",
|
||||||
|
Short: "Runs command defined in config file on the hosts in order specified.",
|
||||||
|
Long: "Host executes specified commands on the hosts defined in config file.\nUse the --commands or -c flag to choose the commands.",
|
||||||
|
Run: Host,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Holds list of hosts to run commands on
|
||||||
|
var hostsList []string
|
||||||
|
|
||||||
|
// Holds command list to run
|
||||||
|
var cmdList []string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
hostExecCommand.Flags().StringArrayVarP(&hostsList, "hosts", "m", nil, "Accepts space-separated names of hosts. Specify multiple times for multiple hosts.")
|
||||||
|
hostExecCommand.Flags().StringArrayVarP(&cmdList, "command", "c", nil, "Accepts space-separated names of commands. Specify multiple times for multiple commands.")
|
||||||
|
parseS3Config()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// cli input should be hosts and commands. Hosts are defined in config files.
|
||||||
|
// commands can be passed by the following mutually exclusive options:
|
||||||
|
// 1. as a list of commands defined in the config file
|
||||||
|
// 2. stdin (on command line) (TODO)
|
||||||
|
|
||||||
|
func Host(cmd *cobra.Command, args []string) {
|
||||||
|
backyConfOpts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.EnableCommandStdOut(cmdStdOut),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
backyConfOpts.InitConfig()
|
||||||
|
|
||||||
|
backyConfOpts.ParseConfigurationFile()
|
||||||
|
|
||||||
|
// check CLI input
|
||||||
|
if hostsList == nil {
|
||||||
|
logging.ExitWithMSG("error: hosts must be specified", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range hostsList {
|
||||||
|
if backy.IsHostLocal(h) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// check if h exists in the config file
|
||||||
|
_, hostFound := backyConfOpts.Hosts[h]
|
||||||
|
if !hostFound {
|
||||||
|
// check if h exists in the SSH config file
|
||||||
|
hostFoundInConfig, s := backy.DoesHostHaveHostName(h)
|
||||||
|
if !hostFoundInConfig {
|
||||||
|
logging.ExitWithMSG("host "+h+" not found", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
if backyConfOpts.Hosts == nil {
|
||||||
|
backyConfOpts.Hosts = make(map[string]*backy.Host)
|
||||||
|
}
|
||||||
|
// create host with hostname and host
|
||||||
|
backyConfOpts.Hosts[h] = &backy.Host{Host: h, HostName: s}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cmdList == nil {
|
||||||
|
logging.ExitWithMSG("error: commands must be specified", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
for _, c := range cmdList {
|
||||||
|
_, cmdFound := backyConfOpts.Cmds[c]
|
||||||
|
if !cmdFound {
|
||||||
|
logging.ExitWithMSG("cmd "+c+" not found", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backyConfOpts.ExecCmdsOnHosts(cmdList, hostsList)
|
||||||
|
}
|
||||||
93
cmd/hosts.go
Executable file
93
cmd/hosts.go
Executable file
@@ -0,0 +1,93 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"maps"
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/backy"
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
runCommandsInParallel bool
|
||||||
|
|
||||||
|
hostsExecCommand = &cobra.Command{
|
||||||
|
Use: "hosts [--command=command1 --command=command2 ... | -c command1 -c command2 ...]",
|
||||||
|
Short: "Runs command defined in config file on the hosts in order specified.",
|
||||||
|
Long: "Hosts executes specified commands on all the hosts defined in config file.\nUse the --commands or -c flag to choose the commands.",
|
||||||
|
Run: Hosts,
|
||||||
|
}
|
||||||
|
|
||||||
|
hostsListExecCommand = &cobra.Command{
|
||||||
|
Use: "list list1 list2 ...",
|
||||||
|
Short: "Runs lists in order specified defined in config file on all hosts.",
|
||||||
|
Long: "Lists executes specified lists on all the hosts defined in hosts config.\nPass the names of lists as arguments after command.",
|
||||||
|
Run: HostsList,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
hostsExecCommand.AddCommand(hostsListExecCommand)
|
||||||
|
hostsListExecCommand.Flags().BoolVarP(&runCommandsInParallel, "parallel", "p", false, "Run commands in parallel on hosts")
|
||||||
|
parseS3Config()
|
||||||
|
}
|
||||||
|
|
||||||
|
// cli input should be hosts and commands. Hosts are defined in config files.
|
||||||
|
// commands can be passed by the following mutually exclusive options:
|
||||||
|
// 1. as a list of commands defined in the config file
|
||||||
|
// 2. stdin (on command line) (TODO)
|
||||||
|
|
||||||
|
func Hosts(cmd *cobra.Command, args []string) {
|
||||||
|
backyConfOpts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.EnableCommandStdOut(cmdStdOut),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
backyConfOpts.InitConfig()
|
||||||
|
|
||||||
|
backyConfOpts.ParseConfigurationFile()
|
||||||
|
|
||||||
|
for _, h := range backyConfOpts.Hosts {
|
||||||
|
|
||||||
|
hostsList = append(hostsList, h.Host)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmdList == nil {
|
||||||
|
logging.ExitWithMSG("error: commands must be specified", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
for _, c := range cmdList {
|
||||||
|
_, cmdFound := backyConfOpts.Cmds[c]
|
||||||
|
if !cmdFound {
|
||||||
|
logging.ExitWithMSG("cmd "+c+" not found", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backyConfOpts.ExecCmdsOnHosts(cmdList, hostsList)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HostsList(cmd *cobra.Command, args []string) {
|
||||||
|
backyConfOpts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.EnableCommandStdOut(cmdStdOut),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
backyConfOpts.InitConfig()
|
||||||
|
|
||||||
|
backyConfOpts.ParseConfigurationFile()
|
||||||
|
|
||||||
|
if len(args) == 0 {
|
||||||
|
logging.ExitWithMSG("error: no lists specified", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range args {
|
||||||
|
_, listFound := backyConfOpts.CmdConfigLists[l]
|
||||||
|
if !listFound {
|
||||||
|
logging.ExitWithMSG("list "+l+" not found", 1, &backyConfOpts.Logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maps.DeleteFunc(backyConfOpts.CmdConfigLists, func(k string, v *backy.CmdList) bool {
|
||||||
|
return !slices.Contains(args, k)
|
||||||
|
})
|
||||||
|
|
||||||
|
backyConfOpts.ExecuteListOnHosts(args, runCommandsInParallel)
|
||||||
|
}
|
||||||
90
cmd/list.go
Executable file
90
cmd/list.go
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
// backup.go
|
||||||
|
// Copyright (C) Andrew Woodlee 2023
|
||||||
|
// License: Apache-2.0
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/backy"
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
listCmd = &cobra.Command{
|
||||||
|
Use: "list [command]",
|
||||||
|
Short: "List commands, lists, or hosts defined in config file.",
|
||||||
|
Long: "List commands, lists, or hosts defined in config file",
|
||||||
|
}
|
||||||
|
|
||||||
|
listCmds = &cobra.Command{
|
||||||
|
Use: "cmds [cmd1 cmd2 cmd3...]",
|
||||||
|
Short: "List commands defined in config file.",
|
||||||
|
Long: "List commands defined in config file",
|
||||||
|
Run: ListCommands,
|
||||||
|
}
|
||||||
|
listCmdLists = &cobra.Command{
|
||||||
|
Use: "lists [list1 list2 ...]",
|
||||||
|
Short: "List lists defined in config file.",
|
||||||
|
Long: "List lists defined in config file",
|
||||||
|
Run: ListCommandLists,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var listsToList []string
|
||||||
|
var cmdsToList []string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
listCmd.AddCommand(listCmds, listCmdLists)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListCommands(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
|
// setup based on whats passed in:
|
||||||
|
// - cmds
|
||||||
|
// - lists
|
||||||
|
// - if none, list all commands
|
||||||
|
if len(args) > 0 {
|
||||||
|
cmdsToList = args
|
||||||
|
} else {
|
||||||
|
logging.ExitWithMSG("Error: list cmds subcommand needs commands to list", 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
parseS3Config()
|
||||||
|
|
||||||
|
opts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
|
||||||
|
opts.InitConfig()
|
||||||
|
opts.ParseConfigurationFile()
|
||||||
|
|
||||||
|
for _, v := range cmdsToList {
|
||||||
|
opts.ListCommand(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListCommandLists(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
|
parseS3Config()
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
listsToList = args
|
||||||
|
} else {
|
||||||
|
logging.ExitWithMSG("Error: lists subcommand needs lists", 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := backy.NewConfigOptions(configFile,
|
||||||
|
backy.SetLogFile(logFile),
|
||||||
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
|
|
||||||
|
opts.InitConfig()
|
||||||
|
opts.ParseConfigurationFile()
|
||||||
|
|
||||||
|
for _, v := range listsToList {
|
||||||
|
opts.ListCommandList(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
cmd/root.go
Normal file → Executable file
23
cmd/root.go
Normal file → Executable file
@@ -13,8 +13,12 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// Used for flags.
|
// Used for flags.
|
||||||
cfgFile string
|
configFile string
|
||||||
verbose bool
|
hostsConfigFile string
|
||||||
|
verbose bool
|
||||||
|
cmdStdOut bool
|
||||||
|
logFile string
|
||||||
|
s3Endpoint string
|
||||||
|
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "backy",
|
Use: "backy",
|
||||||
@@ -32,9 +36,18 @@ func Execute() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
rootCmd.PersistentFlags().StringVar(&logFile, "logFile", "", "log file to write to")
|
||||||
|
rootCmd.PersistentFlags().BoolVar(&cmdStdOut, "cmdStdOut", false, "Pass to print command output to stdout")
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "f", "", "config file to read from")
|
rootCmd.PersistentFlags().StringVarP(&configFile, "config", "f", "", "config file to read from")
|
||||||
|
rootCmd.PersistentFlags().StringVar(&hostsConfigFile, "hostsConfig", "", "yaml hosts file to read from")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Sets verbose level")
|
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Sets verbose level")
|
||||||
|
rootCmd.PersistentFlags().StringVar(&s3Endpoint, "s3Endpoint", "", "Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.")
|
||||||
rootCmd.AddCommand(backupCmd, execCmd, cronCmd)
|
rootCmd.AddCommand(backupCmd, execCmd, cronCmd, versionCmd, listCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseS3Config() {
|
||||||
|
if s3Endpoint != "" {
|
||||||
|
os.Setenv("S3_ENDPOINT", s3Endpoint)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
cmd/version.go
Executable file
39
cmd/version.go
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
const versionStr = "0.11.0"
|
||||||
|
|
||||||
|
var (
|
||||||
|
versionCmd = &cobra.Command{
|
||||||
|
Use: "version [flags]",
|
||||||
|
Short: "Prints the version and exits",
|
||||||
|
Long: "Prints the version and exits. No arguments just prints the version number only.",
|
||||||
|
Run: version,
|
||||||
|
}
|
||||||
|
numOnly bool
|
||||||
|
vPre bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
versionCmd.PersistentFlags().BoolVarP(&numOnly, "num", "n", false, "Output the version number only.")
|
||||||
|
versionCmd.PersistentFlags().BoolVarP(&vPre, "vpre", "V", false, "Output the version with v prefixed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func version(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
|
if numOnly && !vPre {
|
||||||
|
fmt.Printf("%s\n", versionStr)
|
||||||
|
} else if vPre && !numOnly {
|
||||||
|
fmt.Printf("v%s\n", versionStr)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Backy version: %s\n", versionStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
2
docs/.gitignore
vendored
Executable file
2
docs/.gitignore
vendored
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
public/
|
||||||
|
resources/_gen
|
||||||
0
docs/.hugo_build.lock
Executable file
0
docs/.hugo_build.lock
Executable file
6
docs/archetypes/default.md
Executable file
6
docs/archetypes/default.md
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "{{ replace .Name "-" " " | title }}"
|
||||||
|
date: {{ .Date }}
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
||||||
79
docs/config.yaml
Executable file
79
docs/config.yaml
Executable file
@@ -0,0 +1,79 @@
|
|||||||
|
baseURL: https://backy.cybershell.xyz/
|
||||||
|
languageCode: en-us
|
||||||
|
title: A tool for commands
|
||||||
|
theme:
|
||||||
|
- hugo-theme-relearn
|
||||||
|
- plausible-hugo
|
||||||
|
outputs:
|
||||||
|
home:
|
||||||
|
- HTML
|
||||||
|
- RSS
|
||||||
|
- PRINT
|
||||||
|
module:
|
||||||
|
imports:
|
||||||
|
- path: github.com/divinerites/plausible-hugo
|
||||||
|
- path: github.com/McShelby/hugo-theme-relearn
|
||||||
|
version: "v8.2.0"
|
||||||
|
params:
|
||||||
|
themeVariant:
|
||||||
|
- auto: []
|
||||||
|
identifier: relearn-auto
|
||||||
|
name: Relearn Light/Dark
|
||||||
|
- identifier: relearn-light
|
||||||
|
- identifier: relearn-dark
|
||||||
|
- identifier: relearn-bright
|
||||||
|
- auto:
|
||||||
|
- zen-light
|
||||||
|
- zen-dark
|
||||||
|
identifier: zen-auto
|
||||||
|
name: Zen Light/Dark
|
||||||
|
- identifier: zen-light
|
||||||
|
- identifier: zen-dark
|
||||||
|
- auto:
|
||||||
|
- learn
|
||||||
|
- neon
|
||||||
|
identifier: retro-auto
|
||||||
|
name: Retro Learn/Neon
|
||||||
|
- identifier: neon
|
||||||
|
- identifier: learn
|
||||||
|
plausible:
|
||||||
|
enable: true
|
||||||
|
domain: backy.cybershell.xyz
|
||||||
|
outbound_link: true
|
||||||
|
gitstar: false
|
||||||
|
selfhosted_domain: stats.andrewnw.com
|
||||||
|
author:
|
||||||
|
name: Andrew Woodlee
|
||||||
|
alwaysopen: false
|
||||||
|
editURL: ""
|
||||||
|
description: ""
|
||||||
|
showVisitedLinks: false
|
||||||
|
disableSearch: false
|
||||||
|
disableSearchHiddenPages: false
|
||||||
|
disableSeoHiddenPages: false
|
||||||
|
disableTagHiddenPages: false
|
||||||
|
disableAssetsBusting: false
|
||||||
|
disableGeneratorVersion: false
|
||||||
|
disableInlineCopyToClipBoard: false
|
||||||
|
disableShortcutsTitle: false
|
||||||
|
disableLandingPageButton: true
|
||||||
|
disableLanguageSwitchingButton: false
|
||||||
|
disableBreadcrumb: true
|
||||||
|
disableToc: false
|
||||||
|
math: true
|
||||||
|
customMathJaxURL: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
|
||||||
|
mathJaxInitialize: "{}"
|
||||||
|
mermaid: true
|
||||||
|
customMermaidURL: https://unpkg.com/mermaid/dist/mermaid.min.js
|
||||||
|
mermaidInitialize: '{ "theme": "default" }'
|
||||||
|
disableSwagger: false
|
||||||
|
customSwaggerURL: https://unpkg.com/rapidoc/dist/rapidoc-min.js
|
||||||
|
swaggerInitialize: '{ "theme": "light" }'
|
||||||
|
disableNextPrev: true
|
||||||
|
ordersectionsby: weight
|
||||||
|
titleSeparator: "-"
|
||||||
|
collapsibleMenu: true
|
||||||
|
additionalContentLanguage:
|
||||||
|
- en
|
||||||
|
disableExplicitIndexURLs: false
|
||||||
|
externalLinkTarget: _blank
|
||||||
32
docs/content/_index.md
Executable file
32
docs/content/_index.md
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
+++
|
||||||
|
archetype = "home"
|
||||||
|
title = "Backy"
|
||||||
|
+++
|
||||||
|
|
||||||
|
Backy is a tool for automating data backup and remote command execution. It can work over SSH, and provides completion and failure notifications, error reporting, and more.
|
||||||
|
|
||||||
|
Why the name Backy? Because I wanted an app for backups.
|
||||||
|
|
||||||
|
View the [changelog here](https://git.andrewnw.xyz/CyberShell/backy/src/branch/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
{{% notice tip %}}
|
||||||
|
Feel free to open a [PR](https://git.andrewnw.xyz/CyberShell/backy/pulls), raise an [issue](https://git.andrewnw.xyz/CyberShell/backy/issues "Open a Gitea Issue")(s), or request new feature(s).
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Allows easy configuration of executable commands
|
||||||
|
|
||||||
|
- Allows for running package operations
|
||||||
|
|
||||||
|
- Allows configuring failure, success, and final hooks
|
||||||
|
|
||||||
|
- Allows for commands to be run on many hosts over SSH
|
||||||
|
|
||||||
|
- Commands can be grouped in list to run in specific order
|
||||||
|
|
||||||
|
- Notifications on completion and failure
|
||||||
|
|
||||||
|
- Run in cron mode
|
||||||
|
|
||||||
|
- For any command, especially backup commands
|
||||||
215
docs/content/cli/_index.md
Normal file
215
docs/content/cli/_index.md
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
---
|
||||||
|
title: CLI
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
This page lists documentation for the CLI.
|
||||||
|
|
||||||
|
## Backy
|
||||||
|
|
||||||
|
```
|
||||||
|
Backy is a command-line application useful for configuring backups, or any commands run in sequence.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy [command]
|
||||||
|
|
||||||
|
Available Commands:
|
||||||
|
backup Runs commands defined in config file. Use -l flag multiple times to run multiple lists.
|
||||||
|
completion Generate the autocompletion script for the specified shell
|
||||||
|
cron Starts a scheduler that runs lists defined in config file.
|
||||||
|
exec Runs commands defined in config file in order given.
|
||||||
|
help Help about any command
|
||||||
|
list List commands, lists, or hosts defined in config file.
|
||||||
|
version Prints the version and exits
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
-h, --help help for backy
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
|
||||||
|
Use "backy [command] --help" for more information about a command.
|
||||||
|
```
|
||||||
|
|
||||||
|
# Subcommands
|
||||||
|
|
||||||
|
## backup
|
||||||
|
|
||||||
|
```
|
||||||
|
Backup executes commands defined in config file.
|
||||||
|
Use the --lists or -l flag to execute the specified lists. If not flag is not given, all lists will be executed.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy backup [--lists=list1 --lists list2 ... | -l list1 -l list2 ...] [flags]
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for backup
|
||||||
|
-l, --lists stringArray Accepts comma-separated names of command lists to execute.
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
```
|
||||||
|
|
||||||
|
## cron
|
||||||
|
|
||||||
|
```
|
||||||
|
Cron starts a scheduler that executes command lists at the time defined in config file.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy cron [flags]
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for cron
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
```
|
||||||
|
|
||||||
|
## exec
|
||||||
|
|
||||||
|
```
|
||||||
|
Exec executes commands defined in config file in order given.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy exec command ... [flags]
|
||||||
|
backy exec [command]
|
||||||
|
|
||||||
|
Available Commands:
|
||||||
|
host Runs command defined in config file on the hosts in order specified.
|
||||||
|
hosts Runs command defined in config file on the hosts in order specified.
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for exec
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
|
||||||
|
Use "backy exec [command] --help" for more information about a command.
|
||||||
|
```
|
||||||
|
|
||||||
|
### exec host
|
||||||
|
|
||||||
|
```
|
||||||
|
Host executes specified commands on the hosts defined in config file.
|
||||||
|
Use the --commands or -c flag to choose the commands.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy exec host [--command=command1 --command=command2 ... | -c command1 -c command2 ...] [--hosts=host1 --hosts=hosts2 ... | -m host1 -m host2 ...] [flags]
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-c, --command stringArray Accepts space-separated names of commands. Specify multiple times for multiple commands.
|
||||||
|
-h, --help help for host
|
||||||
|
-m, --hosts stringArray Accepts space-separated names of hosts. Specify multiple times for multiple hosts.
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
```
|
||||||
|
|
||||||
|
## version
|
||||||
|
|
||||||
|
```
|
||||||
|
Prints the version and exits. No arguments just prints the version number only.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy version [flags]
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for version
|
||||||
|
-n, --num Output the version number only.
|
||||||
|
-V, --vpre Output the version with v prefixed.
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
```
|
||||||
|
|
||||||
|
## list
|
||||||
|
|
||||||
|
```
|
||||||
|
List commands, lists, or hosts defined in config file
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy list [command]
|
||||||
|
|
||||||
|
Available Commands:
|
||||||
|
cmds List commands defined in config file.
|
||||||
|
lists List lists defined in config file.
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for list
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
|
||||||
|
Use "backy list [command] --help" for more information about a command.
|
||||||
|
```
|
||||||
|
## list cmds
|
||||||
|
|
||||||
|
```
|
||||||
|
List commands defined in config file
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy list cmds [cmd1 cmd2 cmd3...] [flags]
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for cmds
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
```
|
||||||
|
## list lists
|
||||||
|
|
||||||
|
```
|
||||||
|
List lists defined in config file
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
backy list lists [list1 list2 ...] [flags]
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for lists
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--hostsConfig string yaml hosts file to read from
|
||||||
|
--logFile string log file to write to
|
||||||
|
--s3Endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
```
|
||||||
19
docs/content/cli/exec.md
Executable file
19
docs/content/cli/exec.md
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
title: Exec
|
||||||
|
---
|
||||||
|
|
||||||
|
The `exec` subcommand can do some things that the configuration file can't do yet. The command `exec host` can execute commands on many hosts.
|
||||||
|
|
||||||
|
`exec host` takes the following arguments:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
-c, --commands strings Accepts space-separated names of commands.
|
||||||
|
-h, --help help for host
|
||||||
|
-m, --hosts strings Accepts space-separated names of hosts.
|
||||||
|
```
|
||||||
|
|
||||||
|
The commands have to be defined in the config file. The hosts need to at least be in the ssh_config(5) file.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
backy exec host [--commands=command1 -commands=command2 ... | -c command1 -c command2 ...] [--hosts=host1 --hosts=hosts2 ... | -m host1 -m host2 ...] [flags]
|
||||||
|
```
|
||||||
29
docs/content/cli/list.md
Executable file
29
docs/content/cli/list.md
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
title: List
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
List commands, lists, or hosts defined in config file
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
```
|
||||||
|
backy list [command]
|
||||||
|
```
|
||||||
|
|
||||||
|
Available Commands:
|
||||||
|
cmds List commands defined in config file.
|
||||||
|
lists List lists defined in config file.
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
```
|
||||||
|
-h, --help help for list
|
||||||
|
```
|
||||||
|
|
||||||
|
Global Flags:
|
||||||
|
```
|
||||||
|
--cmdStdOut Pass to print command output to stdout
|
||||||
|
-f, --config string config file to read from
|
||||||
|
--log-file string log file to write to
|
||||||
|
--s3-endpoint string Sets the S3 endpoint used for config file fetching. Overrides S3_ENDPOINT env variable.
|
||||||
|
-v, --verbose Sets verbose level
|
||||||
|
```
|
||||||
40
docs/content/config/_index.md
Executable file
40
docs/content/config/_index.md
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
title: "Configuring Backy"
|
||||||
|
weight: 3
|
||||||
|
description: >
|
||||||
|
This page tells you how to configure Backy.
|
||||||
|
---
|
||||||
|
|
||||||
|
This is the section on the config file.
|
||||||
|
|
||||||
|
To use a specific file:
|
||||||
|
```backy [command] -f /path/to/file```
|
||||||
|
|
||||||
|
You can also use a remote file:
|
||||||
|
```
|
||||||
|
backy [command] -f `s3/http source`
|
||||||
|
```
|
||||||
|
|
||||||
|
See remote resources docs for specific info.
|
||||||
|
|
||||||
|
If you leave the config path blank, the following paths will be searched in order:
|
||||||
|
|
||||||
|
1. `./backy.yml`
|
||||||
|
2. `./backy.yaml`
|
||||||
|
3. The same two files above contained in a `backy` subdirectory under in what is returned by Go's `os` package function `UserConfigDir()`.
|
||||||
|
|
||||||
|
{{% expand title="`UserConfigDir()` documentation:" %}}
|
||||||
|
|
||||||
|
Up-to date documentation for this function may be found on [GoDoc](https://pkg.go.dev/os#UserConfigDir).
|
||||||
|
|
||||||
|
>UserConfigDir returns the default root directory to use for user-specific configuration data. Users should create their own application-specific subdirectory within this one and use that.
|
||||||
|
|
||||||
|
>On Unix systems, it returns $XDG_CONFIG_HOME as specified by https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if non-empty, else $HOME/.config. On Darwin, it returns $HOME/Library/Application Support. On Windows, it returns %AppData%. On Plan 9, it returns $home/lib.
|
||||||
|
|
||||||
|
>If the location cannot be determined (for example, $HOME is not defined), then it will return an error.
|
||||||
|
|
||||||
|
{{% /expand %}}
|
||||||
|
|
||||||
|
See the rest of the documentation, titles included below, in this section to configure it.
|
||||||
|
|
||||||
|
{{% children description="true" %}}
|
||||||
99
docs/content/config/command-lists.md
Executable file
99
docs/content/config/command-lists.md
Executable file
@@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
title: "Command Lists"
|
||||||
|
weight: 2
|
||||||
|
description: >
|
||||||
|
This page tells you how to use command lists.
|
||||||
|
---
|
||||||
|
|
||||||
|
Command lists are for executing commands in sequence and getting notifications from them.
|
||||||
|
|
||||||
|
The top-level object key can be anything you want but not the same as another.
|
||||||
|
|
||||||
|
Lists can go in a separate file. Command lists should be in a separate file if:
|
||||||
|
|
||||||
|
1. key 'cmdLists.file' is specified
|
||||||
|
2. lists.yml or lists.yaml is found in the same directory as the backy config file (this includes remote config files as of v0.7.0)
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
The lists file is also checked in remote resources.
|
||||||
|
|
||||||
|
The lists file is ignored under the following condition:
|
||||||
|
|
||||||
|
If a remote config file is specified (on the command-line using `-f`) and the lists file is not found in the same directory, the lists file is assumed to not exist.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
```yaml {lineNos="true" wrap="true" title="yaml"}
|
||||||
|
test2:
|
||||||
|
name: test2
|
||||||
|
order:
|
||||||
|
- test
|
||||||
|
- test2
|
||||||
|
notifications:
|
||||||
|
- mail.prod-email
|
||||||
|
- matrix.sysadmin
|
||||||
|
cron: "0 * * * * *"
|
||||||
|
```
|
||||||
|
|
||||||
|
| key | description | type | required
|
||||||
|
| --- | --- | --- | ---
|
||||||
|
| `order` | Defines the sequence of commands to execute | `[]string` | yes
|
||||||
|
| `sendNotificationOnSuccess` | Whether to send notification on list success with the commands' output | `bool` | no
|
||||||
|
| `notifications` | The notification service(s) and ID(s) to use on success and failure. Must be *`service.id`*. See the [notifications documentation page](/config/notifications/) for more | `[]string` | no
|
||||||
|
| `name` | Optional name of the list | `string` | no
|
||||||
|
| `cron` | Time at which to schedule the list. Only has affect when cron subcommand is run. | `string` | no
|
||||||
|
|
||||||
|
### Order
|
||||||
|
|
||||||
|
The order is an array of commands to execute in order. Each command must be defined.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
order:
|
||||||
|
- cmd-1
|
||||||
|
- cmd-2
|
||||||
|
```
|
||||||
|
|
||||||
|
### getOutput
|
||||||
|
|
||||||
|
Get command output when a notification is sent.
|
||||||
|
|
||||||
|
Is not required. Can be `true` or `false`. Default is `false`.
|
||||||
|
|
||||||
|
### Notifications
|
||||||
|
|
||||||
|
An array of notification IDs to use on success and failure. Must match any of the `notifications` object map keys.
|
||||||
|
|
||||||
|
### Name
|
||||||
|
|
||||||
|
Name is optional. If name is not defined, name will be the object's map key.
|
||||||
|
|
||||||
|
### Cron mode
|
||||||
|
|
||||||
|
Backy also has a cron mode, so one can run `backy cron` and start a process that schedules jobs to run at times defined in the configuration file.
|
||||||
|
|
||||||
|
Adding `cron: 0 0 1 * * *` to a `cmdLists` object will schedule the list at 1 in the morning. See [https://crontab.guru/](https://crontab.guru/) for reference.
|
||||||
|
|
||||||
|
{{% notice tip %}}
|
||||||
|
Note: Backy uses the second field of cron, so add anything except `*` to the beginning of a regular cron expression.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
```yaml {lineNos="true" wrap="true" title="yaml"}
|
||||||
|
cmdLists:
|
||||||
|
docker-container-backup: # this can be any name you want
|
||||||
|
# all commands have to be defined
|
||||||
|
order:
|
||||||
|
- stop-docker-container
|
||||||
|
- backup-docker-container-script
|
||||||
|
- shell-cmd
|
||||||
|
- hostname
|
||||||
|
- start-docker-container
|
||||||
|
notifications:
|
||||||
|
- matrix.id
|
||||||
|
name: backup-some-container
|
||||||
|
cron: "0 0 1 * * *"
|
||||||
|
hostname:
|
||||||
|
name: hostname
|
||||||
|
order:
|
||||||
|
- hostname
|
||||||
|
notifications:
|
||||||
|
- mail.prod-email
|
||||||
|
```
|
||||||
164
docs/content/config/commands/_index.md
Executable file
164
docs/content/config/commands/_index.md
Executable file
@@ -0,0 +1,164 @@
|
|||||||
|
---
|
||||||
|
title: "Commands"
|
||||||
|
description: Commands are just that, commands
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Example Config
|
||||||
|
|
||||||
|
{{% code file="/examples/example.yml" language="yaml" %}}
|
||||||
|
|
||||||
|
Values available for this section **(case-sensitive)**:
|
||||||
|
|
||||||
|
| name | notes | type | required | External directive support |
|
||||||
|
| ----------------| ------------------------------------------------------------------------------------------------------- | --------------------- | -------- |----------------------------|
|
||||||
|
| `cmd` | Defines the command to execute | `string` | yes | No |
|
||||||
|
| `Args` | Defines the arguments to the command | `[]string` | no | No |
|
||||||
|
| `environment` | Defines environment variables for the command | `[]string` | no | Partial |
|
||||||
|
| `type` | See documentation further down the page. Additional fields may be required. | `string` | no | No |
|
||||||
|
| `getOutput` | Command(s) output is in the notification(s) | `bool` | no | No |
|
||||||
|
| `host` | Depricated: use `hosts`. If not specified, the command will execute locally. | `string` | no | No |
|
||||||
|
| `hosts` | Must be specified to run commands both locallly and in parrallel. | `[]string` | no | No |
|
||||||
|
| `scriptEnvFile` | When type is `scriptFile` or `script`, this file is prepended to the input. | `string` | no | No |
|
||||||
|
| `shell` | Run the command in the shell | `string` | no | No |
|
||||||
|
| `hooks` | Hooks are used at the end of the individual command. Must have at least `error`, `success`, or `final`. | `map[string][]string` | no | No |
|
||||||
|
|
||||||
|
#### cmd
|
||||||
|
|
||||||
|
cmd must be a valid command or script to execute.
|
||||||
|
|
||||||
|
#### Args
|
||||||
|
|
||||||
|
args must be arguments to cmd as they would be passed on the command-line:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmd [arg1 arg2 ...]
|
||||||
|
```
|
||||||
|
|
||||||
|
Define them in an array:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Args:
|
||||||
|
- arg1
|
||||||
|
- arg2
|
||||||
|
- arg3
|
||||||
|
```
|
||||||
|
|
||||||
|
### getOutput
|
||||||
|
|
||||||
|
Get command output when a notification is sent.
|
||||||
|
|
||||||
|
Is not required. Can be `true` or `false`.
|
||||||
|
|
||||||
|
### host
|
||||||
|
|
||||||
|
|
||||||
|
{{% notice warning %}}
|
||||||
|
Depricated: use `hosts` instead.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
If any `host` is not defined or left blank, the command will run on the local machine.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
Host may or may not be defined in the `hosts` section.
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
If any `host` from the commands section does not match any object in the `hosts` section, the `Host` is assumed to be this value. This value will be used to search in the default SSH config files.
|
||||||
|
|
||||||
|
For example, say that I have a host defined in my SSH config with the `Host` defined as `web-prod`.
|
||||||
|
If I assign a value to host as `host: web-prod` and don't specify this value in the `hosts` object, web-prod will be used as the `Host` in searching the SSH config files.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
### hosts
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
If any `command.[name].hosts` index is `localhost` or `127.0.0.1`, the command will run on the local machine.
|
||||||
|
|
||||||
|
You can also remove the field to have the command run locally.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
Host may or may not be defined in the `hosts` section.
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
If any `host` from the commands section does not match any object in the `hosts` section, the `Host` is assumed to be this value. This value will be used to search in the default SSH config files.
|
||||||
|
|
||||||
|
For example, say that I have a host defined in my SSH config with the `Host` defined as `web-prod`.
|
||||||
|
If I assign a value to host as `host: web-prod` and don't specify this value in the `hosts` object, web-prod will be used as the `Host` in searching the SSH config files.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
###### Example:
|
||||||
|
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
command:
|
||||||
|
start-some-process:
|
||||||
|
cmd: start-server
|
||||||
|
hosts:
|
||||||
|
- prod-1
|
||||||
|
- prod-2
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### shell
|
||||||
|
|
||||||
|
If shell is defined, the command will run in the specified shell.
|
||||||
|
Make sure to escape any shell input.
|
||||||
|
|
||||||
|
### scriptEnvFile
|
||||||
|
|
||||||
|
Path to a file.
|
||||||
|
|
||||||
|
When type is `script` or `scriptFile` , the script is appended to this file.
|
||||||
|
|
||||||
|
This is useful for specifying environment variables or other things so they don't have to be included in the script.
|
||||||
|
|
||||||
|
### type
|
||||||
|
|
||||||
|
The following options are available:
|
||||||
|
|
||||||
|
| name | description |
|
||||||
|
| --- | --- |
|
||||||
|
| script | `cmd` is used as the script |
|
||||||
|
| scriptFile | Can only be run on a host. `cmd` is read and used as the script, and `scriptEnvFile` can be used to add env variables |
|
||||||
|
| package | Run package operations. See [dedicated page](/config/packages) for configuring package commands |
|
||||||
|
| user | Run user operations. See [dedicated page](/config/user-commands) for configuring package commands |
|
||||||
|
|
||||||
|
### environment
|
||||||
|
|
||||||
|
The environment variables support expansion:
|
||||||
|
|
||||||
|
- using escaped values `$VAR` or `${VAR}`
|
||||||
|
- using any external directive, and if using the env directive, the variable will be read from a `.env` file
|
||||||
|
|
||||||
|
<!-- For now, the variables expanded have to be defined in an `.env` file in the same directory that the program is run from. -->
|
||||||
|
|
||||||
|
If using it with host specified, the SSH server has to be configured to accept those env variables.
|
||||||
|
|
||||||
|
If the command is run locally, the OS's environment is added.
|
||||||
|
|
||||||
|
### hooks
|
||||||
|
|
||||||
|
Hooks are run after the command is run.
|
||||||
|
|
||||||
|
Errors are run if the command errors, success if it returns no error. Final hooks are run regardless of error condition.
|
||||||
|
|
||||||
|
Values for hooks are as follows:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
command:
|
||||||
|
hook:
|
||||||
|
# these commands are defined elsewhere in the file
|
||||||
|
error:
|
||||||
|
- errcommand
|
||||||
|
success:
|
||||||
|
- successcommand
|
||||||
|
final:
|
||||||
|
- donecommand
|
||||||
|
```
|
||||||
|
|
||||||
|
### packages
|
||||||
|
|
||||||
|
See the [dedicated page](/config/packages) for package configuration.
|
||||||
81
docs/content/config/commands/packages.md
Executable file
81
docs/content/config/commands/packages.md
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
title: "Packages"
|
||||||
|
weight: 2
|
||||||
|
description: This is dedicated to package commands.
|
||||||
|
---
|
||||||
|
|
||||||
|
This is dedicated to `package` commands. The command `type` field must be `package`. Package is a type that allows one to perform package operations. There are several additional options available when `type` is `package`:
|
||||||
|
|
||||||
|
| name | notes | type | required |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `packageName` | The name of a package to be modified. | `[]packagemanagercommon.Package` | yes |
|
||||||
|
| `packageManager` | The name of the package manger to be used. | `string` | yes |
|
||||||
|
| `packageOperation` | The type of operation to perform. | `string` | yes |
|
||||||
|
| `packageVersion` | The version of a package. | `string` | no |
|
||||||
|
|
||||||
|
|
||||||
|
#### example
|
||||||
|
|
||||||
|
The following is an example of a package command:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
update-docker:
|
||||||
|
type: package
|
||||||
|
shell: zsh
|
||||||
|
packages:
|
||||||
|
- name: docker-ce
|
||||||
|
version: 10
|
||||||
|
packageManager: apt
|
||||||
|
packageOperation: install
|
||||||
|
host: debian-based-host
|
||||||
|
```
|
||||||
|
|
||||||
|
#### packageOperation
|
||||||
|
|
||||||
|
The following package operations are supported:
|
||||||
|
|
||||||
|
- `install`
|
||||||
|
- `remove`
|
||||||
|
- `upgrade`
|
||||||
|
- `checkVersion`
|
||||||
|
|
||||||
|
#### packageManager
|
||||||
|
|
||||||
|
The following package managers are recognized:
|
||||||
|
|
||||||
|
- `apt`
|
||||||
|
- `yum`
|
||||||
|
- `dnf`
|
||||||
|
|
||||||
|
#### package command args
|
||||||
|
|
||||||
|
You can add additional arguments using the standard `Args` key. This is useful for adding more packages, yet it does not work with `checkVersion`.
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
The PackageManager interface provides an easy way to enforce functions and options. There are two interfaces, `PackageManager` and `ConfigurablePackageManager` in the directory `pkg/pkgman`. Go's import-cycle "feature" caused me to implement functional options using a third interface. `PackageManagerOption`is a function that takes an interface.
|
||||||
|
|
||||||
|
#### PackageManager
|
||||||
|
|
||||||
|
```go
|
||||||
|
// PackageManager is an interface used to define common package commands. This shall be implemented by every package.
|
||||||
|
type PackageManager interface {
|
||||||
|
Install(pkg, version string, args []string) (string, []string)
|
||||||
|
Remove(pkg string, args []string) (string, []string)
|
||||||
|
Upgrade(pkg, version string) (string, []string) // Upgrade a specific package
|
||||||
|
UpgradeAll() (string, []string)
|
||||||
|
|
||||||
|
// Configure applies functional options to customize the package manager.
|
||||||
|
Configure(options ...pkgcommon.PackageManagerOption)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
There are a few functional options that should be implemented using the `ConfigurablePackageManager` interface:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// ConfigurablePackageManager defines methods for setting configuration options.
|
||||||
|
type ConfigurablePackageManager interface {
|
||||||
|
SetUseAuth(useAuth bool)
|
||||||
|
SetAuthCommand(authCommand string)
|
||||||
|
}
|
||||||
|
```
|
||||||
66
docs/content/config/commands/user-commands.md
Executable file
66
docs/content/config/commands/user-commands.md
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
title: "User commands"
|
||||||
|
weight: 2
|
||||||
|
description: This is dedicated to user commands.
|
||||||
|
---
|
||||||
|
|
||||||
|
This is dedicated to `user` commands. The command `type` field must be `user`. User is a type that allows one to perform user operations. There are several additional options available when `type` is `user`:
|
||||||
|
|
||||||
|
| name | notes | type | required | External directive support
|
||||||
|
| ----------------| -------------------------------------------------------------| ---------- | ---------| --------------------------|
|
||||||
|
| `userName` | The name of a user to be configured. | `string` | yes | no |
|
||||||
|
| `userOperation` | The type of operation to perform. | `string` | yes | no |
|
||||||
|
| `userID` | The user ID to use. | `string` | no | no |
|
||||||
|
| `userGroups` | The groups the user should be added to. | `[]string` | no | no |
|
||||||
|
| `systemUser` | Create a system user. | `bool` | no | no |
|
||||||
|
| `userCreateHome`| Create the home directory. | `bool` | no | no |
|
||||||
|
| `userSshPubKeys`| The keys to add to the user's authorized keys. | `[]string` | no | yes |
|
||||||
|
| `userShell` | The shell for the user. | `string` | no | no |
|
||||||
|
| `userHome` | The user's home directory. | `string` | no | no |
|
||||||
|
| `userPassword` | The new password value when using the `password` operation. | `string` | no | yes |
|
||||||
|
|
||||||
|
|
||||||
|
#### example
|
||||||
|
|
||||||
|
The following is an example of a package command:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
addUser:
|
||||||
|
name: add user backy with custom home dir
|
||||||
|
type: user
|
||||||
|
userName: backy
|
||||||
|
userHome: /opt/backy
|
||||||
|
userOperation: add
|
||||||
|
host: some-host
|
||||||
|
```
|
||||||
|
|
||||||
|
#### userOperation
|
||||||
|
|
||||||
|
The following package operations are supported:
|
||||||
|
|
||||||
|
- `add`
|
||||||
|
- `remove`
|
||||||
|
- `modify`
|
||||||
|
- `password`
|
||||||
|
- `checkIfExists`
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
The UserManager interface provides an way easy to add new commands. There is one interface `Usermanager` in directory `pkg/usermanager`.
|
||||||
|
|
||||||
|
#### UserManager
|
||||||
|
|
||||||
|
```go
|
||||||
|
// UserManager defines the interface for user management operations.
|
||||||
|
// All functions but one return a string for the command and any args.
|
||||||
|
type UserManager interface {
|
||||||
|
AddUser(username, homeDir, shell string, isSystem bool, groups, args []string) (string, []string)
|
||||||
|
RemoveUser(username string) (string, []string)
|
||||||
|
ModifyUser(username, homeDir, shell string, groups []string) (string, []string)
|
||||||
|
// Modify password uses chpasswd for Linux systems to build the command to change the password
|
||||||
|
// Should return a password as the last argument
|
||||||
|
// TODO: refactor when adding more systems instead of Linux
|
||||||
|
ModifyPassword(username, password string) (string, *strings.Reader, string)
|
||||||
|
UserExists(username string) (string, []string)
|
||||||
|
}
|
||||||
|
```
|
||||||
15
docs/content/config/directives.md
Executable file
15
docs/content/config/directives.md
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: "External Directives"
|
||||||
|
weight: 2
|
||||||
|
description: How to set up external directives.
|
||||||
|
---
|
||||||
|
|
||||||
|
External directives are for including data that should not be in the config file. The following directives are supported:
|
||||||
|
|
||||||
|
- `%{file:path/to/file}%`
|
||||||
|
- `%{env:ENV_VAR}%`
|
||||||
|
- `%{vault:vault-key}%`
|
||||||
|
|
||||||
|
See the docs of each command if the field is supported.
|
||||||
|
|
||||||
|
If the file path does not begin with a `/`, the config file's directory will be used as the starting point.
|
||||||
24
docs/content/config/hosts.md
Executable file
24
docs/content/config/hosts.md
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
title: "Hosts"
|
||||||
|
weight: 2
|
||||||
|
description: >
|
||||||
|
This page tells you how to use hosts.
|
||||||
|
---
|
||||||
|
|
||||||
|
| Key | Description | Type | Required | External directive support |
|
||||||
|
|----------------------|---------------------------------------------------------------|----------|----------|----------------------------|
|
||||||
|
| `OS` | Operating system of the host (used for package commands) | `string` | no | No |
|
||||||
|
| `config` | Path to the SSH config file | `string` | no | No |
|
||||||
|
| `host` | Specifies the `Host` ssh_config(5) directive | `string` | yes | No |
|
||||||
|
| `hostname` | Hostname of the host | `string` | no | No |
|
||||||
|
| `knownHostsFile` | Path to the known hosts file | `string` | no | No |
|
||||||
|
| `port` | Port number to connect to | `uint16` | no | No |
|
||||||
|
| `proxyjump` | Proxy jump hosts, comma-separated | `string` | no | No |
|
||||||
|
| `password` | Password for SSH authentication | `string` | no | No |
|
||||||
|
| `privateKeyPath` | Path to the private key file | `string` | no | No |
|
||||||
|
| `privateKeyPassword` | Password for the private key file | `string` | no | Yes |
|
||||||
|
| `user` | Username for SSH authentication | `string` | no | No |
|
||||||
|
|
||||||
|
## exec host subcommand
|
||||||
|
|
||||||
|
Backy has a subcommand `exec host`. This subcommand takes the flags of `-m host1 -m host2`. The commands can also be specified by `-c command1 -c command2`.
|
||||||
75
docs/content/config/notifications.md
Executable file
75
docs/content/config/notifications.md
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
title: "Notifications"
|
||||||
|
weight: 3
|
||||||
|
description: >
|
||||||
|
This page tells you how to get set up Backy notifications.
|
||||||
|
---
|
||||||
|
|
||||||
|
Notifications are only configurable for command lists, as of right now.
|
||||||
|
|
||||||
|
Notifications can be sent on command list completion and failure.
|
||||||
|
|
||||||
|
The supported platforms for notifications are email (SMTP) and [Matrix](https://matrix.org/).
|
||||||
|
|
||||||
|
Notifications are defined by service, with the current form following below. Ids must come after the service.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
notifications:
|
||||||
|
mail:
|
||||||
|
prod-email:
|
||||||
|
host: yourhost.tld
|
||||||
|
port: 587
|
||||||
|
senderaddress: email@domain.tld
|
||||||
|
to:
|
||||||
|
- admin@domain.tld
|
||||||
|
username: smtp-username@domain.tld
|
||||||
|
password: your-password-here
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
matrix:
|
||||||
|
home-server: your-home-server.tld
|
||||||
|
room-id: room-id
|
||||||
|
access-token: your-access-token
|
||||||
|
user-id: your-user-id
|
||||||
|
```
|
||||||
|
|
||||||
|
Sections recognized are `mail` and `matrix`
|
||||||
|
|
||||||
|
There must be a section with an id (eg. `mail.test-svr`) following one of these sections.
|
||||||
|
|
||||||
|
### mail
|
||||||
|
|
||||||
|
| key | description | type | External directive support |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `host` | Specifies the SMTP host to connect to | `string` | no
|
||||||
|
| `port` | Specifies the SMTP port | `uint16` | no
|
||||||
|
| `senderaddress` | Address from which to send mail | `string` | no
|
||||||
|
| `to` | Recipients to send emails to | `[]string` | no
|
||||||
|
| `username` | SMTP username | `string` | no
|
||||||
|
| `password` | SMTP password | `string` | yes
|
||||||
|
|
||||||
|
### matrix
|
||||||
|
|
||||||
|
| key | description | type | External directive support |
|
||||||
|
| --- | --- | ---| ---- |
|
||||||
|
| `home-server` | Specifies the Matrix server connect to | `string` | no
|
||||||
|
| `room-id` | Specifies the room ID of the room to send messages to | `string` | no
|
||||||
|
| `access-token` | Matrix access token | `string` | yes
|
||||||
|
| `user-id` | Matrix user ID | `string` | no
|
||||||
|
|
||||||
|
To get your access token (assumes you are using [Element](https://element.io/)) :
|
||||||
|
|
||||||
|
1. Log in to the account you want to get the access token for. Click on the name in the top left corner, then "Settings".
|
||||||
|
2. Click the "Help & About" tab (left side of the dialog).
|
||||||
|
3. Scroll to the bottom and click on `<click to reveal>` part of Access Token.
|
||||||
|
4. Copy your access token to a safe place.
|
||||||
|
|
||||||
|
To get the room ID:
|
||||||
|
|
||||||
|
1. On Element or a similar client, navigate to the room.
|
||||||
|
2. Navigate to the settings from the top menu.
|
||||||
|
3. Click on Advanced, the room ID is there.
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
Make sure to quote the room ID, as [YAML spec defines tags using `!`](https://yaml.org/spec/1.2.2/#3212-tags).
|
||||||
|
{{% /notice %}}
|
||||||
21
docs/content/config/remote-resources.md
Executable file
21
docs/content/config/remote-resources.md
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
title: "Remote resources"
|
||||||
|
weight: 2
|
||||||
|
description: This is dedicated to configuring remote resources.
|
||||||
|
---
|
||||||
|
|
||||||
|
Remote resources can be used for a lot of things, including config files and scripts.
|
||||||
|
|
||||||
|
## Config file
|
||||||
|
|
||||||
|
For the main config file to be fetched remotely, pass the URL using `-f [url]`.
|
||||||
|
|
||||||
|
If using S3, you should use the s3 protocol URI: `s3://bucketName/key/path`. You will also need to set the env variable `S3_ENDPOINT` to the appropriate value. The flag `--s3-endpoint` can be used to override this value or to set this value, if not already set.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Currently, only the AWS authentication credentials file `~/.aws/credentials` is supported. For now, the environment variable `AWS_PROFILE` is used to lookup the profile.
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
Remote script support is currently limited to http/https endpoints.
|
||||||
29
docs/content/config/vault.md
Executable file
29
docs/content/config/vault.md
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
title: "Vault"
|
||||||
|
weight: 4
|
||||||
|
description: Set up and configure vault.
|
||||||
|
---
|
||||||
|
|
||||||
|
[Vault](https://www.vaultproject.io/) is a tool for storing secrets and other data securely.
|
||||||
|
|
||||||
|
A Vault key can be used by prefixing `%{vault:vault.keys.name}%` in a field that supports external directives.
|
||||||
|
|
||||||
|
This is the object in the config file:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
vault:
|
||||||
|
token: hvs.tXqcASvTP8wg92f7riyvGyuf
|
||||||
|
address: http://127.0.0.1:8200
|
||||||
|
enabled: false
|
||||||
|
keys:
|
||||||
|
- name: mongourl
|
||||||
|
mountpath: secret
|
||||||
|
key: data
|
||||||
|
path: mongo/url
|
||||||
|
type: KVv2 # KVv1 or KVv2
|
||||||
|
- name: someKeyName
|
||||||
|
mountpath: secret
|
||||||
|
key: keyData
|
||||||
|
type: KVv2
|
||||||
|
path: some/path
|
||||||
|
```
|
||||||
108
docs/content/examples/backy.yaml
Executable file
108
docs/content/examples/backy.yaml
Executable file
@@ -0,0 +1,108 @@
|
|||||||
|
commands:
|
||||||
|
stop-docker-container:
|
||||||
|
cmd: docker
|
||||||
|
Args:
|
||||||
|
- compose
|
||||||
|
- -f /some/path/to/docker-compose.yaml
|
||||||
|
- down
|
||||||
|
# if host is not defined, cmd will be run locally
|
||||||
|
host: some-host
|
||||||
|
hooks:
|
||||||
|
final:
|
||||||
|
- hostname
|
||||||
|
error:
|
||||||
|
- hostname
|
||||||
|
backup-docker-container-script:
|
||||||
|
cmd: /path/to/script
|
||||||
|
# The host has to be defined in the config file
|
||||||
|
host: some-host
|
||||||
|
environment:
|
||||||
|
- FOO=BAR
|
||||||
|
- APP=$VAR
|
||||||
|
shell-cmd:
|
||||||
|
cmd: rsync
|
||||||
|
shell: bash
|
||||||
|
Args:
|
||||||
|
- -av some-host:/path/to/data ~/Docker/Backups/docker-data
|
||||||
|
hostname:
|
||||||
|
cmd: hostname
|
||||||
|
update-docker:
|
||||||
|
type: package
|
||||||
|
shell: zsh # best to run package commands in a shell
|
||||||
|
packageName: docker-ce
|
||||||
|
Args:
|
||||||
|
- docker-ce-cli
|
||||||
|
packageManager: apt
|
||||||
|
packageOperation: install
|
||||||
|
update-dockerApt:
|
||||||
|
# type: package
|
||||||
|
shell: zsh
|
||||||
|
cmd: apt
|
||||||
|
Args:
|
||||||
|
- update
|
||||||
|
- "&&"
|
||||||
|
- apt install -y docker-ce
|
||||||
|
- docker-ce-cli
|
||||||
|
packageManager: apt
|
||||||
|
packageOperation: install
|
||||||
|
|
||||||
|
cmd-lists:
|
||||||
|
cmds-to-run: # this can be any name you want
|
||||||
|
# all commands have to be defined
|
||||||
|
order:
|
||||||
|
- stop-docker-container
|
||||||
|
- backup-docker-container-script
|
||||||
|
- shell-cmd
|
||||||
|
- hostname
|
||||||
|
notifications:
|
||||||
|
- matrix.matrix
|
||||||
|
name: backup-some-server
|
||||||
|
cron: "0 0 1 * * *"
|
||||||
|
hostname:
|
||||||
|
name: hostname
|
||||||
|
order:
|
||||||
|
- hostname
|
||||||
|
notifications:
|
||||||
|
- mail.prod-email
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
# any ssh_config(5) keys/values not listed here will be looked up in the config file or the default config file
|
||||||
|
some-host:
|
||||||
|
hostname: some-hostname
|
||||||
|
config: ~/.ssh/config
|
||||||
|
user: user
|
||||||
|
privateKeyPath: /path/to/private/key
|
||||||
|
port: 22
|
||||||
|
# can also be env:VAR
|
||||||
|
password: file:/path/to/file
|
||||||
|
# only one is supported for now
|
||||||
|
proxyjump: some-proxy-host
|
||||||
|
|
||||||
|
# optional
|
||||||
|
logging:
|
||||||
|
verbose: true
|
||||||
|
file: ./backy.log
|
||||||
|
console: false
|
||||||
|
cmd-std-out: false
|
||||||
|
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
mail:
|
||||||
|
prod-email:
|
||||||
|
id: prod-email
|
||||||
|
type: mail
|
||||||
|
host: yourhost.tld
|
||||||
|
port: 587
|
||||||
|
senderAddress: email@domain.tld
|
||||||
|
to:
|
||||||
|
- admin@domain.tld
|
||||||
|
username: smtp-username@domain.tld
|
||||||
|
password: your-password-here
|
||||||
|
matrix:
|
||||||
|
matrix:
|
||||||
|
id: matrix
|
||||||
|
type: matrix
|
||||||
|
home-server: your-home-server.tld
|
||||||
|
room-id: room-id
|
||||||
|
access-token: your-access-token
|
||||||
|
user-id: your-user-id
|
||||||
24
docs/content/examples/example.yml
Executable file
24
docs/content/examples/example.yml
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
commands:
|
||||||
|
stop-docker-container:
|
||||||
|
cmd: docker
|
||||||
|
Args:
|
||||||
|
- compose
|
||||||
|
- -f /some/path/to/docker-compose.yaml
|
||||||
|
- down
|
||||||
|
# if host is not defined, command will be run locally
|
||||||
|
# The host has to be defined in either the config file or the SSH Config files
|
||||||
|
host: some-host
|
||||||
|
hooks:
|
||||||
|
error:
|
||||||
|
- some-other-command-when-failing
|
||||||
|
success:
|
||||||
|
- success-command
|
||||||
|
final:
|
||||||
|
- final-command
|
||||||
|
backup-docker-container-script:
|
||||||
|
cmd: /path/to/local/script
|
||||||
|
# script file is input as stdin to SSH
|
||||||
|
type: scriptFile # also can be script
|
||||||
|
environment:
|
||||||
|
- FOO=BAR
|
||||||
|
- APP=$VAR
|
||||||
10
docs/content/getting-started/_index.md
Executable file
10
docs/content/getting-started/_index.md
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: "Getting started"
|
||||||
|
weight: 2
|
||||||
|
description: >
|
||||||
|
This page tells you how to get started with Backy.
|
||||||
|
---
|
||||||
|
|
||||||
|
If you have not installed Backy, [see the install documentation](install).
|
||||||
|
|
||||||
|
If you need to configure it, [see the config page](config).
|
||||||
161
docs/content/getting-started/config.md
Executable file
161
docs/content/getting-started/config.md
Executable file
@@ -0,0 +1,161 @@
|
|||||||
|
---
|
||||||
|
title: "Config File Definitions"
|
||||||
|
description: >
|
||||||
|
This page tells you how to configure Backy.
|
||||||
|
---
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
The commands section is for defining commands. These can be run with or without a shell and on a host or locally.
|
||||||
|
|
||||||
|
See the [commands documentation](/config/commands) for further information.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
commands:
|
||||||
|
stop-docker-container:
|
||||||
|
output: true # Optional and only when run in list and notifications are sent
|
||||||
|
cmd: docker
|
||||||
|
args:
|
||||||
|
- compose
|
||||||
|
- -f /some/path/to/docker-compose.yaml
|
||||||
|
- down
|
||||||
|
# if host is not defined, cmd will be run locally
|
||||||
|
host: some-host
|
||||||
|
backup-docker-container-script:
|
||||||
|
cmd: /path/to/script
|
||||||
|
# The host has to be defined in the config file
|
||||||
|
host: some-host
|
||||||
|
environment:
|
||||||
|
- FOO=BAR
|
||||||
|
- APP=$VAR # defined in .env file in config directory
|
||||||
|
shell-cmd:
|
||||||
|
cmd: rsync
|
||||||
|
shell: bash
|
||||||
|
args:
|
||||||
|
- -av
|
||||||
|
- some-host:/path/to/data
|
||||||
|
- ~/Docker/Backups/docker-data
|
||||||
|
script:
|
||||||
|
type: scriptFile # run a local script on a remote host
|
||||||
|
cmd: path/to/your/script.sh
|
||||||
|
host: some-host
|
||||||
|
hostname:
|
||||||
|
cmd: hostname
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lists
|
||||||
|
|
||||||
|
To execute groups of commands in sequence, use a list configuration.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
cmdLists:
|
||||||
|
cmds-to-run: # this can be any name you want
|
||||||
|
# all commands have to be defined in the commands section
|
||||||
|
order:
|
||||||
|
- stop-docker-container
|
||||||
|
- backup-docker-container-script
|
||||||
|
- shell-cmd
|
||||||
|
- hostname
|
||||||
|
getOutput: true # Optional and only for when notifications are sent
|
||||||
|
notifications:
|
||||||
|
- matrix
|
||||||
|
name: backup-some-server
|
||||||
|
hostname:
|
||||||
|
name: hostname
|
||||||
|
order:
|
||||||
|
- hostname
|
||||||
|
notifications:
|
||||||
|
- prod-email
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hosts
|
||||||
|
|
||||||
|
The hosts object may or may not be defined.
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
If any `host` from a commands object does not match any `host` object, the needed values will be checked in the default SSH config files.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
hosts:
|
||||||
|
# any needed ssh_config(5) keys/values not listed here will be looked up in the config file or the default config file
|
||||||
|
some-host:
|
||||||
|
hostname: some-hostname
|
||||||
|
config: ~/.ssh/config
|
||||||
|
user: user
|
||||||
|
privatekeypath: /path/to/private/key
|
||||||
|
port: 22
|
||||||
|
# can also be env:VAR or the password itself
|
||||||
|
password: file:/path/to/file
|
||||||
|
# can also be env:VAR or the password itself
|
||||||
|
privatekeypassword: file:/path/to/file
|
||||||
|
# only one is supported for now
|
||||||
|
proxyjump: some-proxy-host
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notifications
|
||||||
|
|
||||||
|
The notifications object can have two forms.
|
||||||
|
|
||||||
|
For more, [see the notification object documentation](/config/notifications). The top-level map key is id that has to be referenced by the `cmdLists` key `notifications`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
notifications:
|
||||||
|
mail:
|
||||||
|
prod-email:
|
||||||
|
id: prod-email
|
||||||
|
type: mail
|
||||||
|
host: yourhost.tld
|
||||||
|
port: 587
|
||||||
|
senderAddress: email@domain.tld
|
||||||
|
to:
|
||||||
|
- admin@domain.tld
|
||||||
|
username: smtp-username@domain.tld
|
||||||
|
password: your-password-here
|
||||||
|
matrix:
|
||||||
|
matrix:
|
||||||
|
id: matrix
|
||||||
|
type: matrix
|
||||||
|
home-server: your-home-server.tld
|
||||||
|
room-id: room-id
|
||||||
|
access-token: your-access-token
|
||||||
|
user-id: your-user-id
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
`cmd-std-out` controls whether commands output is echoed to StdOut.
|
||||||
|
|
||||||
|
If `logfile` is not defined, the log file will be written to the config directory in the file `backy.log`.
|
||||||
|
|
||||||
|
`console-disabled` controls whether the logging messages are echoed to StdOut. Default is false.
|
||||||
|
|
||||||
|
`verbose` prints out debugging messages.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logging:
|
||||||
|
verbose: false
|
||||||
|
file: path/to/log/file.log
|
||||||
|
console-disabled: false
|
||||||
|
cmd-std-out: false
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vault
|
||||||
|
|
||||||
|
[Vault](https://www.vaultproject.io/) can be used to get some configuration values and ENV variables securely.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
vault:
|
||||||
|
token: hvs.tXqcASvTP8wg92f7riyvGyuf
|
||||||
|
address: http://127.0.0.1:8200
|
||||||
|
enabled: false
|
||||||
|
keys:
|
||||||
|
- name: mongourl
|
||||||
|
mountpath: secret
|
||||||
|
path: mongo/url
|
||||||
|
type: # KVv1 or KVv2
|
||||||
|
- name:
|
||||||
|
path:
|
||||||
|
type:
|
||||||
|
mountpath:
|
||||||
|
```
|
||||||
21
docs/content/getting-started/install.md
Executable file
21
docs/content/getting-started/install.md
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
title: "Install Backy"
|
||||||
|
weight: 1
|
||||||
|
description: >
|
||||||
|
This page tells you how to install Backy.
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
Binaries are available from the [release page](https://git.andrewnw.xyz/CyberShell/backy/releases). Make sure to get the correct version for your system, which supports x86_64, ARM64, and i386.
|
||||||
|
|
||||||
|
### Source Install
|
||||||
|
|
||||||
|
You can install from source. You will need [Go installed](https://go.dev/doc/install).
|
||||||
|
|
||||||
|
Then run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go install git.andrewnw.xyz/CyberShell/backy@master
|
||||||
|
```
|
||||||
|
|
||||||
|
Once set, jump over to the [config docs](/getting-started/config) and start configuring your file.
|
||||||
9
docs/content/repositories/_index.md
Executable file
9
docs/content/repositories/_index.md
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "Repositories"
|
||||||
|
weight: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
The repo mirrors are:
|
||||||
|
|
||||||
|
* [https://git.andrewnw.xyz/CyberShell/backy](https://git.andrewnw.xyz/CyberShell/backy)
|
||||||
|
* [https://github.com/CybersShell/backy](https://github.com/CybersShell/backy)
|
||||||
8
docs/go.mod
Executable file
8
docs/go.mod
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
module git.andrewnw.xyz/CyberShell/backy/docs
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/McShelby/hugo-theme-relearn v0.0.0-20251115105808-d9ca8e8d8f59 // indirect
|
||||||
|
github.com/divinerites/plausible-hugo v1.22.0 // indirect
|
||||||
|
)
|
||||||
4
docs/go.sum
Executable file
4
docs/go.sum
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
github.com/McShelby/hugo-theme-relearn v0.0.0-20251115105808-d9ca8e8d8f59 h1:mnEjz/Wrpv6Hea26KeFJPx94w9g9ZHIurUEWvPdaEvs=
|
||||||
|
github.com/McShelby/hugo-theme-relearn v0.0.0-20251115105808-d9ca8e8d8f59/go.mod h1:mKQQdxZNIlLvAj8X3tMq+RzntIJSr9z7XdzuMomt0IM=
|
||||||
|
github.com/divinerites/plausible-hugo v1.22.0 h1:2pZheSaIMc+EtwcEeZv0ioU2qBOEZa1Ii7IaR/9II9k=
|
||||||
|
github.com/divinerites/plausible-hugo v1.22.0/go.mod h1:cxr+YB3FUwbLon8KCs4pV4Ankbkq6lJxTQUpNb5KqPo=
|
||||||
81
docs/layouts/_default/baseof.html
Executable file
81
docs/layouts/_default/baseof.html
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
{{- block "storeOutputFormat" . }}{{ end }}
|
||||||
|
{{- if .IsHome }}
|
||||||
|
{{- $hugoVersion := "0.141.0" }}
|
||||||
|
{{- if lt hugo.Version $hugoVersion }}
|
||||||
|
{{- errorf "The Relearn theme requires Hugo %s or later" $hugoVersion }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Site.Params.description }}
|
||||||
|
{{- warnf "UNSUPPORTED usage of 'params.description' config parameter found, move it to the front matter of your home page; see https://mcshelby.github.io/hugo-theme-relearn/introduction/releasenotes/6/#6-0-0" }}
|
||||||
|
{{- end }}
|
||||||
|
<html lang="{{ .Page.Language.LanguageCode }}" dir="{{ .Page.Language.LanguageDirection | default (T "Reading-direction") | default "ltr" }}" itemscope itemtype="http://schema.org/Article" data-r-output-format="{{ with .Store.Get "relearnOutputFormat" }}{{ . }}{{ else }}html{{ end }}">
|
||||||
|
<head>
|
||||||
|
{{ partial "plausible_head.html" . }}
|
||||||
|
{{- partial "meta.html" . }}
|
||||||
|
{{- $title := partial "title.gotmpl" (dict "page" . "fullyQualified" true "reverse" true) }}
|
||||||
|
<title>{{ $title }}</title>
|
||||||
|
|
||||||
|
{{- /* multilingual stuff */}}
|
||||||
|
{{- if .IsTranslated -}}
|
||||||
|
{{- range $index, $trans := .AllTranslations }}
|
||||||
|
{{- if eq $index 0 }}
|
||||||
|
<link href="{{ partial "permalink.gotmpl" (dict "to" . "abs" true) }}" rel="alternate" hreflang="x-default">
|
||||||
|
{{- end }}
|
||||||
|
<link href="{{ partial "permalink.gotmpl" (dict "to" . "abs" true) }}" rel="alternate" hreflang="{{ .Language.LanguageCode }}">
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- /* output formats */}}
|
||||||
|
{{- $page := . }}
|
||||||
|
{{- $link := "<link href=\"%s\" rel=\"%s\" type=\"%s\" title=\"%s\">" }}
|
||||||
|
{{- range .AlternativeOutputFormats }}
|
||||||
|
{{- if eq .Rel "canonical" }}
|
||||||
|
{{ (printf $link (partial "permalink.gotmpl" (dict "to" . "abs" true)) .Rel .MediaType.Type ($title | htmlEscape)) | safeHTML }}
|
||||||
|
{{- else if not (partial "_relearn/pageIsSpecial.gotmpl" $page) }}
|
||||||
|
{{ (printf $link (partial "permalink.gotmpl" (dict "to" .)) .Rel .MediaType.Type ($title | htmlEscape)) | safeHTML }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- partialCached "favicon.html" . }}
|
||||||
|
{{- partial "dependencies.html" (dict "page" . "location" "header") }}
|
||||||
|
{{- partial "custom-header.html" . }}
|
||||||
|
</head>
|
||||||
|
<body class="mobile-support {{ with .Store.Get "relearnOutputFormat" }}{{ . }}{{ else }}html{{ end }}{{- if .Site.Params.disableHoverBlockCopyToClipBoard }} disableHoverBlockCopyToClipBoard{{ end }}" data-url="{{ partial "permalink.gotmpl" (dict "to" .) }}">
|
||||||
|
<div id="R-body" class="default-animation">
|
||||||
|
<div id="R-body-overlay"></div>
|
||||||
|
<nav id="R-topbar">
|
||||||
|
<div class="topbar-wrapper">
|
||||||
|
<div class="topbar-sidebar-divider"></div>
|
||||||
|
<div class="topbar-area topbar-area-start" data-area="start">
|
||||||
|
{{- partial "topbar/area/start.html" . }}
|
||||||
|
</div>
|
||||||
|
{{- $showBreadcrumb := (and (not .Params.disableBreadcrumb) (not .Site.Params.disableBreadcrumb)) }}
|
||||||
|
{{- if $showBreadcrumb }}
|
||||||
|
<ol class="topbar-breadcrumbs breadcrumbs highlightable" itemscope itemtype="http://schema.org/BreadcrumbList">
|
||||||
|
{{- partial "breadcrumbs.html" (dict "page" . "schema" true) }}
|
||||||
|
</ol>
|
||||||
|
{{- else }}
|
||||||
|
<span class="topbar-breadcrumbs highlightable">
|
||||||
|
{{ partial "title.gotmpl" (dict "page" . "linkTitle" true) }}
|
||||||
|
</span>
|
||||||
|
{{- end }}
|
||||||
|
<div class="topbar-area topbar-area-end" data-area="end">
|
||||||
|
{{- partial "topbar/area/end.html" . }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div id="R-main-overlay"></div>
|
||||||
|
<main id="R-body-inner" class="highlightable{{ with or .Type "default" }} {{ . }}{{ end }}" tabindex="-1">
|
||||||
|
<div class="flex-block-wrapper">
|
||||||
|
{{- block "body" . }}{{ end }}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{{- partial "custom-comments.html" . }}
|
||||||
|
</div>
|
||||||
|
{{- block "menu" . }}{{ end }}
|
||||||
|
{{- partial "dependencies.html" (dict "page" . "location" "footer") }}
|
||||||
|
{{- partial "custom-footer.html" . }}
|
||||||
|
<div id="toast-container" role="status" aria-live="polite" aria-atomic="false"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
46
docs/layouts/partials/logo.html
Executable file
46
docs/layouts/partials/logo.html
Executable file
File diff suppressed because one or more lines are too long
3
docs/layouts/shortcodes/code.html
Executable file
3
docs/layouts/shortcodes/code.html
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
{{ $file := .Get "file" | readFile }}
|
||||||
|
{{ $lang := .Get "language" }}
|
||||||
|
{{ (print "```" $lang "\n" $file "\n```") }}
|
||||||
1
docs/themes/hugo-theme-relearn
vendored
Submodule
1
docs/themes/hugo-theme-relearn
vendored
Submodule
Submodule docs/themes/hugo-theme-relearn added at 528984250a
1
docs/themes/plausible-hugo
vendored
Submodule
1
docs/themes/plausible-hugo
vendored
Submodule
Submodule docs/themes/plausible-hugo added at 25d00b53c8
20
docs/vangen.json
Executable file
20
docs/vangen.json
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"domain": "go.cybershell.xyz",
|
||||||
|
"docsDomain": "pkg.go.dev",
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"prefix": "backy",
|
||||||
|
"type": "git",
|
||||||
|
"hidden": false,
|
||||||
|
"url": "https://git.andrewnw.xyz/CyberShell/backy",
|
||||||
|
"source": {
|
||||||
|
"home": "https://git.andrewnw.xyz/CyberShell/backy",
|
||||||
|
"dir": "https://git.andrewnw.xyz/CyberShell/backy/src/branch/master/{/dir}",
|
||||||
|
"file": "https://git.andrewnw.xyz/CyberShell/backy/src/branch/master/{/dir}/{file}#L{line}"
|
||||||
|
},
|
||||||
|
"website": {
|
||||||
|
"url": "https://backy.cybershell.xyz/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
25
docs/vangen/backy/index.html
Executable file
25
docs/vangen/backy/index.html
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>go.cybershell.xyz/backy</title>
|
||||||
|
<meta name="go-import" content="go.cybershell.xyz/backy git https://git.andrewnw.xyz/CyberShell/backy">
|
||||||
|
<meta name="go-source" content="go.cybershell.xyz/backy https://git.andrewnw.xyz/CyberShell/backy https://git.andrewnw.xyz/CyberShell/backy/src/branch/master/{/dir} https://git.andrewnw.xyz/CyberShell/backy/src/branch/master/{/dir}/{file}#L{line}">
|
||||||
|
<style>
|
||||||
|
* { font-family: sans-serif; }
|
||||||
|
body { margin-top: 0; }
|
||||||
|
.content { display: inline-block; }
|
||||||
|
code { display: block; font-family: monospace; font-size: 1em; background-color: #d5d5d5; padding: 1em; margin-bottom: 16px; }
|
||||||
|
ul { margin-top: 16px; margin-bottom: 16px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<h2>go.cybershell.xyz/backy</h2>
|
||||||
|
<code>go get go.cybershell.xyz/backy</code>
|
||||||
|
<code>import "go.cybershell.xyz/backy"</code>
|
||||||
|
Home: <a href="https://backy.cybershell.xyz/">https://backy.cybershell.xyz/</a><br/>
|
||||||
|
Source: <a href="https://git.andrewnw.xyz/CyberShell/backy">https://git.andrewnw.xyz/CyberShell/backy</a><br/>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
71
examples/backy.yaml
Normal file → Executable file
71
examples/backy.yaml
Normal file → Executable file
@@ -6,7 +6,12 @@ commands:
|
|||||||
- -f /some/path/to/docker-compose.yaml
|
- -f /some/path/to/docker-compose.yaml
|
||||||
- down
|
- down
|
||||||
# if host is not defined, cmd will be run locally
|
# if host is not defined, cmd will be run locally
|
||||||
host: some-host
|
host: some-host
|
||||||
|
hooks:
|
||||||
|
final:
|
||||||
|
- hostname
|
||||||
|
error:
|
||||||
|
- hostname
|
||||||
backup-docker-container-script:
|
backup-docker-container-script:
|
||||||
cmd: /path/to/script
|
cmd: /path/to/script
|
||||||
# The host has to be defined in the config file
|
# The host has to be defined in the config file
|
||||||
@@ -21,8 +26,29 @@ commands:
|
|||||||
- -av some-host:/path/to/data ~/Docker/Backups/docker-data
|
- -av some-host:/path/to/data ~/Docker/Backups/docker-data
|
||||||
hostname:
|
hostname:
|
||||||
cmd: hostname
|
cmd: hostname
|
||||||
|
update-docker:
|
||||||
|
type: package
|
||||||
|
shell: zsh # best to run package commands in a shell
|
||||||
|
packages:
|
||||||
|
- name: docker-ce
|
||||||
|
version: latest
|
||||||
|
- name: docker-ce-cli
|
||||||
|
version: latest
|
||||||
|
packageManager: apt
|
||||||
|
packageOperation: install
|
||||||
|
update-dockerApt:
|
||||||
|
# type: package
|
||||||
|
shell: zsh
|
||||||
|
cmd: apt
|
||||||
|
packages:
|
||||||
|
- name: docker-ce
|
||||||
|
version: latest
|
||||||
|
- name: docker-ce-cli
|
||||||
|
version: latest
|
||||||
|
packageManager: apt
|
||||||
|
packageOperation: install
|
||||||
|
|
||||||
cmd-configs:
|
cmd-lists:
|
||||||
cmds-to-run: # this can be any name you want
|
cmds-to-run: # this can be any name you want
|
||||||
# all commands have to be defined
|
# all commands have to be defined
|
||||||
order:
|
order:
|
||||||
@@ -31,14 +57,15 @@ cmd-configs:
|
|||||||
- shell-cmd
|
- shell-cmd
|
||||||
- hostname
|
- hostname
|
||||||
notifications:
|
notifications:
|
||||||
- matrix
|
- matrix.matrix
|
||||||
name: backup-some-server
|
name: backup-some-server
|
||||||
|
cron: "0 0 1 * * *"
|
||||||
hostname:
|
hostname:
|
||||||
name: hostname
|
name: hostname
|
||||||
order:
|
order:
|
||||||
- hostname
|
- hostname
|
||||||
notifications:
|
notifications:
|
||||||
- prod-email
|
- mail.prod-email
|
||||||
|
|
||||||
hosts:
|
hosts:
|
||||||
# any ssh_config(5) keys/values not listed here will be looked up in the config file or the default config file
|
# any ssh_config(5) keys/values not listed here will be looked up in the config file or the default config file
|
||||||
@@ -56,26 +83,28 @@ hosts:
|
|||||||
# optional
|
# optional
|
||||||
logging:
|
logging:
|
||||||
verbose: true
|
verbose: true
|
||||||
file: /path/to/logs/commands.log
|
file: ./backy.log
|
||||||
console: false
|
console: false
|
||||||
cmd-std-out: false
|
cmd-std-out: false
|
||||||
|
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
prod-email:
|
mail:
|
||||||
id: prod-email
|
prod-email:
|
||||||
type: mail
|
id: prod-email
|
||||||
host: yourhost.tld
|
type: mail
|
||||||
port: 587
|
host: yourhost.tld
|
||||||
senderAddress: email@domain.tld
|
port: 587
|
||||||
to:
|
senderAddress: email@domain.tld
|
||||||
- admin@domain.tld
|
to:
|
||||||
username: smtp-username@domain.tld
|
- admin@domain.tld
|
||||||
password: your-password-here
|
username: smtp-username@domain.tld
|
||||||
|
password: your-password-here
|
||||||
matrix:
|
matrix:
|
||||||
id: matrix
|
matrix:
|
||||||
type: matrix
|
id: matrix
|
||||||
home-server: your-home-server.tld
|
type: matrix
|
||||||
room-id: room-id
|
home-server: your-home-server.tld
|
||||||
access-token: your-access-token
|
room-id: room-id
|
||||||
user-id: your-user-id
|
access-token: your-access-token
|
||||||
|
user-id: your-user-id
|
||||||
25
examples/example.yml
Executable file
25
examples/example.yml
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
commands:
|
||||||
|
stop-docker-container:
|
||||||
|
cmd: docker
|
||||||
|
Args:
|
||||||
|
- compose
|
||||||
|
- -f /some/path/to/docker-compose.yaml
|
||||||
|
- down
|
||||||
|
# if host is not defined, command will be run locally
|
||||||
|
# The host has to be defined in either the config file or the SSH Config files
|
||||||
|
hosts:
|
||||||
|
- prod
|
||||||
|
hooks:
|
||||||
|
error:
|
||||||
|
- some-other-command-when-failing
|
||||||
|
success:
|
||||||
|
- success-command
|
||||||
|
final:
|
||||||
|
- final-command
|
||||||
|
backup-docker-container-script:
|
||||||
|
cmd: /path/to/local/script
|
||||||
|
# script file is input as stdin to SSH
|
||||||
|
type: scriptFile # also can be script
|
||||||
|
environment:
|
||||||
|
- FOO=BAR
|
||||||
|
- APP=$VAR
|
||||||
67
frontmatter.json
Executable file
67
frontmatter.json
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://frontmatter.codes/frontmatter.schema.json",
|
||||||
|
"frontMatter.taxonomy.contentTypes": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"pageBundle": false,
|
||||||
|
"previewPath": null,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"title": "Title",
|
||||||
|
"name": "title",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Description",
|
||||||
|
"name": "description",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Publishing date",
|
||||||
|
"name": "date",
|
||||||
|
"type": "datetime",
|
||||||
|
"default": "{{now}}",
|
||||||
|
"isPublishDate": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Content preview",
|
||||||
|
"name": "preview",
|
||||||
|
"type": "image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Is in draft",
|
||||||
|
"name": "draft",
|
||||||
|
"type": "draft"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Tags",
|
||||||
|
"name": "tags",
|
||||||
|
"type": "tags"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Categories",
|
||||||
|
"name": "categories",
|
||||||
|
"type": "categories"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frontMatter.framework.id": "hugo",
|
||||||
|
"frontMatter.content.publicFolder": "static",
|
||||||
|
"frontMatter.content.pageFolders": [
|
||||||
|
{
|
||||||
|
"title": "content",
|
||||||
|
"path": "[[workspace]]/docs/content",
|
||||||
|
"originalPath": "[[workspace]]/docs/content"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "config-main",
|
||||||
|
"path": "[[workspace]]/docs/content/config",
|
||||||
|
"originalPath": "[[workspace]]/docs/content/config"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "gs",
|
||||||
|
"path": "[[workspace]]/docs/content/getting-started"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
83
getCommandHelp
Executable file
83
getCommandHelp
Executable file
@@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
CLI_PAGE="docs/content/cli/_index.md"
|
||||||
|
|
||||||
|
BACKYCOMMAND="go run backy.go"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "---
|
||||||
|
title: CLI
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
This page lists documentation for the CLI.
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "## Backy "
|
||||||
|
echo " "
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo " "
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo "# Subcommands"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "## backup"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} backup -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "## cron"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} cron -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "## exec"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} exec -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "### exec host"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} exec host -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
echo "## version"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} version -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "## list"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} list -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
|
||||||
|
echo "## list cmds"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} list cmds -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
|
||||||
|
echo "## list lists"
|
||||||
|
echo ""
|
||||||
|
echo "\`\`\`"
|
||||||
|
eval "${BACKYCOMMAND} list lists -h"
|
||||||
|
echo "\`\`\`"
|
||||||
|
} >> _index.md
|
||||||
|
|
||||||
|
|
||||||
|
mv _index.md "$CLI_PAGE"
|
||||||
123
go.mod
Normal file → Executable file
123
go.mod
Normal file → Executable file
@@ -1,60 +1,99 @@
|
|||||||
module git.andrewnw.xyz/CyberShell/backy
|
module git.andrewnw.xyz/CyberShell/backy
|
||||||
|
|
||||||
go 1.19
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.7
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-co-op/gocron v1.18.0
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0
|
||||||
github.com/joho/godotenv v1.4.0
|
github.com/dmarkham/enumer v1.5.11
|
||||||
|
github.com/go-co-op/gocron v1.37.0
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
|
github.com/hashicorp/vault/api v1.20.0
|
||||||
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/kevinburke/ssh_config v1.2.0
|
github.com/kevinburke/ssh_config v1.2.0
|
||||||
github.com/mattn/go-isatty v0.0.17
|
github.com/knadh/koanf/parsers/yaml v1.1.0
|
||||||
github.com/nikoksr/notify v0.36.0
|
github.com/knadh/koanf/providers/rawbytes v1.0.0
|
||||||
|
github.com/knadh/koanf/v2 v2.2.2
|
||||||
|
github.com/mattn/go-isatty v0.0.20
|
||||||
|
github.com/minio/minio-go/v7 v7.0.94
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
|
github.com/nikoksr/notify v1.3.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/rs/zerolog v1.28.0
|
github.com/pkg/sftp v1.13.9
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/rs/zerolog v1.34.0
|
||||||
github.com/spf13/viper v1.14.0
|
github.com/sethvargo/go-password v0.3.1
|
||||||
go.mongodb.org/mongo-driver v1.11.1
|
github.com/spf13/cobra v1.9.1
|
||||||
golang.org/x/crypto v0.5.0
|
golang.org/x/crypto v0.40.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
maunium.net/go/mautrix v0.13.0
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
mvdan.cc/sh/v3 v3.6.0
|
maunium.net/go/mautrix v0.24.1
|
||||||
|
mvdan.cc/sh/v3 v3.12.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 // indirect
|
||||||
|
github.com/aws/smithy-go v1.22.4 // indirect
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/golang/snappy v0.0.1 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||||
|
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||||
|
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect
|
||||||
|
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
||||||
|
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.1-vault-7 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
|
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
|
||||||
github.com/klauspost/compress v1.13.6 // indirect
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/knadh/koanf/maps v0.1.2 // indirect
|
||||||
|
github.com/kr/fs v0.1.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
|
github.com/minio/crc64nvme v1.0.2 // indirect
|
||||||
|
github.com/minio/md5-simd v1.1.2 // indirect
|
||||||
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pascaldekloe/name v1.0.1 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
github.com/philhofer/fwd v1.2.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||||
github.com/spf13/afero v1.9.3 // indirect
|
github.com/rs/xid v1.6.0 // indirect
|
||||||
github.com/spf13/cast v1.5.0 // indirect
|
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/stretchr/objx v0.5.2 // indirect
|
||||||
github.com/stretchr/objx v0.5.0 // indirect
|
github.com/stretchr/testify v1.10.0 // indirect
|
||||||
github.com/stretchr/testify v1.8.1 // indirect
|
github.com/tidwall/gjson v1.18.0 // indirect
|
||||||
github.com/subosito/gotenv v1.4.1 // indirect
|
|
||||||
github.com/tidwall/gjson v1.14.4 // indirect
|
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
github.com/tidwall/sjson v1.2.5 // indirect
|
github.com/tidwall/sjson v1.2.5 // indirect
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
github.com/tinylib/msgp v1.3.0 // indirect
|
||||||
github.com/xdg-go/scram v1.1.1 // indirect
|
go.mau.fi/util v0.8.8 // indirect
|
||||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/net v0.5.0 // indirect
|
golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
golang.org/x/mod v0.26.0 // indirect
|
||||||
golang.org/x/sys v0.4.0 // indirect
|
golang.org/x/net v0.42.0 // indirect
|
||||||
golang.org/x/text v0.6.0 // indirect
|
golang.org/x/sync v0.16.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
golang.org/x/sys v0.34.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
golang.org/x/text v0.27.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
golang.org/x/time v0.12.0 // indirect
|
||||||
|
golang.org/x/tools v0.35.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
740
go.sum
Normal file → Executable file
740
go.sum
Normal file → Executable file
@@ -1,564 +1,296 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0=
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0=
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA=
|
||||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY=
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s=
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo=
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM=
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8=
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 h1:GMYy2EOWfzdP3wfVAGXBNKY5vK4K8vMET4sYOYltmqs=
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36/go.mod h1:gDhdAV6wL3PmPqBhiPbnlS447GoWs8HTTOYef9/9Inw=
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc=
|
||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ=
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 h1:nAP2GYbfh8dd2zGZqFRSMlq+/F6cMPBUuCsGAMkN074=
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4/go.mod h1:LT10DsiGjLWh4GbjInf9LQejkYEhBgBCjLG5+lvk4EE=
|
||||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI=
|
||||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4=
|
||||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 h1:qcLWgdhq45sDM9na4cvXax9dyLitn8EYBRl8Ak4XtG4=
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17/go.mod h1:M+jkjBFZ2J6DJrjMv2+vkBbuht6kxJYtJiwoVgX4p4U=
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0 h1:5Y75q0RPQoAbieyOuGLhjV9P3txvYgXv2lg0UwJOfmE=
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0/go.mod h1:kUklwasNoCn5YpyAqC/97r6dzTA1SRKJfKq16SXeoDU=
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw=
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
|
||||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
|
||||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/dmarkham/enumer v1.5.11 h1:quorLCaEfzjJ23Pf7PB9lyyaHseh91YfTM/sAD/4Mbo=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/dmarkham/enumer v1.5.11/go.mod h1:yixql+kDDQRYqcuBM2n9Vlt7NoT9ixgXhaXry8vmRg8=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
|
||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||||
github.com/go-co-op/gocron v1.18.0 h1:SxTyJ5xnSN4byCq7b10LmmszFdxQlSQJod8s3gbnXxA=
|
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
github.com/go-co-op/gocron v1.18.0/go.mod h1:sD/a0Aadtw5CpflUJ/lpP9Vfdk979Wl1Sg33HPHg0FY=
|
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||||
|
github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
|
||||||
|
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0=
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/hashicorp/vault/api v1.20.0 h1:KQMHElgudOsr+IbJgmbjHnCTxEpKs9LnozA1D3nozU4=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/hashicorp/vault/api v1.20.0/go.mod h1:GZ4pcjfzoOWpkJ3ijHNpEoAxKEsBJnVljyTe3jM2Sms=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
|
github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
|
||||||
|
github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
|
||||||
|
github.com/knadh/koanf/parsers/yaml v1.1.0 h1:3ltfm9ljprAHt4jxgeYLlFPmUaunuCgu1yILuTXRdM4=
|
||||||
|
github.com/knadh/koanf/parsers/yaml v1.1.0/go.mod h1:HHmcHXUrp9cOPcuC+2wrr44GTUB0EC+PyfN3HZD9tFg=
|
||||||
|
github.com/knadh/koanf/providers/rawbytes v1.0.0 h1:MrKDh/HksJlKJmaZjgs4r8aVBb/zsJyc/8qaSnzcdNI=
|
||||||
|
github.com/knadh/koanf/providers/rawbytes v1.0.0/go.mod h1:KxwYJf1uezTKy6PBtfE+m725NGp4GPVA7XoNTJ/PtLo=
|
||||||
|
github.com/knadh/koanf/v2 v2.2.2 h1:ghbduIkpFui3L587wavneC9e3WIliCgiCgdxYO/wd7A=
|
||||||
|
github.com/knadh/koanf/v2 v2.2.2/go.mod h1:abWQc0cBXLSF/PSOMCB/SK+T13NXDsPvOksbpi5e/9Q=
|
||||||
|
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||||
|
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/minio/crc64nvme v1.0.2 h1:6uO1UxGAD+kwqWWp7mBFsi5gAse66C4NXO8cmcVculg=
|
||||||
|
github.com/minio/crc64nvme v1.0.2/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||||
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
|
github.com/minio/minio-go/v7 v7.0.94 h1:1ZoksIKPyaSt64AVOyaQvhDOgVC3MfZsWM6mZXRUGtM=
|
||||||
|
github.com/minio/minio-go/v7 v7.0.94/go.mod h1:71t2CqDt3ThzESgZUlU1rBN54mksGGlkLcFgguDnnAc=
|
||||||
|
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/nikoksr/notify v0.36.0 h1:OeO/COtxZYLjtFuxBhpeVLfCFdGt48KKgOHKu43w8H0=
|
github.com/nikoksr/notify v1.3.0 h1:UxzfxzAYGQD9a5JYLBTVx0lFMxeHCke3rPCkfWdPgLs=
|
||||||
github.com/nikoksr/notify v0.36.0/go.mod h1:U5h6rVleLTcAJASy7kRdD4vtsFBBxirWQKYX8NJ4jcw=
|
github.com/nikoksr/notify v1.3.0/go.mod h1:Xor2hMmkvrCfkCKvXGbcrESez4brac2zQjhd6U2BbeM=
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pascaldekloe/name v1.0.1 h1:9lnXOHeqeHHnWLbKfH6X98+4+ETVqFqxN09UXSjcMb0=
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pascaldekloe/name v1.0.1/go.mod h1:Z//MfYJnH4jVpQ9wkclwu2I2MkHmXTlT9wR5UZScttM=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||||
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw=
|
||||||
|
github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||||
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
|
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||||
|
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
|
||||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
|
||||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
|
||||||
github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU=
|
|
||||||
github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
|
||||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||||
|
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
go.mau.fi/util v0.8.8 h1:OnuEEc/sIJFhnq4kFggiImUpcmnmL/xpvQMRu5Fiy5c=
|
||||||
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
|
go.mau.fi/util v0.8.8/go.mod h1:Y/kS3loxTEhy8Vill513EtPXr+CRDdae+Xj2BXXMy/c=
|
||||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
go.mongodb.org/mongo-driver v1.11.1 h1:QP0znIRTuL0jf1oBQoAoM0C6ZJfBK4kx0Uumtv1A7w8=
|
|
||||||
go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc h1:TS73t7x3KarrNd5qAipmspBDS1rkMcgVG/fS1aRb4Rc=
|
||||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||||
|
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||||
|
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
|
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||||
|
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||||
|
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||||
|
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||||
|
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||||
|
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
|
||||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
|
||||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
|
||||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
|
||||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
maunium.net/go/mautrix v0.24.1 h1:09/xi4qTeA03g1n/DPmmqAlT8Cx4QrgwiPlmLVzA9AU=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
maunium.net/go/mautrix v0.24.1/go.mod h1:Xy6o+pXmbqmgWsUWh15EQ1eozjC+k/VT/7kloByv9PI=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
maunium.net/go/mautrix v0.13.0 h1:CRdpMFc1kDSNnCZMcqahR9/pkDy/vgRbd+fHnSCl6Yg=
|
|
||||||
maunium.net/go/mautrix v0.13.0/go.mod h1:gYMQPsZ9lQpyKlVp+DGwOuc9LIcE/c8GZW2CvKHISgM=
|
|
||||||
mvdan.cc/sh/v3 v3.6.0 h1:gtva4EXJ0dFNvl5bHjcUEvws+KRcDslT8VKheTYkbGU=
|
|
||||||
mvdan.cc/sh/v3 v3.6.0/go.mod h1:U4mhtBLZ32iWhif5/lD+ygy1zrgaQhUu+XFy7C8+TTA=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
||||||
|
|||||||
149
pkg/backy/allowedexternaldirectives_enumer.go
Normal file
149
pkg/backy/allowedexternaldirectives_enumer.go
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
// Code generated by "enumer -linecomment -yaml -text -json -type=AllowedExternalDirectives"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package backy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const _AllowedExternalDirectivesName = "DefaultExternalDirvaultvault-envvault-filevault-file-envfile-envfileenv"
|
||||||
|
|
||||||
|
var _AllowedExternalDirectivesIndex = [...]uint8{0, 18, 23, 32, 42, 56, 64, 68, 71}
|
||||||
|
|
||||||
|
const _AllowedExternalDirectivesLowerName = "defaultexternaldirvaultvault-envvault-filevault-file-envfile-envfileenv"
|
||||||
|
|
||||||
|
func (i AllowedExternalDirectives) String() string {
|
||||||
|
if i < 0 || i >= AllowedExternalDirectives(len(_AllowedExternalDirectivesIndex)-1) {
|
||||||
|
return fmt.Sprintf("AllowedExternalDirectives(%d)", i)
|
||||||
|
}
|
||||||
|
return _AllowedExternalDirectivesName[_AllowedExternalDirectivesIndex[i]:_AllowedExternalDirectivesIndex[i+1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
func _AllowedExternalDirectivesNoOp() {
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[DefaultExternalDir-(0)]
|
||||||
|
_ = x[AllowedExternalDirectiveVault-(1)]
|
||||||
|
_ = x[AllowedExternalDirectiveVaultEnv-(2)]
|
||||||
|
_ = x[AllowedExternalDirectiveVaultFile-(3)]
|
||||||
|
_ = x[AllowedExternalDirectiveAll-(4)]
|
||||||
|
_ = x[AllowedExternalDirectiveFileEnv-(5)]
|
||||||
|
_ = x[AllowedExternalDirectiveFile-(6)]
|
||||||
|
_ = x[AllowedExternalDirectiveEnv-(7)]
|
||||||
|
}
|
||||||
|
|
||||||
|
var _AllowedExternalDirectivesValues = []AllowedExternalDirectives{DefaultExternalDir, AllowedExternalDirectiveVault, AllowedExternalDirectiveVaultEnv, AllowedExternalDirectiveVaultFile, AllowedExternalDirectiveAll, AllowedExternalDirectiveFileEnv, AllowedExternalDirectiveFile, AllowedExternalDirectiveEnv}
|
||||||
|
|
||||||
|
var _AllowedExternalDirectivesNameToValueMap = map[string]AllowedExternalDirectives{
|
||||||
|
_AllowedExternalDirectivesName[0:18]: DefaultExternalDir,
|
||||||
|
_AllowedExternalDirectivesLowerName[0:18]: DefaultExternalDir,
|
||||||
|
_AllowedExternalDirectivesName[18:23]: AllowedExternalDirectiveVault,
|
||||||
|
_AllowedExternalDirectivesLowerName[18:23]: AllowedExternalDirectiveVault,
|
||||||
|
_AllowedExternalDirectivesName[23:32]: AllowedExternalDirectiveVaultEnv,
|
||||||
|
_AllowedExternalDirectivesLowerName[23:32]: AllowedExternalDirectiveVaultEnv,
|
||||||
|
_AllowedExternalDirectivesName[32:42]: AllowedExternalDirectiveVaultFile,
|
||||||
|
_AllowedExternalDirectivesLowerName[32:42]: AllowedExternalDirectiveVaultFile,
|
||||||
|
_AllowedExternalDirectivesName[42:56]: AllowedExternalDirectiveAll,
|
||||||
|
_AllowedExternalDirectivesLowerName[42:56]: AllowedExternalDirectiveAll,
|
||||||
|
_AllowedExternalDirectivesName[56:64]: AllowedExternalDirectiveFileEnv,
|
||||||
|
_AllowedExternalDirectivesLowerName[56:64]: AllowedExternalDirectiveFileEnv,
|
||||||
|
_AllowedExternalDirectivesName[64:68]: AllowedExternalDirectiveFile,
|
||||||
|
_AllowedExternalDirectivesLowerName[64:68]: AllowedExternalDirectiveFile,
|
||||||
|
_AllowedExternalDirectivesName[68:71]: AllowedExternalDirectiveEnv,
|
||||||
|
_AllowedExternalDirectivesLowerName[68:71]: AllowedExternalDirectiveEnv,
|
||||||
|
}
|
||||||
|
|
||||||
|
var _AllowedExternalDirectivesNames = []string{
|
||||||
|
_AllowedExternalDirectivesName[0:18],
|
||||||
|
_AllowedExternalDirectivesName[18:23],
|
||||||
|
_AllowedExternalDirectivesName[23:32],
|
||||||
|
_AllowedExternalDirectivesName[32:42],
|
||||||
|
_AllowedExternalDirectivesName[42:56],
|
||||||
|
_AllowedExternalDirectivesName[56:64],
|
||||||
|
_AllowedExternalDirectivesName[64:68],
|
||||||
|
_AllowedExternalDirectivesName[68:71],
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowedExternalDirectivesString retrieves an enum value from the enum constants string name.
|
||||||
|
// Throws an error if the param is not part of the enum.
|
||||||
|
func AllowedExternalDirectivesString(s string) (AllowedExternalDirectives, error) {
|
||||||
|
if val, ok := _AllowedExternalDirectivesNameToValueMap[s]; ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, ok := _AllowedExternalDirectivesNameToValueMap[strings.ToLower(s)]; ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("%s does not belong to AllowedExternalDirectives values", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowedExternalDirectivesValues returns all values of the enum
|
||||||
|
func AllowedExternalDirectivesValues() []AllowedExternalDirectives {
|
||||||
|
return _AllowedExternalDirectivesValues
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowedExternalDirectivesStrings returns a slice of all String values of the enum
|
||||||
|
func AllowedExternalDirectivesStrings() []string {
|
||||||
|
strs := make([]string, len(_AllowedExternalDirectivesNames))
|
||||||
|
copy(strs, _AllowedExternalDirectivesNames)
|
||||||
|
return strs
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAAllowedExternalDirectives returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||||
|
func (i AllowedExternalDirectives) IsAAllowedExternalDirectives() bool {
|
||||||
|
for _, v := range _AllowedExternalDirectivesValues {
|
||||||
|
if i == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements the json.Marshaler interface for AllowedExternalDirectives
|
||||||
|
func (i AllowedExternalDirectives) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(i.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshaler interface for AllowedExternalDirectives
|
||||||
|
func (i *AllowedExternalDirectives) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
|
return fmt.Errorf("AllowedExternalDirectives should be a string, got %s", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
*i, err = AllowedExternalDirectivesString(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText implements the encoding.TextMarshaler interface for AllowedExternalDirectives
|
||||||
|
func (i AllowedExternalDirectives) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(i.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText implements the encoding.TextUnmarshaler interface for AllowedExternalDirectives
|
||||||
|
func (i *AllowedExternalDirectives) UnmarshalText(text []byte) error {
|
||||||
|
var err error
|
||||||
|
*i, err = AllowedExternalDirectivesString(string(text))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalYAML implements a YAML Marshaler for AllowedExternalDirectives
|
||||||
|
func (i AllowedExternalDirectives) MarshalYAML() (interface{}, error) {
|
||||||
|
return i.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalYAML implements a YAML Unmarshaler for AllowedExternalDirectives
|
||||||
|
func (i *AllowedExternalDirectives) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
|
var s string
|
||||||
|
if err := unmarshal(&s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
*i, err = AllowedExternalDirectivesString(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
1068
pkg/backy/backy.go
Normal file → Executable file
1068
pkg/backy/backy.go
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
83
pkg/backy/backy_test.go
Executable file
83
pkg/backy/backy_test.go
Executable file
@@ -0,0 +1,83 @@
|
|||||||
|
package backy
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "context"
|
||||||
|
// "fmt"
|
||||||
|
// "io"
|
||||||
|
// "log"
|
||||||
|
// "testing"
|
||||||
|
|
||||||
|
// "git.andrewnw.xyz/CyberShell/backy/pkg/pkgman"
|
||||||
|
// packagemanagercommon "git.andrewnw.xyz/CyberShell/backy/pkg/pkgman/common"
|
||||||
|
// "github.com/stretchr/testify/assert"
|
||||||
|
// "github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
// "github.com/testcontainers/testcontainers-go"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// // TestConfigOptions tests the configuration options for the backy package.
|
||||||
|
// func Test_ErrorHook(t *testing.T) {
|
||||||
|
|
||||||
|
// configFile := "../../tests/ErrorHook.yml"
|
||||||
|
// logFile := "ErrorHook.log"
|
||||||
|
// backyConfigOptions := NewConfigOptions(configFile, SetLogFile(logFile))
|
||||||
|
// backyConfigOptions.InitConfig()
|
||||||
|
// backyConfigOptions.ParseConfigurationFile()
|
||||||
|
// backyConfigOptions.RunListConfig("")
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestSettingCommandInfoPackageCommandDnf(t *testing.T) {
|
||||||
|
|
||||||
|
// packagecommand := &Command{
|
||||||
|
// Type: PackageCommandType,
|
||||||
|
// PackageManager: "dnf",
|
||||||
|
// Shell: "zsh",
|
||||||
|
// PackageOperation: PackageOperationCheckVersion,
|
||||||
|
// Packages: []packagemanagercommon.Package{{Name: "docker-ce"}},
|
||||||
|
// }
|
||||||
|
// dnfPackage, _ := pkgman.PackageManagerFactory("dnf", pkgman.WithoutAuth())
|
||||||
|
|
||||||
|
// packagecommand.pkgMan = dnfPackage
|
||||||
|
// PackageCommand := getCommandTypeAndSetCommandInfo(packagecommand)
|
||||||
|
|
||||||
|
// assert.Equal(t, "dnf", PackageCommand.Cmd)
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestWithDockerFile(t *testing.T) {
|
||||||
|
// ctx := context.Background()
|
||||||
|
|
||||||
|
// docker, err := testcontainers.Run(ctx, "",
|
||||||
|
// testcontainers.WithDockerfile(testcontainers.FromDockerfile{
|
||||||
|
// Context: "../../tests/docker",
|
||||||
|
// Dockerfile: "Dockerfile",
|
||||||
|
// KeepImage: false,
|
||||||
|
// // BuildOptionsModifier: func(buildOptions *types.ImageBuildOptions) {
|
||||||
|
// // buildOptions.Target = "target2"
|
||||||
|
// // },
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
// // docker.
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("failed to start container: %v", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// r, err := docker.Logs(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("failed to get logs: %v", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// logs, err := io.ReadAll(r)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("failed to read logs: %v", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fmt.Println(string(logs))
|
||||||
|
|
||||||
|
// require.NoError(t, err)
|
||||||
|
// }
|
||||||
141
pkg/backy/commandtype_enumer.go
Normal file
141
pkg/backy/commandtype_enumer.go
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
// Code generated by "enumer -linecomment -yaml -text -json -type=CommandType"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package backy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const _CommandTypeName = "scriptscriptFileremoteScriptpackageuser"
|
||||||
|
|
||||||
|
var _CommandTypeIndex = [...]uint8{0, 0, 6, 16, 28, 35, 39}
|
||||||
|
|
||||||
|
const _CommandTypeLowerName = "scriptscriptfileremotescriptpackageuser"
|
||||||
|
|
||||||
|
func (i CommandType) String() string {
|
||||||
|
if i < 0 || i >= CommandType(len(_CommandTypeIndex)-1) {
|
||||||
|
return fmt.Sprintf("CommandType(%d)", i)
|
||||||
|
}
|
||||||
|
return _CommandTypeName[_CommandTypeIndex[i]:_CommandTypeIndex[i+1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
func _CommandTypeNoOp() {
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[DefaultCommandType-(0)]
|
||||||
|
_ = x[ScriptCommandType-(1)]
|
||||||
|
_ = x[ScriptFileCommandType-(2)]
|
||||||
|
_ = x[RemoteScriptCommandType-(3)]
|
||||||
|
_ = x[PackageCommandType-(4)]
|
||||||
|
_ = x[UserCommandType-(5)]
|
||||||
|
}
|
||||||
|
|
||||||
|
var _CommandTypeValues = []CommandType{DefaultCommandType, ScriptCommandType, ScriptFileCommandType, RemoteScriptCommandType, PackageCommandType, UserCommandType}
|
||||||
|
|
||||||
|
var _CommandTypeNameToValueMap = map[string]CommandType{
|
||||||
|
_CommandTypeName[0:0]: DefaultCommandType,
|
||||||
|
_CommandTypeLowerName[0:0]: DefaultCommandType,
|
||||||
|
_CommandTypeName[0:6]: ScriptCommandType,
|
||||||
|
_CommandTypeLowerName[0:6]: ScriptCommandType,
|
||||||
|
_CommandTypeName[6:16]: ScriptFileCommandType,
|
||||||
|
_CommandTypeLowerName[6:16]: ScriptFileCommandType,
|
||||||
|
_CommandTypeName[16:28]: RemoteScriptCommandType,
|
||||||
|
_CommandTypeLowerName[16:28]: RemoteScriptCommandType,
|
||||||
|
_CommandTypeName[28:35]: PackageCommandType,
|
||||||
|
_CommandTypeLowerName[28:35]: PackageCommandType,
|
||||||
|
_CommandTypeName[35:39]: UserCommandType,
|
||||||
|
_CommandTypeLowerName[35:39]: UserCommandType,
|
||||||
|
}
|
||||||
|
|
||||||
|
var _CommandTypeNames = []string{
|
||||||
|
_CommandTypeName[0:0],
|
||||||
|
_CommandTypeName[0:6],
|
||||||
|
_CommandTypeName[6:16],
|
||||||
|
_CommandTypeName[16:28],
|
||||||
|
_CommandTypeName[28:35],
|
||||||
|
_CommandTypeName[35:39],
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandTypeString retrieves an enum value from the enum constants string name.
|
||||||
|
// Throws an error if the param is not part of the enum.
|
||||||
|
func CommandTypeString(s string) (CommandType, error) {
|
||||||
|
if val, ok := _CommandTypeNameToValueMap[s]; ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, ok := _CommandTypeNameToValueMap[strings.ToLower(s)]; ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("%s does not belong to CommandType values", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandTypeValues returns all values of the enum
|
||||||
|
func CommandTypeValues() []CommandType {
|
||||||
|
return _CommandTypeValues
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandTypeStrings returns a slice of all String values of the enum
|
||||||
|
func CommandTypeStrings() []string {
|
||||||
|
strs := make([]string, len(_CommandTypeNames))
|
||||||
|
copy(strs, _CommandTypeNames)
|
||||||
|
return strs
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsACommandType returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||||
|
func (i CommandType) IsACommandType() bool {
|
||||||
|
for _, v := range _CommandTypeValues {
|
||||||
|
if i == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements the json.Marshaler interface for CommandType
|
||||||
|
func (i CommandType) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(i.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshaler interface for CommandType
|
||||||
|
func (i *CommandType) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
|
return fmt.Errorf("CommandType should be a string, got %s", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
*i, err = CommandTypeString(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText implements the encoding.TextMarshaler interface for CommandType
|
||||||
|
func (i CommandType) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(i.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText implements the encoding.TextUnmarshaler interface for CommandType
|
||||||
|
func (i *CommandType) UnmarshalText(text []byte) error {
|
||||||
|
var err error
|
||||||
|
*i, err = CommandTypeString(string(text))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalYAML implements a YAML Marshaler for CommandType
|
||||||
|
func (i CommandType) MarshalYAML() (interface{}, error) {
|
||||||
|
return i.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalYAML implements a YAML Unmarshaler for CommandType
|
||||||
|
func (i *CommandType) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
|
var s string
|
||||||
|
if err := unmarshal(&s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
*i, err = CommandTypeString(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
888
pkg/backy/config.go
Normal file → Executable file
888
pkg/backy/config.go
Normal file → Executable file
@@ -3,240 +3,455 @@ package backy
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
||||||
"github.com/joho/godotenv"
|
"git.andrewnw.xyz/CyberShell/backy/pkg/pkgman"
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/remotefetcher"
|
||||||
|
"git.andrewnw.xyz/CyberShell/backy/pkg/usermanager"
|
||||||
|
vault "github.com/hashicorp/vault/api"
|
||||||
|
"github.com/knadh/koanf/parsers/yaml"
|
||||||
|
"github.com/knadh/koanf/providers/rawbytes"
|
||||||
|
"github.com/knadh/koanf/v2"
|
||||||
"github.com/mattn/go-isatty"
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadConfig validates and reads the config file.
|
const (
|
||||||
func ReadConfig(opts *BackyConfigOpts) *BackyConfigFile {
|
externDirectiveStart string = "%{"
|
||||||
|
externDirectiveEnd string = "}%"
|
||||||
|
externFileDirectiveStart string = "%{file:"
|
||||||
|
envExternDirectiveStart string = "%{env:"
|
||||||
|
vaultExternDirectiveStart string = "%{vault:"
|
||||||
|
)
|
||||||
|
|
||||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
func (opts *ConfigOpts) InitConfig() {
|
||||||
os.Setenv("BACKY_TERM", "enabled")
|
var err error
|
||||||
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
|
homeConfigDir, err := os.UserConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(err.Error(), 1, nil)
|
||||||
|
}
|
||||||
|
homeCacheDir, err := os.UserCacheDir()
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(err.Error(), 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
backyHomeConfDir := path.Join(homeConfigDir, "backy")
|
||||||
|
configFiles := []string{
|
||||||
|
"./backy.yml", "./backy.yaml",
|
||||||
|
path.Join(backyHomeConfDir, "backy.yml"),
|
||||||
|
path.Join(backyHomeConfDir, "backy.yaml"),
|
||||||
|
}
|
||||||
|
|
||||||
|
backyKoanf := koanf.New(".")
|
||||||
|
opts.ConfigFilePath = strings.TrimSpace(opts.ConfigFilePath)
|
||||||
|
|
||||||
|
// metadataFile := "hashMetadataSample.yml"
|
||||||
|
|
||||||
|
cacheDir := homeCacheDir
|
||||||
|
|
||||||
|
// Load metadata from file
|
||||||
|
opts.CachedData, err = remotefetcher.LoadMetadataFromFile(path.Join(backyHomeConfDir, "cache", "cache.yml"))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error loading metadata:", err)
|
||||||
|
logging.ExitWithMSG(err.Error(), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize cache with loaded metadata
|
||||||
|
cache, err := remotefetcher.NewCache(path.Join(backyHomeConfDir, "cache.yml"), cacheDir)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error initializing cache:", err)
|
||||||
|
logging.ExitWithMSG(err.Error(), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate cache with loaded metadata
|
||||||
|
for _, data := range opts.CachedData {
|
||||||
|
if err := cache.AddDataToStore(data.Hash, *data); err != nil {
|
||||||
|
logging.ExitWithMSG(err.Error(), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Cache, err = remotefetcher.NewCache(path.Join(backyHomeConfDir, "cache.yml"), backyHomeConfDir)
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error initializing cache: %v", err), 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if isRemoteURL(opts.ConfigFilePath) {
|
||||||
|
p, _ := getRemoteDir(opts.ConfigFilePath)
|
||||||
|
opts.ConfigDir = p
|
||||||
|
}
|
||||||
|
|
||||||
|
fetcher, err := remotefetcher.NewRemoteFetcher(opts.ConfigFilePath, opts.Cache)
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error initializing config fetcher: %v", err), 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.ConfigFilePath != "" {
|
||||||
|
loadConfigFile(fetcher, opts.ConfigFilePath, backyKoanf, opts)
|
||||||
|
} else {
|
||||||
|
loadDefaultConfigFiles(fetcher, configFiles, backyKoanf, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.koanf = backyKoanf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *ConfigOpts) ParseConfigurationFile() *ConfigOpts {
|
||||||
|
setTerminalEnv()
|
||||||
|
|
||||||
|
backyKoanf := opts.koanf
|
||||||
|
|
||||||
|
if backyKoanf.Exists("variables") {
|
||||||
|
unmarshalConfigIntoStruct(backyKoanf, "variables", &opts.Vars, opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
getConfigDir(opts)
|
||||||
|
|
||||||
|
opts.loadEnv()
|
||||||
|
|
||||||
|
if backyKoanf.Bool(getNestedConfig("logging", "cmd-std-out")) {
|
||||||
|
os.Setenv("BACKY_CMDSTDOUT", "enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
// override the default value of cmd-std-out if flag is set
|
||||||
|
if opts.CmdStdOut {
|
||||||
|
os.Setenv("BACKY_CMDSTDOUT", "enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckConfigValues(backyKoanf, opts.ConfigFilePath)
|
||||||
|
|
||||||
|
validateExecCommandsFromCLI(backyKoanf, opts)
|
||||||
|
|
||||||
|
setLoggingOptions(backyKoanf, opts)
|
||||||
|
|
||||||
|
log := setupLogger(opts)
|
||||||
|
opts.Logger = log
|
||||||
|
|
||||||
|
hostsFetcher, err := remotefetcher.NewRemoteFetcher(opts.HostsFilePath, opts.Cache)
|
||||||
|
opts.Logger.Info().Str("hosts file", opts.HostsFilePath).Send()
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error initializing config fetcher: %v", err), 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hostKoanf = koanf.New(".")
|
||||||
|
if opts.HostsFilePath != "" {
|
||||||
|
loadConfigFile(hostsFetcher, opts.HostsFilePath, hostKoanf, opts)
|
||||||
|
unmarshalConfigIntoStruct(hostKoanf, "hosts", &opts.Hosts, opts.Logger)
|
||||||
|
} else {
|
||||||
|
unmarshalConfigIntoStruct(backyKoanf, "hosts", &opts.Hosts, opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().Str("config file", opts.ConfigFilePath).Send()
|
||||||
|
|
||||||
|
if err := opts.initializeVault(); err != nil {
|
||||||
|
log.Err(err).Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
unmarshalConfigIntoStruct(backyKoanf, "commands", &opts.Cmds, opts.Logger)
|
||||||
|
|
||||||
|
getCommandEnvironments(opts)
|
||||||
|
|
||||||
|
getHostConfigs(opts)
|
||||||
|
|
||||||
|
for k, v := range opts.Vars {
|
||||||
|
v = getExternalConfigDirectiveValue(v, opts, AllowedExternalDirectiveAll)
|
||||||
|
opts.Vars[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCommandLists(opts, backyKoanf)
|
||||||
|
|
||||||
|
validateCommandLists(opts)
|
||||||
|
|
||||||
|
if opts.cronEnabled && len(opts.CmdConfigLists) == 0 {
|
||||||
|
logging.ExitWithMSG("No cron fields detected in any command lists", 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := processCmds(opts); err != nil {
|
||||||
|
logging.ExitWithMSG(err.Error(), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
filterExecuteLists(opts)
|
||||||
|
|
||||||
|
if backyKoanf.Exists("notifications") {
|
||||||
|
unmarshalConfigIntoStruct(backyKoanf, "notifications", &opts.NotificationConf, opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.SetupNotify()
|
||||||
|
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfigFile(fetcher remotefetcher.RemoteFetcher, filePath string, koanfConfigParser *koanf.Koanf, opts *ConfigOpts) {
|
||||||
|
data, err := fetcher.Fetch(filePath)
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(generateFileFetchErrorString(filePath, "config", err), 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := koanfConfigParser.Load(rawbytes.Provider(data), yaml.Parser()); err != nil {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error loading config: %v", err), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadDefaultConfigFiles(fetcher remotefetcher.RemoteFetcher, configFiles []string, k *koanf.Koanf, opts *ConfigOpts) {
|
||||||
|
cFileFailures := 0
|
||||||
|
for _, c := range configFiles {
|
||||||
|
opts.ConfigFilePath = c
|
||||||
|
data, err := fetcher.Fetch(c)
|
||||||
|
if err != nil {
|
||||||
|
cFileFailures++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if data != nil {
|
||||||
|
if err := k.Load(rawbytes.Provider(data), yaml.Parser()); err == nil {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error loading config from file %s: %v", c, err), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cFileFailures == len(configFiles) {
|
||||||
|
logging.ExitWithMSG("Could not find any valid local config file", 1, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTerminalEnv() {
|
||||||
|
if isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) {
|
||||||
os.Setenv("BACKY_TERM", "enabled")
|
os.Setenv("BACKY_TERM", "enabled")
|
||||||
} else {
|
} else {
|
||||||
os.Setenv("BACKY_TERM", "disabled")
|
os.Setenv("BACKY_TERM", "disabled")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
backyConfigFile := NewConfig()
|
func validateExecCommandsFromCLI(k *koanf.Koanf, opts *ConfigOpts) {
|
||||||
backyViper := opts.viper
|
|
||||||
opts.loadEnv()
|
|
||||||
envFileInConfigDir := fmt.Sprintf("%s/.env", path.Dir(backyViper.ConfigFileUsed()))
|
|
||||||
|
|
||||||
// load the .env file in config file directory
|
|
||||||
_ = godotenv.Load(envFileInConfigDir)
|
|
||||||
|
|
||||||
if backyViper.GetBool(getNestedConfig("logging", "cmd-std-out")) {
|
|
||||||
os.Setenv("BACKY_STDOUT", "enabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckConfigValues(backyViper)
|
|
||||||
for _, c := range opts.executeCmds {
|
for _, c := range opts.executeCmds {
|
||||||
if !backyViper.IsSet(getCmdFromConfig(c)) {
|
if !k.Exists(getCmdFromConfig(c)) {
|
||||||
logging.ExitWithMSG(Sprintf("command %s is not in config file %s", c, backyViper.ConfigFileUsed()), 1, nil)
|
logging.ExitWithMSG(fmt.Sprintf("command %s is not in config file %s", c, opts.ConfigFilePath), 1, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, l := range opts.executeLists {
|
func setLoggingOptions(backyKoanf *koanf.Koanf, opts *ConfigOpts) {
|
||||||
if !backyViper.IsSet(getCmdListFromConfig(l)) {
|
isVerboseLoggingSetInConfig := backyKoanf.Bool(getLoggingKeyFromConfig("verbose"))
|
||||||
logging.ExitWithMSG(Sprintf("list %s not found", l), 1, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
// if log file is set in config file and not set on command line, use "./backy.log"
|
||||||
// backyLoggingOpts *viper.Viper
|
if opts.LogFilePath == "" && backyKoanf.Exists(getLoggingKeyFromConfig("file")) {
|
||||||
verbose bool
|
opts.LogFilePath = backyKoanf.String(getLoggingKeyFromConfig("file"))
|
||||||
logFile string
|
} else {
|
||||||
)
|
opts.LogFilePath = "./backy.log"
|
||||||
|
|
||||||
verbose = backyViper.GetBool(getLoggingKeyFromConfig("verbose"))
|
|
||||||
|
|
||||||
logFile = fmt.Sprintf("%s/backy.log", path.Dir(backyViper.ConfigFileUsed()))
|
|
||||||
if backyViper.IsSet(getLoggingKeyFromConfig("file")) {
|
|
||||||
logFile = backyViper.GetString(getLoggingKeyFromConfig("file"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||||
|
if isVerboseLoggingSetInConfig {
|
||||||
if verbose {
|
|
||||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||||
globalLvl := zerolog.GlobalLevel()
|
os.Setenv("BACKY_LOGLEVEL", fmt.Sprintf("%v", zerolog.GlobalLevel()))
|
||||||
os.Setenv("BACKY_LOGLEVEL", Sprintf("%v", globalLvl))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
consoleLoggingEnabled := backyViper.GetBool(getLoggingKeyFromConfig("console"))
|
if backyKoanf.Bool(getLoggingKeyFromConfig("console-disabled")) {
|
||||||
|
|
||||||
// Other qualifiers can go here as well
|
|
||||||
if consoleLoggingEnabled {
|
|
||||||
os.Setenv("BACKY_CONSOLE_LOGGING", "enabled")
|
|
||||||
} else {
|
|
||||||
os.Setenv("BACKY_CONSOLE_LOGGING", "")
|
os.Setenv("BACKY_CONSOLE_LOGGING", "")
|
||||||
|
} else {
|
||||||
|
os.Setenv("BACKY_CONSOLE_LOGGING", "enabled")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
writers := logging.SetLoggingWriters(logFile)
|
func setupLogger(opts *ConfigOpts) zerolog.Logger {
|
||||||
|
writers := logging.SetLoggingWriters(opts.LogFilePath)
|
||||||
|
return zerolog.New(writers).With().Timestamp().Logger()
|
||||||
|
}
|
||||||
|
|
||||||
log := zerolog.New(writers).With().Timestamp().Logger()
|
func unmarshalConfigIntoStruct(k *koanf.Koanf, key string, target interface{}, log zerolog.Logger) {
|
||||||
|
if err := k.UnmarshalWithConf(key, target, koanf.UnmarshalConf{Tag: "yaml"}); err != nil {
|
||||||
backyConfigFile.Logger = log
|
logging.ExitWithMSG(fmt.Sprintf("error unmarshaling key %s into struct: %v", key, err), 1, &log)
|
||||||
|
|
||||||
log.Info().Str("config file", backyViper.ConfigFileUsed()).Send()
|
|
||||||
commandsMap := backyViper.GetStringMapString("commands")
|
|
||||||
commandsMapViper := backyViper.Sub("commands")
|
|
||||||
unmarshalErr := commandsMapViper.Unmarshal(&backyConfigFile.Cmds)
|
|
||||||
if unmarshalErr != nil {
|
|
||||||
panic(fmt.Errorf("error unmarshalling cmds struct: %w", unmarshalErr))
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hostConfigsMap := make(map[string]*viper.Viper)
|
func getCommandEnvironments(opts *ConfigOpts) {
|
||||||
|
for cmdName, cmdConf := range opts.Cmds {
|
||||||
for cmdName, cmdConf := range backyConfigFile.Cmds {
|
if cmdConf.Env == "" {
|
||||||
envFileErr := testFile(cmdConf.Env)
|
continue
|
||||||
if envFileErr != nil {
|
}
|
||||||
backyConfigFile.Logger.Info().Str("cmd", cmdName).Err(envFileErr).Send()
|
opts.Logger.Debug().Str("env file", cmdConf.Env).Str("cmd", cmdName).Send()
|
||||||
os.Exit(1)
|
if err := testFile(cmdConf.Env); err != nil {
|
||||||
|
logging.ExitWithMSG("Could not open file"+cmdConf.Env+": "+err.Error(), 1, &opts.Logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
expandEnvVars(opts.backyEnv, cmdConf.Environment)
|
expandEnvVars(opts.backyEnv, cmdConf.Environment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
host := cmdConf.Host
|
func getHostConfigs(opts *ConfigOpts) {
|
||||||
if host != nil {
|
for hostConfigName, host := range opts.Hosts {
|
||||||
if backyViper.IsSet(getNestedConfig("hosts", *host)) {
|
if host.Host == "" {
|
||||||
hostconfig := backyViper.Sub(getNestedConfig("hosts", *host))
|
host.Host = hostConfigName
|
||||||
hostConfigsMap[*host] = hostconfig
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hostsMapViper := backyViper.Sub("hosts")
|
|
||||||
unmarshalErr = hostsMapViper.Unmarshal(&backyConfigFile.Hosts)
|
|
||||||
if unmarshalErr != nil {
|
|
||||||
panic(fmt.Errorf("error unmarshalling hosts struct: %w", unmarshalErr))
|
|
||||||
}
|
|
||||||
for _, host := range backyConfigFile.Hosts {
|
|
||||||
if host.ProxyJump != "" {
|
if host.ProxyJump != "" {
|
||||||
proxyHosts := strings.Split(host.ProxyJump, ",")
|
getProxyHosts(host, opts)
|
||||||
if len(proxyHosts) > 1 {
|
}
|
||||||
for hostNum, h := range proxyHosts {
|
}
|
||||||
if hostNum > 1 {
|
}
|
||||||
proxyHost, defined := backyConfigFile.Hosts[h]
|
|
||||||
if defined {
|
func getProxyHosts(host *Host, opts *ConfigOpts) {
|
||||||
host.ProxyHost = append(host.ProxyHost, proxyHost)
|
proxyHosts := strings.Split(host.ProxyJump, ",")
|
||||||
} else {
|
for _, h := range proxyHosts {
|
||||||
newProxy := &Host{Host: h}
|
proxyHost, defined := opts.Hosts[h]
|
||||||
host.ProxyHost = append(host.ProxyHost, newProxy)
|
if !defined {
|
||||||
}
|
proxyHost = &Host{Host: h}
|
||||||
} else {
|
opts.Hosts[h] = proxyHost
|
||||||
proxyHost, defined := backyConfigFile.Hosts[h]
|
}
|
||||||
if defined {
|
host.ProxyHost = append(host.ProxyHost, proxyHost)
|
||||||
host.ProxyHost = append(host.ProxyHost, proxyHost)
|
}
|
||||||
} else {
|
}
|
||||||
newHost := &Host{Host: h}
|
|
||||||
host.ProxyHost = append(host.ProxyHost, newHost)
|
func getConfigDir(opts *ConfigOpts) {
|
||||||
}
|
if isRemoteURL(opts.ConfigFilePath) {
|
||||||
}
|
p, _ := getRemoteDir(opts.ConfigFilePath)
|
||||||
}
|
opts.ConfigDir = p
|
||||||
} else {
|
} else {
|
||||||
proxyHost, defined := backyConfigFile.Hosts[proxyHosts[0]]
|
opts.ConfigDir = path.Dir(opts.ConfigFilePath)
|
||||||
if defined {
|
}
|
||||||
host.ProxyHost = append(host.ProxyHost, proxyHost)
|
}
|
||||||
} else {
|
|
||||||
newProxy := &Host{Host: proxyHosts[0]}
|
func loadCommandLists(opts *ConfigOpts, backyKoanf *koanf.Koanf) {
|
||||||
host.ProxyHost = append(host.ProxyHost, newProxy)
|
var listConfigFiles []string
|
||||||
}
|
var u *url.URL
|
||||||
|
var p string
|
||||||
|
if isRemoteURL(opts.ConfigFilePath) {
|
||||||
|
p, u = getRemoteDir(opts.ConfigFilePath)
|
||||||
|
opts.ConfigDir = p
|
||||||
|
listConfigFiles = []string{u.JoinPath("lists.yml").String(), u.JoinPath("lists.yaml").String()}
|
||||||
|
} else {
|
||||||
|
opts.ConfigDir = path.Dir(opts.ConfigFilePath)
|
||||||
|
listConfigFiles = []string{
|
||||||
|
// "./lists.yml", "./lists.yaml",
|
||||||
|
path.Join(opts.ConfigDir, "lists.yml"),
|
||||||
|
path.Join(opts.ConfigDir, "lists.yaml"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listsConfig := koanf.New(".")
|
||||||
|
|
||||||
|
if backyKoanf.Exists("cmdLists") {
|
||||||
|
if backyKoanf.Exists("cmdLists.file") {
|
||||||
|
loadCmdListsFile(backyKoanf, listsConfig, opts)
|
||||||
|
} else {
|
||||||
|
unmarshalConfigIntoStruct(backyKoanf, "cmdLists", &opts.CmdConfigLists, opts.Logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CmdConfigLists == nil {
|
||||||
|
for _, l := range listConfigFiles {
|
||||||
|
if loadListConfigFile(l, listsConfig, opts) {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmdListCfg := backyViper.Sub("cmd-configs")
|
}
|
||||||
unmarshalErr = cmdListCfg.Unmarshal(&backyConfigFile.CmdConfigLists)
|
|
||||||
if unmarshalErr != nil {
|
func isRemoteURL(filePath string) bool {
|
||||||
panic(fmt.Errorf("error unmarshalling cmd list struct: %w", unmarshalErr))
|
return strings.HasPrefix(filePath, "http://") || strings.HasPrefix(filePath, "https://") || strings.HasPrefix(filePath, "s3://")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRemoteDir(filePath string) (string, *url.URL) {
|
||||||
|
u, err := url.Parse(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
// u.Path is the path to the file, stripped of scheme and hostname
|
||||||
|
u.Path = path.Dir(u.Path)
|
||||||
|
|
||||||
|
return u.String(), u
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadListConfigFile(filePath string, k *koanf.Koanf, opts *ConfigOpts) bool {
|
||||||
|
fetcher, err := remotefetcher.NewRemoteFetcher(filePath, opts.Cache, remotefetcher.IgnoreFileNotFound())
|
||||||
|
if err != nil {
|
||||||
|
// if file not found, ignore
|
||||||
|
if errors.Is(err, remotefetcher.ErrIgnoreFileNotFound) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error initializing config fetcher: %v", err), 1, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data, err := fetcher.Fetch(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := k.Load(rawbytes.Provider(data), yaml.Parser()); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
unmarshalConfigIntoStruct(k, "cmdLists", &opts.CmdConfigLists, opts.Logger)
|
||||||
|
keyNotSupported("cmd-lists", "cmdLists", k, opts, true)
|
||||||
|
opts.CmdListFile = filePath
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCmdListsFile(backyKoanf *koanf.Koanf, listsConfig *koanf.Koanf, opts *ConfigOpts) {
|
||||||
|
opts.CmdListFile = strings.TrimSpace(backyKoanf.String("cmdLists.file"))
|
||||||
|
if !path.IsAbs(opts.CmdListFile) {
|
||||||
|
// TODO: Needs testing - might cause undefined/unexpected behavior if remote config path is used
|
||||||
|
opts.CmdListFile = path.Join(path.Dir(opts.ConfigFilePath), opts.CmdListFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
fetcher, err := remotefetcher.NewRemoteFetcher(opts.CmdListFile, opts.Cache)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error initializing config fetcher: %v", err), 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := fetcher.Fetch(opts.CmdListFile)
|
||||||
|
if err != nil {
|
||||||
|
logging.ExitWithMSG(generateFileFetchErrorString(opts.CmdListFile, "list config", err), 1, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := listsConfig.Load(rawbytes.Provider(data), yaml.Parser()); err != nil {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error loading config: %v", err), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyNotSupported("cmd-lists", "cmdLists", listsConfig, opts, true)
|
||||||
|
unmarshalConfigIntoStruct(listsConfig, "cmdLists", &opts.CmdConfigLists, opts.Logger)
|
||||||
|
opts.Logger.Info().Str("using lists config file", opts.CmdListFile).Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateFileFetchErrorString(file, fileType string, err error) string {
|
||||||
|
return fmt.Sprintf("Could not fetch %s file %s: %v", file, fileType, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateCommandLists(opts *ConfigOpts) {
|
||||||
var cmdNotFoundSliceErr []error
|
var cmdNotFoundSliceErr []error
|
||||||
for cmdListName, cmdList := range backyConfigFile.CmdConfigLists {
|
for cmdListName, cmdList := range opts.CmdConfigLists {
|
||||||
if opts.useCron {
|
// if cron is enabled and cron is not set, delete the list
|
||||||
cron := strings.TrimSpace(cmdList.Cron)
|
if opts.cronEnabled && strings.TrimSpace(cmdList.Cron) == "" {
|
||||||
if cron == "" {
|
opts.Logger.Debug().Str("cron", "enabled").Str("list", cmdListName).Msg("cron not set, deleting list")
|
||||||
delete(backyConfigFile.CmdConfigLists, cmdListName)
|
delete(opts.CmdConfigLists, cmdListName)
|
||||||
}
|
continue
|
||||||
}
|
}
|
||||||
for _, cmdInList := range cmdList.Order {
|
for _, cmdInList := range cmdList.Order {
|
||||||
_, cmdNameFound := backyConfigFile.Cmds[cmdInList]
|
if _, cmdNameFound := opts.Cmds[cmdInList]; !cmdNameFound {
|
||||||
if !cmdNameFound {
|
cmdNotFoundSliceErr = append(cmdNotFoundSliceErr, fmt.Errorf("command %s in list %s is not defined in commands section in config file", cmdInList, cmdListName))
|
||||||
cmdNotFoundStr := fmt.Sprintf("command %s in list %s is not defined in config file", cmdInList, cmdListName)
|
|
||||||
cmdNotFoundErr := errors.New(cmdNotFoundStr)
|
|
||||||
cmdNotFoundSliceErr = append(cmdNotFoundSliceErr, cmdNotFoundErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, notificationID := range cmdList.Notifications {
|
|
||||||
if !backyViper.IsSet(getNestedConfig("notifications", notificationID)) {
|
|
||||||
logging.ExitWithMSG(fmt.Sprintf("%s in list %s not found in notifications", notificationID, cmdListName), 1, nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cmdNotFoundSliceErr) > 0 {
|
if len(cmdNotFoundSliceErr) > 0 {
|
||||||
var cmdNotFoundErrorLog = log.Fatal()
|
opts.Logger.Fatal().Errs("commands not found", cmdNotFoundSliceErr).Send()
|
||||||
cmdNotFoundErrorLog.Errs("commands not found", cmdNotFoundSliceErr).Send()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.useCron && (len(backyConfigFile.CmdConfigLists) == 0) {
|
|
||||||
logging.ExitWithMSG("No cron fields detected in any command lists", 1, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
for c := range commandsMap {
|
|
||||||
if opts.executeCmds != nil && !contains(opts.executeCmds, c) {
|
|
||||||
delete(backyConfigFile.Cmds, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(opts.executeLists) > 0 {
|
|
||||||
for l := range backyConfigFile.CmdConfigLists {
|
|
||||||
if !contains(opts.executeLists, l) {
|
|
||||||
delete(backyConfigFile.CmdConfigLists, l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var notificationsMap = make(map[string]interface{})
|
|
||||||
if backyViper.IsSet("notifications") {
|
|
||||||
notificationsMap = backyViper.GetStringMap("notifications")
|
|
||||||
for id := range notificationsMap {
|
|
||||||
notifConfig := backyViper.Sub(getNestedConfig("notifications", id))
|
|
||||||
config := &NotificationsConfig{
|
|
||||||
Config: notifConfig,
|
|
||||||
Enabled: true,
|
|
||||||
}
|
|
||||||
backyConfigFile.Notifications[id] = config
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, cmd := range backyConfigFile.Cmds {
|
|
||||||
if cmd.Host != nil {
|
|
||||||
host, hostFound := backyConfigFile.Hosts[*cmd.Host]
|
|
||||||
if hostFound {
|
|
||||||
cmd.RemoteHost = host
|
|
||||||
cmd.RemoteHost.Host = host.Host
|
|
||||||
if host.HostName != "" {
|
|
||||||
cmd.RemoteHost.HostName = host.HostName
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cmd.RemoteHost = &Host{Host: *cmd.Host}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
backyConfigFile.SetupNotify()
|
|
||||||
return backyConfigFile
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filterExecuteLists(opts *ConfigOpts) {
|
||||||
|
if len(opts.executeLists) > 0 {
|
||||||
|
for l := range opts.CmdConfigLists {
|
||||||
|
if !contains(opts.executeLists, l) {
|
||||||
|
delete(opts.CmdConfigLists, l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
func getNestedConfig(nestedConfig, key string) string {
|
func getNestedConfig(nestedConfig, key string) string {
|
||||||
return fmt.Sprintf("%s.%s", nestedConfig, key)
|
return fmt.Sprintf("%s.%s", nestedConfig, key)
|
||||||
}
|
}
|
||||||
@@ -252,33 +467,296 @@ func getLoggingKeyFromConfig(key string) string {
|
|||||||
return fmt.Sprintf("logging.%s", key)
|
return fmt.Sprintf("logging.%s", key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCmdListFromConfig(list string) string {
|
// func getCmdListFromConfig(list string) string {
|
||||||
return fmt.Sprintf("cmd-configs.%s", list)
|
// return fmt.Sprintf("cmdLists.%s", list)
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (opts *ConfigOpts) initializeVault() error {
|
||||||
|
if !opts.koanf.Bool("vault.enabled") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
config := vault.DefaultConfig()
|
||||||
|
|
||||||
|
config.Address = opts.koanf.String("vault.address")
|
||||||
|
if strings.TrimSpace(config.Address) == "" {
|
||||||
|
config.Address = os.Getenv("VAULT_ADDR")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := vault.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
token := opts.koanf.String("vault.token")
|
||||||
|
if strings.TrimSpace(token) == "" {
|
||||||
|
token = os.Getenv("VAULT_TOKEN")
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(token) == "" {
|
||||||
|
return fmt.Errorf("no token found. One is required. \n\nSet the config key vault.token or the environment variable VAULT_TOKEN")
|
||||||
|
}
|
||||||
|
|
||||||
|
client.SetToken(token)
|
||||||
|
|
||||||
|
unmarshalErr := opts.koanf.UnmarshalWithConf("vault.keys", &opts.VaultKeys, koanf.UnmarshalConf{Tag: "yaml"})
|
||||||
|
if unmarshalErr != nil {
|
||||||
|
logging.ExitWithMSG(fmt.Sprintf("error unmarshaling vault.keys into struct: %v", unmarshalErr), 1, &opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.vaultClient = client
|
||||||
|
|
||||||
|
for _, v := range opts.VaultKeys {
|
||||||
|
v.Name = replaceVarInString(opts.Vars, v.Key, opts.Logger)
|
||||||
|
v.MountPath = replaceVarInString(opts.Vars, v.MountPath, opts.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts *BackyConfigOpts) InitConfig() {
|
func processCmds(opts *ConfigOpts) error {
|
||||||
if opts.viper != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
backyViper := viper.New()
|
|
||||||
|
|
||||||
if strings.TrimSpace(opts.ConfigFilePath) != "" {
|
// process commands
|
||||||
err := testFile(opts.ConfigFilePath)
|
for cmdName, cmd := range opts.Cmds {
|
||||||
if err != nil {
|
cmd.GetVariablesFromConf(opts)
|
||||||
logging.ExitWithMSG(fmt.Sprintf("Could not open config file %s: %v", opts.ConfigFilePath, err), 1, nil)
|
cmd.Cmd = replaceVarInString(opts.Vars, cmd.Cmd, opts.Logger)
|
||||||
|
for i, v := range cmd.Args {
|
||||||
|
v = replaceVarInString(opts.Vars, v, opts.Logger)
|
||||||
|
cmd.Args[i] = v
|
||||||
|
}
|
||||||
|
if cmd.Name == "" {
|
||||||
|
cmd.Name = cmdName
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks := cmd.Hooks
|
||||||
|
if hooks != nil {
|
||||||
|
|
||||||
|
processHookSuccess := processHooks(cmd, hooks.Error, opts, "error")
|
||||||
|
if processHookSuccess != nil {
|
||||||
|
return processHookSuccess
|
||||||
|
}
|
||||||
|
processHookSuccess = processHooks(cmd, hooks.Success, opts, "success")
|
||||||
|
if processHookSuccess != nil {
|
||||||
|
return processHookSuccess
|
||||||
|
}
|
||||||
|
processHookSuccess = processHooks(cmd, hooks.Final, opts, "final")
|
||||||
|
if processHookSuccess != nil {
|
||||||
|
return processHookSuccess
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsHostLocal(cmd.Host) {
|
||||||
|
|
||||||
|
cmdHost := replaceVarInString(opts.Vars, cmd.Host, opts.Logger)
|
||||||
|
if cmdHost != cmd.Host {
|
||||||
|
cmd.Host = cmdHost
|
||||||
|
}
|
||||||
|
host, hostFound := opts.Hosts[cmd.Host]
|
||||||
|
if hostFound {
|
||||||
|
cmd.RemoteHost = host
|
||||||
|
cmd.RemoteHost.Host = host.Host
|
||||||
|
if host.HostName != "" {
|
||||||
|
cmd.RemoteHost.HostName = host.HostName
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
opts.Logger.Info().Msgf("adding host %s to host list", cmd.Host)
|
||||||
|
if opts.Hosts == nil {
|
||||||
|
opts.Hosts = make(map[string]*Host)
|
||||||
|
}
|
||||||
|
opts.Hosts[cmd.Host] = &Host{Host: cmd.Host}
|
||||||
|
cmd.RemoteHost = &Host{Host: cmd.Host}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if cmd.Dir != nil {
|
||||||
|
|
||||||
|
cmdDir, err := getFullPathWithHomeDir(*cmd.Dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd.Dir = &cmdDir
|
||||||
|
} else {
|
||||||
|
cmd.Dir = &opts.ConfigDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Type == PackageCommandType {
|
||||||
|
if cmd.PackageManager == "" {
|
||||||
|
return fmt.Errorf("package manager is required for package command %s", cmd.Name)
|
||||||
|
}
|
||||||
|
if cmd.PackageOperation.String() == "" {
|
||||||
|
return fmt.Errorf("package operation is required for package command %s", cmd.Name)
|
||||||
|
}
|
||||||
|
if cmd.Packages == nil {
|
||||||
|
return fmt.Errorf("package name is required for package command %s", cmd.Name)
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Validate the operation
|
||||||
|
if cmd.PackageOperation.IsAPackageOperation() {
|
||||||
|
|
||||||
|
cmd.pkgMan, err = pkgman.PackageManagerFactory(cmd.PackageManager, pkgman.WithoutAuth())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unsupported package operation %s for command %s", cmd.PackageOperation, cmd.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse user commands
|
||||||
|
if cmd.Type == UserCommandType {
|
||||||
|
if cmd.Username == "" {
|
||||||
|
return fmt.Errorf("username is required for user command %s", cmd.Name)
|
||||||
|
}
|
||||||
|
cmd.Username = replaceVarInString(opts.Vars, cmd.Username, opts.Logger)
|
||||||
|
err := detectOSType(cmd, opts)
|
||||||
|
if err != nil {
|
||||||
|
opts.Logger.Info().Err(err).Str("command", cmdName).Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the operation
|
||||||
|
switch cmd.UserOperation {
|
||||||
|
case "add", "remove", "modify", "checkIfExists", "delete", "password":
|
||||||
|
cmd.userMan, err = usermanager.NewUserManager(cmd.OS)
|
||||||
|
|
||||||
|
if cmd.UserOperation == "password" {
|
||||||
|
opts.Logger.Debug().Msg("changing password for user: " + cmd.Username)
|
||||||
|
cmd.UserPassword = getExternalConfigDirectiveValue(cmd.UserPassword, opts, AllowedExternalDirectiveAll)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsHostLocal(cmd.Host) {
|
||||||
|
|
||||||
|
host, ok := opts.Hosts[cmd.Host]
|
||||||
|
if ok {
|
||||||
|
cmd.userMan, err = usermanager.NewUserManager(host.OS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for indx, key := range cmd.UserSshPubKeys {
|
||||||
|
opts.Logger.Debug().Msg("adding SSH Keys")
|
||||||
|
key = getExternalConfigDirectiveValue(key, opts, AllowedExternalDirectiveAll)
|
||||||
|
cmd.UserSshPubKeys[indx] = key
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported user operation %s for command %s", cmd.UserOperation, cmd.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Type == RemoteScriptCommandType {
|
||||||
|
var fetchErr error
|
||||||
|
if !isRemoteURL(cmd.Cmd) {
|
||||||
|
return fmt.Errorf("remoteScript command %s must be a remote resource", cmdName)
|
||||||
|
}
|
||||||
|
cmd.Fetcher, fetchErr = remotefetcher.NewRemoteFetcher(cmd.Cmd, opts.Cache, remotefetcher.WithFileType("script"))
|
||||||
|
if fetchErr != nil {
|
||||||
|
return fmt.Errorf("error initializing remote fetcher for remoteScript: %v", fetchErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if cmd.Output.File != "" {
|
||||||
|
var err error
|
||||||
|
cmd.Output.File, err = getFullPathWithHomeDir(cmd.Output.File)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
backyViper.SetConfigFile(opts.ConfigFilePath)
|
|
||||||
} else {
|
|
||||||
backyViper.SetConfigName("backy.yml") // name of config file (with extension)
|
|
||||||
backyViper.SetConfigName("backy.yaml") // name of config file (with extension)
|
|
||||||
backyViper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
|
|
||||||
backyViper.AddConfigPath(".") // optionally look for config in the working directory
|
|
||||||
backyViper.AddConfigPath("$HOME/.config/backy") // call multiple times to add many search paths
|
|
||||||
}
|
}
|
||||||
err := backyViper.ReadInConfig() // Find and read the config file
|
return nil
|
||||||
if err != nil { // Handle errors reading the config file
|
}
|
||||||
msg := fmt.Sprintf("fatal error reading config file %s: %v", backyViper.ConfigFileUsed(), err)
|
|
||||||
logging.ExitWithMSG(msg, 1, nil)
|
func processHooks(cmd *Command, hooks []string, opts *ConfigOpts, hookType string) error {
|
||||||
}
|
|
||||||
opts.viper = backyViper
|
var hookCmdFound bool
|
||||||
|
cmd.hookRefs = map[string]map[string]*Command{}
|
||||||
|
cmd.hookRefs[hookType] = map[string]*Command{}
|
||||||
|
|
||||||
|
for _, hook := range hooks {
|
||||||
|
|
||||||
|
var hookCmd *Command
|
||||||
|
// TODO: match by Command.Name
|
||||||
|
|
||||||
|
hookCmd, hookCmdFound = opts.Cmds[hook]
|
||||||
|
|
||||||
|
if !hookCmdFound {
|
||||||
|
return fmt.Errorf("error in command %s hook %s list: command %s not found", cmd.Name, hookType, hook)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.hookRefs[hookType][hook] = hookCmd
|
||||||
|
|
||||||
|
// Recursive, decide if this is good
|
||||||
|
// if hookCmd.hookRefs == nil {
|
||||||
|
// }
|
||||||
|
// hookRef[hookType][h] = hookCmd
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectOSType(cmd *Command, opts *ConfigOpts) error {
|
||||||
|
|
||||||
|
if IsHostLocal(cmd.Host) {
|
||||||
|
|
||||||
|
if runtime.GOOS == "linux" {
|
||||||
|
cmd.OS = "linux"
|
||||||
|
opts.Logger.Info().Msg("Unix/Linux type OS detected")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("using an os that is not yet supported for user commands")
|
||||||
|
}
|
||||||
|
|
||||||
|
host, ok := opts.Hosts[cmd.Host]
|
||||||
|
if ok {
|
||||||
|
if host.OS != "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
os, err := host.DetectOS(opts)
|
||||||
|
os = strings.TrimSpace(os)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if os == "" {
|
||||||
|
return fmt.Errorf("error detecting os for command %s: empty string", cmd.Name)
|
||||||
|
}
|
||||||
|
if strings.Contains(os, "linux") {
|
||||||
|
os = "linux"
|
||||||
|
}
|
||||||
|
host.OS = os
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyNotSupported(oldKey, newKey string, koanf *koanf.Koanf, opts *ConfigOpts, deprecated bool) {
|
||||||
|
|
||||||
|
if koanf.Exists(oldKey) {
|
||||||
|
if deprecated {
|
||||||
|
opts.Logger.Warn().Str("key", oldKey).Msg("key is deprecated. Use " + newKey + " instead.")
|
||||||
|
} else {
|
||||||
|
opts.Logger.Fatal().Err(fmt.Errorf("key %s found; it has changed to %s", oldKey, newKey)).Send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func replaceVarInString(vars map[string]string, str string, logger zerolog.Logger) string {
|
||||||
|
if strings.Contains(str, "%{var:") && strings.Contains(str, "}%") {
|
||||||
|
logger.Debug().Msgf("replacing vars in string %s", str)
|
||||||
|
for k, v := range vars {
|
||||||
|
if strings.Contains(str, "%{var:"+k+"}%") {
|
||||||
|
str = strings.ReplaceAll(str, "%{var:"+k+"}%", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.Contains(str, "%{var:") && strings.Contains(str, "}%") {
|
||||||
|
logger.Warn().Msg("could not replace all vars in string")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) GetVariablesFromConf(opts *ConfigOpts) {
|
||||||
|
c.ScriptEnvFile = replaceVarInString(opts.Vars, c.ScriptEnvFile, opts.Logger)
|
||||||
|
c.Name = replaceVarInString(opts.Vars, c.Name, opts.Logger)
|
||||||
|
c.Output.File = replaceVarInString(opts.Vars, c.Output.File, opts.Logger)
|
||||||
|
c.Host = replaceVarInString(opts.Vars, c.Host, opts.Logger)
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user