mirror of
https://github.com/gregtwallace/apc-p15-tool.git
synced 2025-05-25 06:52:44 +00:00
Compare commits
5 commits
1cfd35c4e2
...
2e082a30cf
Author | SHA1 | Date | |
---|---|---|---|
|
2e082a30cf | ||
|
06b76700c4 | ||
|
7f377fc5da | ||
|
eedbdfcc2a | ||
|
47b964d6ee |
7 changed files with 98 additions and 20 deletions
14
.github/workflows/build_releases.yml
vendored
14
.github/workflows/build_releases.yml
vendored
|
@ -8,11 +8,11 @@ on:
|
|||
|
||||
env:
|
||||
GITHUB_REF: ${{ github.ref }}
|
||||
GO_VERSION: '1.23.1'
|
||||
GO_VERSION: '1.23.5'
|
||||
|
||||
jobs:
|
||||
build-common:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Checkout Main Repo
|
||||
|
@ -41,7 +41,7 @@ jobs:
|
|||
path: ./CHANGELOG.md
|
||||
|
||||
build-linux-arm64:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v4
|
||||
|
@ -90,7 +90,7 @@ jobs:
|
|||
path: ./apc-p15-install
|
||||
|
||||
build-linux-amd64:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Backend Repo
|
||||
uses: actions/checkout@v4
|
||||
|
@ -173,7 +173,7 @@ jobs:
|
|||
|
||||
release-file-linux-arm64:
|
||||
needs: [build-common, build-linux-arm64]
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Make release directory
|
||||
|
@ -217,7 +217,7 @@ jobs:
|
|||
|
||||
release-file-linux-amd64:
|
||||
needs: [build-common, build-linux-amd64]
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Make release directory
|
||||
|
@ -261,7 +261,7 @@ jobs:
|
|||
|
||||
release-file-windows-amd64:
|
||||
needs: [build-common, build-windows-amd64]
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Make release directory
|
||||
|
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,5 +1,15 @@
|
|||
# APC P15 Tool Changelog
|
||||
|
||||
## [v1.2.0] - 2025-01-27
|
||||
|
||||
Add a new feature to `install` that checks the time of the UPS to confirm
|
||||
it is accurate. A log message is added that advises either way. Even if
|
||||
the check fails, the install still proceeds with attempting to install
|
||||
the new certificate.
|
||||
|
||||
Dependencies were also all updated.
|
||||
|
||||
|
||||
## [v1.1.0] - 2024-09-17
|
||||
|
||||
> [!IMPORTANT]
|
||||
|
|
8
go.mod
8
go.mod
|
@ -1,14 +1,14 @@
|
|||
module apc-p15-tool
|
||||
|
||||
go 1.23.1
|
||||
go 1.23.5
|
||||
|
||||
require (
|
||||
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
|
||||
golang.org/x/crypto v0.18.0
|
||||
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1
|
||||
golang.org/x/crypto v0.32.0
|
||||
)
|
||||
|
||||
require golang.org/x/sys v0.16.0 // indirect
|
||||
require golang.org/x/sys v0.29.0 // indirect
|
||||
|
||||
replace apc-p15-tool/cmd/install_only => /cmd/install_only
|
||||
|
||||
|
|
16
go.sum
16
go.sum
|
@ -2,13 +2,13 @@ github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N
|
|||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4 h1:aiqS8aBlF9PsAKeMddMSfbwp3smONCn3UO8QfUg0Z7Y=
|
||||
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4/go.mod h1:H/13DK46DKXy7EaIxPhk2Y0EC8aubKm35nBjBe8AAGc=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1 h1:NVK+OqnavpyFmUiKfUMHrpvbCi2VFoWTrcpI7aDaJ2I=
|
||||
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
|
56
pkg/apcssh/cmd_gettime.go
Normal file
56
pkg/apcssh/cmd_gettime.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package apcssh
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GetTime sends the APC `system` command and then attempts to parse the
|
||||
// response to determine the UPS current date/time.
|
||||
func (cli *Client) GetTime() (time.Time, error) {
|
||||
result, err := cli.cmd("date")
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("apcssh: failed to get time (%s)", err)
|
||||
} else if !strings.EqualFold(result.code, "e000") {
|
||||
return time.Time{}, fmt.Errorf("apcssh: failed to get time (%s: %s)", result.code, result.codeText)
|
||||
}
|
||||
|
||||
// capture each portion of the date information
|
||||
regex := regexp.MustCompile(`Date:\s*(\S*)\s*[\r\n]Time:\s*(\S*)\s*[\r\n]Format:\s*(\S*)\s*[\r\n]Time Zone:\s*(\S*)\s*[\r\n]?`)
|
||||
datePieces := regex.FindStringSubmatch(result.resultText)
|
||||
if len(datePieces) != 5 {
|
||||
return time.Time{}, fmt.Errorf("apcssh: failed to get time (length of datetime value pieces was %d (expected: 5))", len(datePieces))
|
||||
}
|
||||
dateVal := datePieces[1]
|
||||
timeVal := datePieces[2]
|
||||
formatUPSVal := datePieces[3]
|
||||
timeZoneVal := datePieces[4]
|
||||
|
||||
// known APC UPS format strings
|
||||
dateFormatVal := ""
|
||||
switch formatUPSVal {
|
||||
case "mm/dd/yyyy":
|
||||
dateFormatVal = "01/02/2006"
|
||||
case "dd.mm.yyyy":
|
||||
dateFormatVal = "02.01.2006"
|
||||
case "mmm-dd-yy":
|
||||
dateFormatVal = "Jan-02-06"
|
||||
case "dd-mmm-yy":
|
||||
dateFormatVal = "02-Jan-06"
|
||||
case "yyyy-mm-dd":
|
||||
dateFormatVal = "2006-01-02"
|
||||
|
||||
default:
|
||||
return time.Time{}, fmt.Errorf("apcssh: failed to get time (ups returned unknown format string (%s)", formatUPSVal)
|
||||
}
|
||||
|
||||
// convert to time.Time
|
||||
t, err := time.Parse(dateFormatVal+" 15:04:05 -07:00", dateVal+" "+timeVal+" "+timeZoneVal)
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("apcssh: failed to get time (time parse failed: %s)", err)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
|
@ -12,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
appVersion = "1.1.0"
|
||||
appVersion = "1.2.0"
|
||||
)
|
||||
|
||||
// struct for receivers to use common app pieces
|
||||
|
|
|
@ -12,6 +12,8 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
const timeLoggingFormat = time.RFC1123Z
|
||||
|
||||
// cmdInstall is the app's command to create apc p15 file content from key and cert
|
||||
// pem files and upload the p15 to the specified APC UPS
|
||||
func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
|
||||
|
@ -75,6 +77,16 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
|
|||
}
|
||||
app.stdLogger.Println("install: connected to ups ssh, installing ssl key and cert...")
|
||||
|
||||
// check time - don't fail it time is no good, just do logging here
|
||||
upsT, err := client.GetTime()
|
||||
if err != nil {
|
||||
app.errLogger.Printf("warn: install: failed to fetch UPS time (%s), you should manually verify the time is correct on the UPS", err)
|
||||
} else if upsT.After(time.Now().Add(1*time.Hour)) || upsT.Before(time.Now().Add(-1*time.Hour)) {
|
||||
app.errLogger.Printf("warn: install: UPS clock skew detected (this system's time is %s vs. UPS time %s", time.Now().Format(timeLoggingFormat), upsT.Format(timeLoggingFormat))
|
||||
} else {
|
||||
app.stdLogger.Printf("install: UPS clock appears correct (%s)", upsT.Format(timeLoggingFormat))
|
||||
}
|
||||
|
||||
// install SSL Cert
|
||||
err = client.InstallSSLCert(keyP15, certPem, keyCertP15)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue