Skip to content

Commit

Permalink
move listSupportBundles query to go
Browse files Browse the repository at this point in the history
  • Loading branch information
sgalsaleh committed Jul 27, 2020
1 parent e147792 commit 9173770
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 54 deletions.
1 change: 1 addition & 0 deletions kotsadm/pkg/apiserver/server.go
Expand Up @@ -67,6 +67,7 @@ func Start() {
r.Path("/api/v1/troubleshoot").Methods("OPTIONS", "GET").HandlerFunc(handlers.GetDefaultTroubleshoot)
r.Path("/api/v1/troubleshoot/{appSlug}").Methods("OPTIONS", "GET").HandlerFunc(handlers.GetTroubleshoot)
r.Path("/api/v1/troubleshoot/{appId}/{bundleId}").Methods("OPTIONS", "PUT").HandlerFunc(handlers.UploadSupportBundle)
r.Path("/api/v1/troubleshoot/app/{appSlug}/supportbundles").Methods("OPTIONS", "GET").HandlerFunc(handlers.ListSupportBundles)
r.Path("/api/v1/troubleshoot/supportbundle/{bundleId}/files").Methods("OPTIONS", "GET").HandlerFunc(handlers.GetSupportBundleFiles)
r.Path("/api/v1/troubleshoot/supportbundle/{bundleId}/redactions").Methods("OPTIONS", "GET").HandlerFunc(handlers.GetSupportBundleRedactions)
r.Path("/api/v1/troubleshoot/supportbundle/{bundleId}/redactions").Methods("PUT").HandlerFunc(handlers.SetSupportBundleRedactions)
Expand Down
95 changes: 95 additions & 0 deletions kotsadm/pkg/handlers/troubleshoot.go
Expand Up @@ -10,8 +10,10 @@ import (
"net/url"
"os"
"strings"
"time"

"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/replicatedhq/kots/kotsadm/pkg/app"
"github.com/replicatedhq/kots/kotsadm/pkg/kotsutil"
"github.com/replicatedhq/kots/kotsadm/pkg/license"
Expand All @@ -21,6 +23,7 @@ import (
"github.com/replicatedhq/kots/kotsadm/pkg/session"
"github.com/replicatedhq/kots/kotsadm/pkg/snapshot"
"github.com/replicatedhq/kots/kotsadm/pkg/supportbundle"
"github.com/replicatedhq/kots/kotsadm/pkg/supportbundle/types"
"github.com/replicatedhq/kots/kotsadm/pkg/version"
"github.com/replicatedhq/kots/pkg/template"
troubleshootanalyze "github.com/replicatedhq/troubleshoot/pkg/analyze"
Expand All @@ -43,6 +46,23 @@ type GetSupportBundleFilesResponse struct {
Error string `json:"error,omitempty"`
}

type ListSupportBundlesResponse struct {
SupportBundles []ResponseSupportBundle `json:"supportBundles"`
}
type ResponseSupportBundle struct {
ID string `json:"id"`
Slug string `json:"slug"`
AppID string `json:"appId"`
Name string `json:"name"`
Size float64 `json:"size"`
Status string `json:"status"`
CreatedAt time.Time `json:"createdAt"`
UploadedAt *time.Time `json:"uploadedAt"`
IsArchived bool `json:"isArchived"`
LicenseType string `json:"licenseType,omitempty"`
Analysis *types.SupportBundleAnalysis `json:"analysis"`
}

type GetSupportBundleRedactionsResponse struct {
Redactions redact2.RedactionList `json:"redactions"`

Expand Down Expand Up @@ -99,6 +119,81 @@ func GetSupportBundleFiles(w http.ResponseWriter, r *http.Request) {
JSON(w, 200, getSupportBundleFilesResponse)
}

func ListSupportBundles(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(200)
return
}

sess, err := session.Parse(r.Header.Get("Authorization"))
if err != nil {
logger.Error(err)
w.WriteHeader(401)
return
}

// we don't currently have roles, all valid tokens are valid sessions
if sess == nil || sess.ID == "" {
logger.Error(err)
w.WriteHeader(401)
return
}

appSlug := mux.Vars(r)["appSlug"]

a, err := app.GetFromSlug(appSlug)
if err != nil {
logger.Error(err)
w.WriteHeader(500)
return
}

supportBundles, err := supportbundle.List(a.ID)
if err != nil {
logger.Error(err)
w.WriteHeader(500)
return
}

responseSupportBundles := []ResponseSupportBundle{}
for _, bundle := range supportBundles {
licenseType, err := supportbundle.GetLicenseType(bundle.ID)
if err != nil {
logger.Error(errors.Wrapf(err, "failed to get license type for bundle %s", bundle.Slug))
}

analysis, err := supportbundle.GetBundleAnalysis(bundle.ID)
if err != nil {
logger.Error(errors.Wrapf(err, "failed to get analysis for bundle %s", bundle.Slug))
}

responseSupportBundle := ResponseSupportBundle{
ID: bundle.ID,
Slug: bundle.Slug,
AppID: bundle.AppID,
Name: bundle.Name,
Size: bundle.Size,
Status: bundle.Status,
CreatedAt: bundle.CreatedAt,
UploadedAt: bundle.UploadedAt,
IsArchived: bundle.IsArchived,
LicenseType: licenseType,
Analysis: analysis,
}

responseSupportBundles = append(responseSupportBundles, responseSupportBundle)
}

listSupportBundlesResponse := ListSupportBundlesResponse{
SupportBundles: responseSupportBundles,
}

JSON(w, 200, listSupportBundlesResponse)
}

func DownloadSupportBundle(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")
Expand Down
4 changes: 2 additions & 2 deletions kotsadm/pkg/online/online.go
Expand Up @@ -9,15 +9,15 @@ import (
"time"

"github.com/pkg/errors"
kotsadmconfig "github.com/replicatedhq/kots/kotsadm/pkg/config"
"github.com/replicatedhq/kots/kotsadm/pkg/downstream"
"github.com/replicatedhq/kots/kotsadm/pkg/kotsutil"
"github.com/replicatedhq/kots/kotsadm/pkg/logger"
"github.com/replicatedhq/kots/kotsadm/pkg/persistence"
"github.com/replicatedhq/kots/kotsadm/pkg/preflight"
"github.com/replicatedhq/kots/kotsadm/pkg/task"
"github.com/replicatedhq/kots/kotsadm/pkg/updatechecker"
"github.com/replicatedhq/kots/kotsadm/pkg/version"
"github.com/replicatedhq/kots/kotsadm/pkg/downstream"
kotsadmconfig "github.com/replicatedhq/kots/kotsadm/pkg/config"
"github.com/replicatedhq/kots/pkg/pull"
"go.uber.org/zap"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down
8 changes: 4 additions & 4 deletions kotsadm/pkg/snapshot/types/types.go
Expand Up @@ -111,8 +111,8 @@ type SnapshotError struct {
}

type VolumeSummary struct {
VolumeCount int `json:"volumeCount"`
VolumeSuccessCount int `json:"volumeSuccessCount"`
VolumeBytes int64 `json:"volumeBytes"`
VolumeSizeHuman string `json:"volumeSizeHuman"`
VolumeCount int `json:"volumeCount"`
VolumeSuccessCount int `json:"volumeSuccessCount"`
VolumeBytes int64 `json:"volumeBytes"`
VolumeSizeHuman string `json:"volumeSizeHuman"`
}
69 changes: 69 additions & 0 deletions kotsadm/pkg/supportbundle/analyze.go
@@ -1,11 +1,16 @@
package supportbundle

import (
"database/sql"
"encoding/json"
"os"
"strconv"
"time"

"github.com/pkg/errors"
"github.com/replicatedhq/kots/kotsadm/pkg/logger"
"github.com/replicatedhq/kots/kotsadm/pkg/persistence"
"github.com/replicatedhq/kots/kotsadm/pkg/supportbundle/types"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
"github.com/segmentio/ksuid"
)
Expand All @@ -28,6 +33,70 @@ func SetBundleAnalysis(id string, insights []byte) error {
return nil
}

func GetBundleAnalysis(id string) (*types.SupportBundleAnalysis, error) {
db := persistence.MustGetPGSession()
query := `SELECT id, error, max_severity, insights, created_at FROM supportbundle_analysis where supportbundle_id = $1`
row := db.QueryRow(query, id)

var _error sql.NullString
var maxSeverity sql.NullString
var insightsStr sql.NullString

a := &types.SupportBundleAnalysis{}
if err := row.Scan(&a.ID, &_error, &maxSeverity, &insightsStr, &a.CreatedAt); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, errors.Wrap(err, "failed to scan")
}

a.Error = _error.String
a.MaxSeverity = maxSeverity.String

if insightsStr.Valid {
type Insight struct {
Primary string `json:"primary"`
Detail string `json:"detail"`
}
type Labels struct {
IconUri string `json:"iconUri"`
IconKey string `json:"iconKey"`
DesiredPosition string `json:"desiredPosition"`
}
type DBInsight struct {
Name string `json:"name"`
Severity string `json:"severity"`
Insight Insight `json:"insight"`
Labels Labels `json:"labels"`
}

dbInsights := []DBInsight{}
if err := json.Unmarshal([]byte(insightsStr.String), &dbInsights); err != nil {
logger.Error(errors.Wrap(err, "failed to unmarshal db insights"))
dbInsights = []DBInsight{}
}

insights := []types.SupportBundleInsight{}
for _, dbInsight := range dbInsights {
desiredPosition, _ := strconv.ParseFloat(dbInsight.Labels.DesiredPosition, 64)
insight := types.SupportBundleInsight{
Key: dbInsight.Name,
Severity: dbInsight.Severity,
Primary: dbInsight.Insight.Primary,
Detail: dbInsight.Insight.Detail,
Icon: dbInsight.Labels.IconUri,
IconKey: dbInsight.Labels.IconKey,
DesiredPosition: desiredPosition,
}
insights = append(insights, insight)
}

a.Insights = insights
}

return a, nil
}

func InjectDefaultAnalyzers(analyzer *troubleshootv1beta1.Analyzer) error {
if err := injectAPIReplicaAnalyzer(analyzer); err != nil {
return errors.Wrap(err, "failed to inject api replica analyzer")
Expand Down
65 changes: 65 additions & 0 deletions kotsadm/pkg/supportbundle/supportbundle.go
@@ -1,6 +1,7 @@
package supportbundle

import (
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
Expand All @@ -13,9 +14,47 @@ import (
"github.com/pkg/errors"
"github.com/replicatedhq/kots/kotsadm/pkg/persistence"
"github.com/replicatedhq/kots/kotsadm/pkg/supportbundle/types"
kotsv1beta1 "github.com/replicatedhq/kots/kotskinds/apis/kots/v1beta1"
"github.com/segmentio/ksuid"
"k8s.io/client-go/kubernetes/scheme"
)

func List(appID string) ([]*types.SupportBundle, error) {
db := persistence.MustGetPGSession()
query := `select id, slug, watch_id, name, size, status, created_at, uploaded_at, is_archived from supportbundle where watch_id = $1 order by created_at desc`

rows, err := db.Query(query, appID)
if err != nil {
return nil, errors.Wrap(err, "failed to query")
}

supportBundles := []*types.SupportBundle{}

for rows.Next() {
var name sql.NullString
var size sql.NullFloat64
var uploadedAt sql.NullTime
var isArchived sql.NullBool

s := &types.SupportBundle{}
if err := rows.Scan(&s.ID, &s.Slug, &s.AppID, &name, &size, &s.Status, &s.CreatedAt, &uploadedAt, &isArchived); err != nil {
return nil, errors.Wrap(err, "failed to scan")
}

s.Name = name.String
s.Size = size.Float64
s.IsArchived = isArchived.Bool

if uploadedAt.Valid {
s.UploadedAt = &uploadedAt.Time
}

supportBundles = append(supportBundles, s)
}

return supportBundles, nil
}

func CreateBundle(requestedID string, appID string, archivePath string) (*types.SupportBundle, error) {
fi, err := os.Stat(archivePath)
if err != nil {
Expand Down Expand Up @@ -105,3 +144,29 @@ func GetFilesContents(bundleID string, filenames []string) (map[string][]byte, e

return files, nil
}

func GetLicenseType(id string) (string, error) {
db := persistence.MustGetPGSession()
query := `SELECT app_version.kots_license FROM supportbundle LEFT JOIN app_version ON supportbundle.watch_id = app_version.app_id where supportbundle.id = $1`
row := db.QueryRow(query, id)

var licenseStr sql.NullString
if err := row.Scan(&licenseStr); err != nil {
if err == sql.ErrNoRows {
return "", nil
}
return "", errors.Wrap(err, "failed to scan")
}

if licenseStr.Valid {
decode := scheme.Codecs.UniversalDeserializer().Decode
obj, _, err := decode([]byte(licenseStr.String), nil, nil)
if err != nil {
return "", errors.Wrap(err, "failed to decode license yaml")
}
license := obj.(*kotsv1beta1.License)
return license.Spec.LicenseType, nil
}

return "", nil
}
32 changes: 31 additions & 1 deletion kotsadm/pkg/supportbundle/types/types.go
@@ -1,7 +1,37 @@
package types

import (
"time"
)

type SupportBundle struct {
ID string `json:"id"`
ID string `json:"id"`
Slug string `json:"slug"`
AppID string `json:"appId"`
Name string `json:"name"`
Size float64 `json:"size"`
Status string `json:"status"`
CreatedAt time.Time `json:"createdAt"`
UploadedAt *time.Time `json:"uploadedAt"`
IsArchived bool `json:"isArchived"`
}

type SupportBundleAnalysis struct {
ID string `json:"id"`
Error string `json:"error"`
MaxSeverity string `json:"maxSeverity"`
Insights []SupportBundleInsight `json:"insights"`
CreatedAt time.Time `json:"createdAt"`
}

type SupportBundleInsight struct {
Key string `json:"key"`
Severity string `json:"severity"`
Primary string `json:"primary"`
Detail string `json:"detail"`
Icon string `json:"icon"`
IconKey string `json:"iconKey"`
DesiredPosition float64 `json:"desiredPosition"`
}

type FileTree struct {
Expand Down

0 comments on commit 9173770

Please sign in to comment.