Skip to content

Commit 6d8280c

Browse files
committed
Completely rework the system to pull statues
The CLI command now provides one status at a time, based on the name provided. A future PR will reinstate multiple statues in some form or fashion. The status handling itself has been moved into a module Go package. This will make it easier to add new status pages and status page providers in the future.
1 parent e98edc4 commit 6d8280c

13 files changed

Lines changed: 334 additions & 125 deletions

arc/cmd/status.go

Lines changed: 18 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -2,148 +2,41 @@ package cmd
22

33
import (
44
"fmt"
5-
"time"
65

6+
"github.com/hubci/arc/arc/statuses"
77
"github.com/spf13/cobra"
88
)
99

10-
type spPage struct {
11-
ID string `json:"id"`
12-
Name string `json:"name"`
13-
URL string `url:"url"`
14-
TimeZone string `json:"time_zone"`
15-
UpdatedAt time.Time `json:"updated_at"`
16-
}
17-
18-
type spStatus struct {
19-
Indicator string `json:"indicator"`
20-
Description string `json:"description"`
21-
}
22-
23-
// StatusPage.io Response
24-
type spResponse struct {
25-
Page *spPage `json:"page"`
26-
Status *spStatus `json:"status"`
27-
}
28-
29-
type sStatus struct {
30-
Updated time.Time `json:"updated"`
31-
Status string `json:"status"`
32-
StatusCode int `json:"status_code"`
33-
}
34-
35-
type sResult struct {
36-
StatusOverall *sStatus `json:"status_overall"`
37-
}
38-
39-
// Status.io Response
40-
type sResponse struct {
41-
Result *sResult `json:"result"`
42-
}
43-
4410
var (
4511
cciFl bool
4612

4713
statusCmd = &cobra.Command{
48-
Use: "status",
49-
Short: "Provides the status page results for various DevOps services",
14+
Use: "status <name>",
15+
Short: "Provides the status page result for the provided name",
16+
Args: cobra.ExactArgs(1),
5017
Run: func(cmd *cobra.Command, args []string) {
5118

52-
var cciResp *spResponse
53-
var cfResp *spResponse
54-
var ghResp *spResponse
55-
var gitlabResp *sResponse
56-
var linodeResp *spResponse
57-
var doResp *spResponse
58-
var dockerResp *sResponse
59-
60-
cciURL := "https://status.circleci.com/api/v2/status.json"
61-
cfURL := "https://www.cloudflarestatus.com/api/v2/status.json"
62-
ghURL := "https://www.githubstatus.com/api/v2/status.json"
63-
gitlabURL := "https://status.gitlab.com/1.0/status/5b36dc6502d06804c08349f7"
64-
linodeURL := "https://status.linode.com/api/v2/status.json"
65-
doURL := "https://status.digitalocean.com/api/v2/status.json"
66-
dockerURL := "https://status.docker.com/1.0/status/533c6539221ae15e3f000031"
67-
68-
client := New()
69-
70-
errCCI := client.getJSON(cciURL, &cciResp)
71-
errCF := client.getJSON(cfURL, &cfResp)
72-
errGH := client.getJSON(ghURL, &ghResp)
73-
errGitlab := client.getJSON(gitlabURL, &gitlabResp)
74-
errLinode := client.getJSON(linodeURL, &linodeResp)
75-
errDO := client.getJSON(doURL, &doResp)
76-
errDocker := client.getJSON(dockerURL, &dockerResp)
77-
78-
if errCCI != nil {
79-
cciResp.Status.Indicator = "can't connect"
80-
}
81-
82-
if errCF != nil {
83-
cfResp.Status.Indicator = "can't connect"
84-
}
85-
86-
if errGH != nil {
87-
ghResp.Status.Indicator = "can't connect"
88-
}
89-
90-
if errGitlab != nil {
91-
gitlabResp.Result.StatusOverall.Status = "can't connect"
92-
}
93-
94-
if errLinode != nil {
95-
linodeResp.Status.Indicator = "can't connect"
96-
}
97-
98-
if errDO != nil {
99-
doResp.Status.Indicator = "can't connect"
19+
statusPage, err := statuses.Page(args[0])
20+
if err != nil {
21+
fmt.Println(err)
22+
return
10023
}
10124

102-
if errDocker != nil {
103-
dockerResp.Result.StatusOverall.Status = "can't connect"
104-
}
105-
106-
var cciTabs = ""
107-
if cciResp.Status.Indicator == "none" {
108-
cciResp.Status.Indicator = ""
109-
cciTabs = "\t"
110-
}
111-
112-
var cfTabs = ""
113-
if cfResp.Status.Indicator == "none" {
114-
cfResp.Status.Indicator = ""
115-
cfTabs = "\t"
116-
}
117-
118-
var ghTabs = ""
119-
if ghResp.Status.Indicator == "none" {
120-
ghResp.Status.Indicator = ""
121-
ghTabs = "\t"
122-
}
25+
client := New()
12326

124-
var linodeTabs = ""
125-
if linodeResp.Status.Indicator == "none" {
126-
linodeResp.Status.Indicator = ""
127-
linodeTabs = "\t"
27+
err = statusPage.Fetch(client.c)
28+
if err != nil {
29+
fmt.Println(err)
30+
return
12831
}
12932

130-
var doTabs = ""
131-
if doResp.Status.Indicator == "none" {
132-
doResp.Status.Indicator = ""
133-
doTabs = "\t"
33+
status, err := statusPage.Status()
34+
if err != nil {
35+
fmt.Println(err)
36+
return
13437
}
13538

136-
fmt.Println("Reporting status page results...")
137-
fmt.Println("")
138-
fmt.Printf("CircleCI:\t%s%s\t%s\n", cciResp.Status.Indicator, cciTabs, cciResp.Status.Description)
139-
fmt.Printf("GitHub:\t\t%s%s\t%s\n", ghResp.Status.Indicator, ghTabs, ghResp.Status.Description)
140-
fmt.Printf("Gitlab:\t\t\t\t%s\n", gitlabResp.Result.StatusOverall.Status)
141-
fmt.Printf("Docker:\t\t\t\t%s\n", dockerResp.Result.StatusOverall.Status)
142-
if !cciFl {
143-
fmt.Printf("Cloudflare:\t\t%s%s\t%s\n", cfResp.Status.Indicator, cfTabs, cfResp.Status.Description)
144-
fmt.Printf("Linode:\t\t%s%s\t%s\n", linodeResp.Status.Indicator, linodeTabs, linodeResp.Status.Description)
145-
fmt.Printf("DigitalOcean:\t%s%s\t%s\n", doResp.Status.Indicator, doTabs, doResp.Status.Description)
146-
}
39+
fmt.Println(status)
14740
},
14841
}
14942
)

arc/statuses/circleci.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package statuses
2+
3+
/*
4+
* Register the CircleCI status page.
5+
*/
6+
func init() {
7+
RegisterStatusPageIOPage("circleci", "https://status.circleci.com/api/v2/status.json")
8+
}

arc/statuses/cloudflare.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package statuses
2+
3+
/*
4+
* Register the CircleCI status page.
5+
*/
6+
func init() {
7+
RegisterStatusPageIOPage("cloudflare", "https://www.cloudflarestatus.com/api/v2/status.json")
8+
}

arc/statuses/digitalocean.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package statuses
2+
3+
/*
4+
* Register the CircleCI status page.
5+
*/
6+
func init() {
7+
RegisterStatusPageIOPage("digitalocean", "https://status.digitalocean.com/api/v2/status.json")
8+
}

arc/statuses/docker.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package statuses
2+
3+
/*
4+
* Register the Docker (company) status page.
5+
*/
6+
func init() {
7+
RegisterStatusIOPage("docker", "https://www.dockerstatus.com/1.0/status/533c6539221ae15e3f000031")
8+
}

arc/statuses/errors.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package statuses
2+
3+
import "fmt"
4+
5+
/*
6+
* NameTakenError occurs when a status page is registered with a name that is
7+
* already registered.
8+
*/
9+
type NameTakenError struct {
10+
Name string
11+
}
12+
13+
/*
14+
* Error returns the string representation of NameTakenError.
15+
*/
16+
func (e *NameTakenError) Error() string {
17+
return fmt.Sprintf("Failed to register the name %s. It has already been taken.", e.Name)
18+
}
19+
20+
/*
21+
* newNameTakenError creates a new NameTakenError.
22+
*/
23+
func newNameTakenError(name string) *NameTakenError {
24+
return &NameTakenError{Name: name}
25+
}

arc/statuses/github.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package statuses
2+
3+
/*
4+
* Register the CircleCI status page.
5+
*/
6+
func init() {
7+
RegisterStatusPageIOPage("github", "https://www.githubstatus.com/api/v2/status.json")
8+
}

arc/statuses/gitlab.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package statuses
2+
3+
/*
4+
* Register the Docker (company) status page.
5+
*/
6+
func init() {
7+
RegisterStatusIOPage("gitlab", "https://status.gitlab.com/1.0/status/5b36dc6502d06804c08349f7")
8+
}

arc/statuses/linode.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package statuses
2+
3+
/*
4+
* Register the CircleCI status page.
5+
*/
6+
func init() {
7+
RegisterStatusPageIOPage("linode", "https://status.linode.com/api/v2/status.json")
8+
}

arc/statuses/status.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package statuses
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
)
7+
8+
// This is how the package keeps track of all the status pages that it knows
9+
// about.
10+
var registeredPages map[string]StatusPage = map[string]StatusPage{}
11+
12+
/*
13+
* GetPageURL returns a status page's API URL.
14+
*/
15+
func Page(name string) (StatusPage, error) {
16+
17+
sp, ok := registeredPages[name]
18+
if !ok {
19+
return nil, fmt.Errorf("Not a registered page.")
20+
}
21+
22+
return sp, nil
23+
}
24+
25+
/*
26+
* registerPage adds a new status page to the list for a specific company /
27+
* provider.
28+
*
29+
* name - should be a unique slug
30+
*/
31+
func registerPage(provider StatusPage) error {
32+
33+
name := provider.Name()
34+
35+
// If the name has already been used.
36+
if _, ok := registeredPages[name]; ok {
37+
return newNameTakenError(name)
38+
}
39+
40+
// If the URL provided is no good.
41+
if _, err := url.Parse(provider.URL()); err != nil {
42+
return err
43+
}
44+
45+
registeredPages[name] = provider
46+
47+
return nil
48+
}

0 commit comments

Comments
 (0)