Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* move get app dashboard query to go
- Loading branch information
Showing
7 changed files
with
507 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package appstatus | ||
|
||
import ( | ||
"database/sql" | ||
"encoding/json" | ||
"time" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/persistence" | ||
) | ||
|
||
type AppStatus struct { | ||
AppID string `json:"appId"` | ||
UpdatedAt time.Time `json:"updatedAt"` | ||
ResourceStates []ResourceState `json:"resourceStates"` | ||
State State `json:"state"` | ||
} | ||
|
||
type ResourceState struct { | ||
Kind string `json:"kind"` | ||
Name string `json:"name"` | ||
Namespace string `json:"namespace"` | ||
State State `json:"state"` | ||
} | ||
|
||
type State string | ||
|
||
const ( | ||
StateReady State = "ready" | ||
StateDegraded State = "degraded" | ||
StateUnavailable State = "unavailable" | ||
StateMissing State = "missing" | ||
) | ||
|
||
func Get(appID string) (*AppStatus, error) { | ||
db := persistence.MustGetPGSession() | ||
query := `select resource_states, updated_at from app_status where app_id = $1` | ||
row := db.QueryRow(query, appID) | ||
|
||
var updatedAt sql.NullTime | ||
var resourceStatesStr sql.NullString | ||
|
||
if err := row.Scan(&resourceStatesStr, &updatedAt); err != nil { | ||
if err == sql.ErrNoRows { | ||
return &AppStatus{ | ||
AppID: appID, | ||
UpdatedAt: time.Time{}, | ||
ResourceStates: []ResourceState{}, | ||
State: StateMissing, | ||
}, nil | ||
} | ||
return nil, errors.Wrap(err, "failed to scan") | ||
} | ||
|
||
appStatus := AppStatus{ | ||
AppID: appID, | ||
} | ||
|
||
if updatedAt.Valid { | ||
appStatus.UpdatedAt = updatedAt.Time | ||
} | ||
|
||
if resourceStatesStr.Valid { | ||
var resourceStates []ResourceState | ||
if err := json.Unmarshal([]byte(resourceStatesStr.String), &resourceStates); err != nil { | ||
return nil, errors.Wrap(err, "failed to unmarshal resource states") | ||
} | ||
appStatus.ResourceStates = resourceStates | ||
} | ||
|
||
appStatus.State = getState(appStatus.ResourceStates) | ||
|
||
return &appStatus, nil | ||
} | ||
|
||
func getState(resourceStates []ResourceState) State { | ||
if len(resourceStates) == 0 { | ||
return StateMissing | ||
} | ||
max := StateReady | ||
for _, resourceState := range resourceStates { | ||
max = minState(max, resourceState.State) | ||
} | ||
return max | ||
} | ||
|
||
func minState(a State, b State) State { | ||
if a == StateMissing || b == StateMissing { | ||
return StateMissing | ||
} | ||
if a == StateUnavailable || b == StateUnavailable { | ||
return StateUnavailable | ||
} | ||
if a == StateDegraded || b == StateDegraded { | ||
return StateDegraded | ||
} | ||
if a == StateReady || b == StateReady { | ||
return StateReady | ||
} | ||
return StateMissing | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package handlers | ||
|
||
import ( | ||
"net/http" | ||
"os" | ||
|
||
"github.com/gorilla/mux" | ||
"github.com/pkg/errors" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/app" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/appstatus" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/downstream" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/kotsadmparams" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/logger" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/version" | ||
) | ||
|
||
type GetAppDashboardResponse struct { | ||
AppStatus *appstatus.AppStatus `json:"appStatus"` | ||
Metrics []version.MetricChart `json:"metrics"` | ||
PrometheusAddress string `json:"prometheusAddress"` | ||
} | ||
|
||
func GetAppDashboard(w http.ResponseWriter, r *http.Request) { | ||
w.Header().Set("Access-Control-Allow-Origin", "*") | ||
w.Header().Set("Access-Control-Allow-Headers", "content-type, origin, accept, authorization") | ||
|
||
if r.Method == "OPTIONS" { | ||
w.WriteHeader(http.StatusOK) | ||
return | ||
} | ||
|
||
if err := requireValidSession(w, r); err != nil { | ||
logger.Error(err) | ||
return | ||
} | ||
|
||
appSlug := mux.Vars(r)["appSlug"] | ||
clusterID := mux.Vars(r)["clusterId"] | ||
|
||
a, err := app.GetFromSlug(appSlug) | ||
if err != nil { | ||
logger.Error(err) | ||
w.WriteHeader(500) | ||
return | ||
} | ||
|
||
appStatus, err := appstatus.Get(a.ID) | ||
if err != nil { | ||
logger.Error(err) | ||
w.WriteHeader(500) | ||
return | ||
} | ||
|
||
parentSequence, err := downstream.GetParentSequence(a.ID, clusterID) | ||
if err != nil { | ||
logger.Error(err) | ||
w.WriteHeader(500) | ||
return | ||
} | ||
|
||
metrics, err := version.GetMetricCharts(a.ID, parentSequence) | ||
if err != nil { | ||
logger.Error(errors.Wrap(err, "failed to get metric charts")) | ||
metrics = []version.MetricChart{} | ||
} | ||
|
||
prometheusAddress, err := kotsadmparams.Get("PROMETHEUS_ADDRESS") | ||
if err != nil { | ||
logger.Error(errors.Wrap(err, "failed to get prometheus address from kotsadm params")) | ||
} | ||
if prometheusAddress == "" { | ||
prometheusAddress = os.Getenv("PROMETHEUS_ADDRESS") | ||
} | ||
|
||
getAppDashboardResponse := GetAppDashboardResponse{ | ||
AppStatus: appStatus, | ||
Metrics: metrics, | ||
PrometheusAddress: prometheusAddress, | ||
} | ||
|
||
JSON(w, 200, getAppDashboardResponse) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package kotsadmparams | ||
|
||
import ( | ||
"database/sql" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/replicatedhq/kots/kotsadm/pkg/persistence" | ||
) | ||
|
||
func Get(name string) (string, error) { | ||
db := persistence.MustGetPGSession() | ||
query := `select value from kotsadm_params where key = $1` | ||
row := db.QueryRow(query, name) | ||
|
||
var value string | ||
if err := row.Scan(&value); err != nil { | ||
if err == sql.ErrNoRows { | ||
return "", nil | ||
} | ||
return "", errors.Wrap(err, "failed to scan") | ||
} | ||
|
||
return value, nil | ||
} |
Oops, something went wrong.