Compare commits
No commits in common. "main" and "v1.3.0" have entirely different histories.
19 changed files with 229 additions and 349 deletions
|
|
@ -9,7 +9,7 @@ when:
|
|||
- renovate/*
|
||||
|
||||
variables:
|
||||
- &golang_image 'golang:1.24'
|
||||
- &golang_image 'golang:1.22'
|
||||
|
||||
depends_on:
|
||||
- test
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ when:
|
|||
- renovate/*
|
||||
|
||||
steps:
|
||||
"Check shell scripts":
|
||||
"Check sehll scripts":
|
||||
image: pipelinecomponents/shellcheck
|
||||
commands:
|
||||
- shellcheck ./bin/*.sh
|
||||
|
|
|
|||
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -1,15 +1,5 @@
|
|||
[Unreleased]
|
||||
|
||||
## v2.0.0
|
||||
### Changed
|
||||
- new project archirecture
|
||||
|
||||
## v1.4.0
|
||||
### Added
|
||||
- add logger and option `-v`
|
||||
### Fixed
|
||||
- fix: render days and date when the value is later than danger value
|
||||
|
||||
## v1.3.0
|
||||
### Added
|
||||
- add manpage for Debian
|
||||
|
|
|
|||
12
Makefile
12
Makefile
|
|
@ -50,7 +50,7 @@ $(BIN_LINUX_AMD64):
|
|||
GOOS=$(GO_OS_LINUX) \
|
||||
CGO_ENABLED=$(CGO_ENABLED) \
|
||||
$(CC) $(CFLAGS) -ldflags="$(LDFLAGS)" -gcflags="$(GCFLAGS)" -asmflags="$(ASMFLAGS)" \
|
||||
-o $(BIN_LINUX_AMD64) cmd/main.go
|
||||
-o $(BIN_LINUX_AMD64) .
|
||||
|
||||
.PHONY: $(BIN_LINUX_ARM64)
|
||||
$(BIN_LINUX_ARM64):
|
||||
|
|
@ -59,7 +59,7 @@ $(BIN_LINUX_ARM64):
|
|||
GOOS=$(GO_OS_LINUX) \
|
||||
CGO_ENABLED=$(CGO_ENABLED) \
|
||||
$(CC) $(CFLAGS) -ldflags="$(LDFLAGS)" -gcflags="$(GCFLAGS)" -asmflags="$(ASMFLAGS)" \
|
||||
-o $(BIN_LINUX_ARM64) cmd/main.go
|
||||
-o $(BIN_LINUX_ARM64) .
|
||||
|
||||
.PHONY: $(BIN_WIN_AMD64)
|
||||
$(BIN_WIN_AMD64):
|
||||
|
|
@ -68,7 +68,7 @@ $(BIN_WIN_AMD64):
|
|||
GOOS=$(GO_OS_WIN) \
|
||||
CGO_ENABLED=$(CGO_ENABLED) \
|
||||
$(CC) $(CFLAGS) -ldflags="$(LDFLAGS)" -gcflags="$(GCFLAGS)" -asmflags="$(ASMFLAGS)" \
|
||||
-o $(BIN_WIN_AMD64) cmd/main.go
|
||||
-o $(BIN_WIN_AMD64) .
|
||||
|
||||
.PHONY: $(BIN_WIN_ARM64)
|
||||
$(BIN_WIN_ARM64):
|
||||
|
|
@ -77,7 +77,7 @@ $(BIN_WIN_ARM64):
|
|||
GOOS=$(GO_OS_WIN) \
|
||||
CGO_ENABLED=$(CGO_ENABLED) \
|
||||
$(CC) $(CFLAGS) -ldflags="$(LDFLAGS)" -gcflags="$(GCFLAGS)" -asmflags="$(ASMFLAGS)" \
|
||||
-o $(BIN_WIN_ARM64) cmd/main.go
|
||||
-o $(BIN_WIN_ARM64) .
|
||||
|
||||
.PHONY: $(BIN_DARWIN_AMD64)
|
||||
$(BIN_DARWIN_AMD64):
|
||||
|
|
@ -86,7 +86,7 @@ $(BIN_DARWIN_AMD64):
|
|||
GOOS=$(GO_OS_DARWIN) \
|
||||
CGO_ENABLED=$(CGO_ENABLED) \
|
||||
$(CC) $(CFLAGS) -ldflags="$(LDFLAGS)" -gcflags="$(GCFLAGS)" -asmflags="$(ASMFLAGS)" \
|
||||
-o $(BIN_DARWIN_AMD64) cmd/main.go
|
||||
-o $(BIN_DARWIN_AMD64) .
|
||||
|
||||
.PHONY: $(BIN_DARWIN_ARM64)
|
||||
$(BIN_DARWIN_ARM64):
|
||||
|
|
@ -95,7 +95,7 @@ $(BIN_DARWIN_ARM64):
|
|||
GOOS=$(GO_OS_DARWIN) \
|
||||
CGO_ENABLED=$(CGO_ENABLED) \
|
||||
$(CC) $(CFLAGS) -ldflags="$(LDFLAGS)" -gcflags="$(GCFLAGS)" -asmflags="$(ASMFLAGS)" \
|
||||
-o $(BIN_DARWIN_ARM64) cmd/main.go
|
||||
-o $(BIN_DARWIN_ARM64) .
|
||||
|
||||
.PHONY: $(MAN_OUTPUT)
|
||||
$(MAN_OUTPUT):
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
package cmd
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/checker"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/logger"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/render"
|
||||
"gitnet.fr/deblan/expiration-check/checker"
|
||||
"gitnet.fr/deblan/expiration-check/render"
|
||||
)
|
||||
|
||||
func NormalizeFormat(format string) string {
|
||||
|
|
@ -34,11 +33,6 @@ func App() *cli.App {
|
|||
Value: "table",
|
||||
Usage: "output format: table, csv, tsv, html, json, markdown",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "verbose",
|
||||
Aliases: []string{"v"},
|
||||
Required: false,
|
||||
},
|
||||
}
|
||||
|
||||
return &cli.App{
|
||||
|
|
@ -51,8 +45,6 @@ func App() *cli.App {
|
|||
Usage: "Checks certificate",
|
||||
Flags: flags,
|
||||
Action: func(c *cli.Context) error {
|
||||
logger.Get().SetVerbose(c.Bool("verbose"))
|
||||
|
||||
render.Render(
|
||||
checker.CheckCertificates(c.StringSlice("domain")),
|
||||
30, 14,
|
||||
|
|
@ -68,8 +60,6 @@ func App() *cli.App {
|
|||
Aliases: []string{"d", "domains"},
|
||||
Flags: flags,
|
||||
Action: func(c *cli.Context) error {
|
||||
logger.Get().SetVerbose(c.Bool("verbose"))
|
||||
|
||||
render.Render(
|
||||
checker.CheckDomains(c.StringSlice("domain")),
|
||||
30, 14,
|
||||
47
checker/certificates.go
Normal file
47
checker/certificates.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func FormatDomain(domain string) string {
|
||||
elements := strings.Split(domain, ":")
|
||||
|
||||
if len(elements) == 1 {
|
||||
return fmt.Sprintf("%s:443", elements[0])
|
||||
}
|
||||
|
||||
return domain
|
||||
}
|
||||
|
||||
func CheckCertificate(domain string) Domain {
|
||||
now := time.Now()
|
||||
conn, err := tls.Dial("tcp", FormatDomain(domain), nil)
|
||||
|
||||
if err == nil {
|
||||
date := conn.ConnectionState().PeerCertificates[0].NotAfter
|
||||
daysLeft := date.Sub(now).Hours() / 24
|
||||
|
||||
return Domain{
|
||||
Name: domain,
|
||||
DaysLeft: math.Floor(daysLeft),
|
||||
Date: date.Format(time.DateTime),
|
||||
}
|
||||
}
|
||||
|
||||
return Domain{Name: domain, Failed: true}
|
||||
}
|
||||
|
||||
func CheckCertificates(domains []string) []Domain {
|
||||
values := []Domain{}
|
||||
|
||||
for _, domain := range domains {
|
||||
values = append(values, CheckCertificate(domain))
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
140
checker/domains.go
Normal file
140
checker/domains.go
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/likexian/whois"
|
||||
)
|
||||
|
||||
type RdapResponseData struct {
|
||||
Events []struct {
|
||||
EventAction string `json:"eventAction"`
|
||||
EventDate string `json:"eventDate"`
|
||||
} `json:"events"`
|
||||
}
|
||||
|
||||
type RdapServices struct {
|
||||
Services [][][]string `json:"services"`
|
||||
}
|
||||
|
||||
func GetRdapServices() map[string]string {
|
||||
response, _ := http.Get("https://data.iana.org/rdap/dns.json")
|
||||
values := make(map[string]string)
|
||||
|
||||
defer response.Body.Close()
|
||||
var data RdapServices
|
||||
json.NewDecoder(response.Body).Decode(&data)
|
||||
|
||||
for _, value := range data.Services {
|
||||
for _, tld := range value[0] {
|
||||
values[tld] = value[1][0]
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
func ExtractTld(domain string) string {
|
||||
elements := strings.Split(domain, ".")
|
||||
|
||||
if len(elements) == 1 {
|
||||
return elements[0]
|
||||
}
|
||||
|
||||
return strings.Join(elements[1:], ".")
|
||||
}
|
||||
|
||||
func RdapCheck(domain, service string) Domain {
|
||||
url := fmt.Sprintf("%sdomain/%s?jscard=1", service, domain)
|
||||
response, _ := http.Get(url)
|
||||
now := time.Now()
|
||||
|
||||
defer response.Body.Close()
|
||||
var data RdapResponseData
|
||||
json.NewDecoder(response.Body).Decode(&data)
|
||||
|
||||
for _, event := range data.Events {
|
||||
if event.EventAction == "expiration" {
|
||||
date, _ := time.Parse(time.RFC3339, event.EventDate)
|
||||
daysLeft := date.Sub(now).Hours() / 24
|
||||
|
||||
return Domain{
|
||||
Name: domain,
|
||||
DaysLeft: math.Floor(daysLeft),
|
||||
Date: date.Format(time.DateTime),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Domain{Name: domain, Failed: true}
|
||||
}
|
||||
|
||||
func WhoisCheck(domain string) Domain {
|
||||
domainFailed := Domain{Name: domain, Failed: true}
|
||||
result, err := whois.Whois(domain)
|
||||
if err != nil {
|
||||
return domainFailed
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
formats := []string{
|
||||
"expiration date",
|
||||
"expiry date",
|
||||
"expires on",
|
||||
"paid-till",
|
||||
"renewal",
|
||||
"expires",
|
||||
"domain_datebilleduntil",
|
||||
"expiration",
|
||||
"registry expiry",
|
||||
"registrar registration expiration",
|
||||
}
|
||||
|
||||
result = strings.ToLower(result)
|
||||
|
||||
for _, format := range formats {
|
||||
r, _ := regexp.Compile(fmt.Sprintf(`%s\s*:?\s*([^\s]+)`, format))
|
||||
|
||||
for i, match := range r.FindStringSubmatch(result) {
|
||||
if i%2 == 1 {
|
||||
date, err := time.Parse(time.RFC3339, strings.ToUpper(match))
|
||||
|
||||
if err == nil {
|
||||
daysLeft := date.Sub(now).Hours() / 24
|
||||
|
||||
return Domain{
|
||||
Name: domain,
|
||||
DaysLeft: math.Floor(daysLeft),
|
||||
Date: date.Format(time.DateTime),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return domainFailed
|
||||
}
|
||||
|
||||
func CheckDomains(domains []string) []Domain {
|
||||
values := []Domain{}
|
||||
services := GetRdapServices()
|
||||
|
||||
for _, domain := range domains {
|
||||
tld := ExtractTld(domain)
|
||||
service := services[tld]
|
||||
|
||||
if service != "" {
|
||||
values = append(values, RdapCheck(domain, service))
|
||||
} else {
|
||||
values = append(values, WhoisCheck(domain))
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
8
checker/struct.go
Normal file
8
checker/struct.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package checker
|
||||
|
||||
type Domain struct {
|
||||
Name string `json:"name"`
|
||||
DaysLeft float64 `json:"days"`
|
||||
Date string `json:"date"`
|
||||
Failed bool `json:"failed"`
|
||||
}
|
||||
14
cmd/main.go
14
cmd/main.go
|
|
@ -1,14 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"gitnet.fr/deblan/expiration-check/internal/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := cmd.App().Run(os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
12
main.go
Normal file
12
main.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := App().Run(os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"gitnet.fr/deblan/expiration-check/pkg/formatter"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/model"
|
||||
)
|
||||
|
||||
func CheckCertificate(domain string) *model.Result {
|
||||
conn, err := tls.Dial("tcp", formatter.ToDomainAndHttpPort(domain), nil)
|
||||
|
||||
if err == nil {
|
||||
date := conn.ConnectionState().PeerCertificates[0].NotAfter
|
||||
|
||||
result := model.NewResult(
|
||||
domain,
|
||||
math.Floor(date.Sub(time.Now()).Hours()/24),
|
||||
date.Format(time.DateTime),
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
return model.NewResultFailed(domain)
|
||||
}
|
||||
|
||||
func CheckCertificates(domains []string) []*model.Result {
|
||||
var values []*model.Result
|
||||
|
||||
for _, domain := range domains {
|
||||
values = append(values, CheckCertificate(domain))
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"gitnet.fr/deblan/expiration-check/pkg/extractor"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/logger"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/model"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/rdap"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/whois"
|
||||
)
|
||||
|
||||
func CheckDomains(domains []string) []*model.Result {
|
||||
var err error
|
||||
var date *time.Time
|
||||
var values []*model.Result
|
||||
|
||||
services, err := rdap.GetRdapServices()
|
||||
|
||||
if err != nil {
|
||||
logger.Get().Logf("GetRdapServices failed: error=%v", err)
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
for _, domain := range domains {
|
||||
tld := extractor.ExtractTld(domain)
|
||||
service, ok := services[tld]
|
||||
|
||||
if ok {
|
||||
date, err = rdap.GetExpiration(domain, service)
|
||||
} else {
|
||||
date, err = whois.GetExpiration(domain)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Get().Logf("CheckDomain: domain=%s error=%s", domain, err)
|
||||
|
||||
values = append(values, model.NewResultFailed(domain))
|
||||
} else {
|
||||
daysLeft := math.Floor(date.Sub(time.Now()).Hours() / 24)
|
||||
|
||||
values = append(values, model.NewResult(
|
||||
domain,
|
||||
daysLeft,
|
||||
date.Format(time.DateTime),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
package extractor
|
||||
|
||||
import "strings"
|
||||
|
||||
func ExtractTld(domain string) string {
|
||||
elements := strings.Split(domain, ".")
|
||||
|
||||
if len(elements) == 1 {
|
||||
return elements[0]
|
||||
}
|
||||
|
||||
return strings.Join(elements[1:], ".")
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
package formatter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ToDomainAndHttpPort(domain string) string {
|
||||
elements := strings.Split(domain, ":")
|
||||
|
||||
if len(elements) == 1 {
|
||||
return fmt.Sprintf("%s:443", elements[0])
|
||||
}
|
||||
|
||||
return domain
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package logger
|
||||
|
||||
import "log"
|
||||
|
||||
type Logger struct {
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
var logger *Logger
|
||||
|
||||
func Get() *Logger {
|
||||
if logger == nil {
|
||||
logger = new(Logger)
|
||||
}
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
func (l *Logger) SetVerbose(value bool) {
|
||||
l.Verbose = value
|
||||
}
|
||||
|
||||
func (l *Logger) Logf(format string, v ...any) {
|
||||
if l.Verbose {
|
||||
log.Printf(format, v...)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package model
|
||||
|
||||
type Result struct {
|
||||
Name string `json:"name"`
|
||||
DaysLeft *float64 `json:"days"`
|
||||
Date *string `json:"date"`
|
||||
Failed bool `json:"failed"`
|
||||
}
|
||||
|
||||
func NewResult(name string, daysLeft float64, date string) *Result {
|
||||
return &Result{
|
||||
Name: name,
|
||||
DaysLeft: &daysLeft,
|
||||
Date: &date,
|
||||
Failed: false,
|
||||
}
|
||||
}
|
||||
|
||||
func NewResultFailed(name string) *Result {
|
||||
return &Result{
|
||||
Name: name,
|
||||
Failed: true,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
package rdap
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RdapResponseData struct {
|
||||
Events []struct {
|
||||
EventAction string `json:"eventAction"`
|
||||
EventDate string `json:"eventDate"`
|
||||
} `json:"events"`
|
||||
}
|
||||
|
||||
type RdapServices struct {
|
||||
Services [][][]string `json:"services"`
|
||||
}
|
||||
|
||||
func GetRdapServices() (map[string]string, error) {
|
||||
response, err := http.Get("https://data.iana.org/rdap/dns.json")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
values := make(map[string]string)
|
||||
|
||||
defer response.Body.Close()
|
||||
var data RdapServices
|
||||
|
||||
json.NewDecoder(response.Body).Decode(&data)
|
||||
|
||||
for _, value := range data.Services {
|
||||
for _, tld := range value[0] {
|
||||
values[tld] = value[1][0]
|
||||
}
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func GetExpiration(domain, service string) (*time.Time, error) {
|
||||
url := fmt.Sprintf("%sdomain/%s?jscard=1", service, domain)
|
||||
response, err := http.Get(url)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer response.Body.Close()
|
||||
var data RdapResponseData
|
||||
|
||||
json.NewDecoder(response.Body).Decode(&data)
|
||||
|
||||
actions := []string{"expiration", "Record expires"}
|
||||
|
||||
for _, event := range data.Events {
|
||||
for _, action := range actions {
|
||||
if action == event.EventAction {
|
||||
date, err := time.Parse(time.RFC3339, event.EventDate)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &date, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("Expiration date not found")
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
package whois
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
w "github.com/likexian/whois"
|
||||
)
|
||||
|
||||
func GetExpiration(domain string) (*time.Time, error) {
|
||||
result, err := w.Whois(domain)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = strings.ToLower(result)
|
||||
formats := []string{
|
||||
"expiration date",
|
||||
"expiry date",
|
||||
"expires on",
|
||||
"paid-till",
|
||||
"renewal",
|
||||
"expires",
|
||||
"domain_datebilleduntil",
|
||||
"expiration",
|
||||
"registry expiry",
|
||||
"registrar registration expiration",
|
||||
}
|
||||
|
||||
for _, format := range formats {
|
||||
r, _ := regexp.Compile(fmt.Sprintf(`%s\s*:?\s*([^\s]+)`, format))
|
||||
|
||||
for i, match := range r.FindStringSubmatch(result) {
|
||||
if i%2 == 1 {
|
||||
if date, err := time.Parse(time.RFC3339, strings.ToUpper(match)); err == nil {
|
||||
return &date, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("Expiration date not found")
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
"github.com/jedib0t/go-pretty/v6/text"
|
||||
"gitnet.fr/deblan/expiration-check/pkg/model"
|
||||
"gitnet.fr/deblan/expiration-check/checker"
|
||||
)
|
||||
|
||||
func RenderColor(value string, c text.Colors, format string) string {
|
||||
|
|
@ -19,7 +19,7 @@ func RenderColor(value string, c text.Colors, format string) string {
|
|||
return c.Sprint(value)
|
||||
}
|
||||
|
||||
func Render(values []*model.Result, warning, danger float64, format string) {
|
||||
func Render(values []checker.Domain, warning, danger float64, format string) {
|
||||
sort.SliceStable(values, func(i, j int) bool {
|
||||
if values[i].Failed && values[j].Failed {
|
||||
return values[i].Name < values[j].Name
|
||||
|
|
@ -33,7 +33,7 @@ func Render(values []*model.Result, warning, danger float64, format string) {
|
|||
return true
|
||||
}
|
||||
|
||||
return *values[i].DaysLeft < *values[j].DaysLeft
|
||||
return values[i].DaysLeft < values[j].DaysLeft
|
||||
})
|
||||
|
||||
if format == "json" {
|
||||
|
|
@ -64,15 +64,15 @@ func Render(values []*model.Result, warning, danger float64, format string) {
|
|||
var days string
|
||||
var date string
|
||||
|
||||
if *value.DaysLeft <= danger {
|
||||
days = RenderColor(fmt.Sprintf("%.0f", *value.DaysLeft), text.Colors{0, text.FgRed}, format)
|
||||
date = RenderColor(*value.Date, text.Colors{0, text.FgRed}, format)
|
||||
} else if *value.DaysLeft <= warning {
|
||||
days = RenderColor(fmt.Sprintf("%.0f", *value.DaysLeft), text.Colors{0, text.FgYellow}, format)
|
||||
date = RenderColor(*value.Date, text.Colors{0, text.FgYellow}, format)
|
||||
if value.DaysLeft <= danger {
|
||||
days = failed
|
||||
date = failed
|
||||
} else if value.DaysLeft <= warning {
|
||||
days = RenderColor(fmt.Sprintf("%.0f", value.DaysLeft), text.Colors{0, text.FgYellow}, format)
|
||||
date = RenderColor(value.Date, text.Colors{0, text.FgYellow}, format)
|
||||
} else {
|
||||
days = RenderColor(fmt.Sprintf("%.0f", *value.DaysLeft), text.Colors{0, text.FgGreen}, format)
|
||||
date = RenderColor(*value.Date, text.Colors{0, text.FgGreen}, format)
|
||||
days = RenderColor(fmt.Sprintf("%.0f", value.DaysLeft), text.Colors{0, text.FgGreen}, format)
|
||||
date = RenderColor(value.Date, text.Colors{0, text.FgGreen}, format)
|
||||
}
|
||||
|
||||
t.AppendRow(table.Row{
|
||||
Loading…
Add table
Add a link
Reference in a new issue