diff --git a/core/aptrust_client_v3.go b/core/aptrust_client_v3.go index c955365..94f0206 100644 --- a/core/aptrust_client_v3.go +++ b/core/aptrust_client_v3.go @@ -178,8 +178,8 @@ func (client *APTrustClientV3) connect() error { registryClient, err := apt_network.NewRegistryClient( client.config.Url, client.version, - client.config.UserID, - client.config.APIToken, + client.config.GetUserID(), + client.config.GetAPIToken(), Dart.Log, ) client.registry = registryClient diff --git a/core/remote_repo_client.go b/core/remote_repo_client.go index d1d936a..c48302b 100644 --- a/core/remote_repo_client.go +++ b/core/remote_repo_client.go @@ -59,26 +59,3 @@ func GetRemoteRepoClient(repo *RemoteRepository) (RemoteRepoClient, error) { } return constructor(repo), nil } - -// // GetViableRepoClients returns a list of RemoteRepoClients that have -// // proven they can connect to the repositories they're supposed to talk to. -// func GetViableRepoClients() ([]RemoteRepoClient, error) { -// clients := make([]RemoteRepoClient, 0) -// result := ObjList(constants.TypeRemoteRepository, "obj_name", 100, 0) -// if result.Error != nil { -// Dart.Log.Errorf("GetViableRepoClients - Error fetching repo list: %s", result.Error.Error()) -// return nil, result.Error -// } -// for _, repo := range result.RemoteRepositories { -// err := repo.TestConnection() -// if err == nil { -// newClient, clientErr := GetRemoteRepoClient(repo) -// if clientErr != nil { -// Dart.Log.Errorf("GetViableRepoClients - Error creating client for repo '%s': %s", repo.Name, clientErr.Error()) -// } else { -// clients = append(clients, newClient) -// } -// } -// } -// return clients, nil -// } diff --git a/core/remote_repository.go b/core/remote_repository.go index 651814f..ac868df 100644 --- a/core/remote_repository.go +++ b/core/remote_repository.go @@ -2,6 +2,7 @@ package core import ( "fmt" + "os" "strings" "github.com/APTrust/dart-runner/constants" @@ -38,6 +39,44 @@ func NewRemoteRepository() *RemoteRepository { } } +// GetUserID returns the UserID for logging into this remote repo. +// If the UserID comes from an environment variable, this returns +// the value of the ENV var. Otherwise, it returns the value of +// this object's UserID property. +// +// When authenticating with a remote repo, call this instead of +// accessing UserID directly. +func (repo *RemoteRepository) GetUserID() string { + if strings.HasPrefix(repo.UserID, "env:") { + parts := strings.SplitN(repo.UserID, ":", 2) + userID := os.Getenv(parts[1]) + if userID == "" { + Dart.Log.Warningf("UserID for repo '%s' is set to env var '%s', but the env var has no value", repo.Name, parts[1]) + } + return userID + } + return repo.UserID +} + +// GetUserAPIToken returns the API token for logging into this remote repo. +// If the token comes from an environment variable, this returns +// the value of the ENV var. Otherwise, it returns the value of +// this object's APIToken property. +// +// When authenticating with a remote repo, call this instead of +// accessing APIToken directly. +func (repo *RemoteRepository) GetAPIToken() string { + if strings.HasPrefix(repo.APIToken, "env:") { + parts := strings.SplitN(repo.APIToken, ":", 2) + token := os.Getenv(parts[1]) + if token == "" { + Dart.Log.Warningf("API token for repo '%s' is set to env var '%s', but the env var has no value", repo.Name, parts[1]) + } + return token + } + return repo.APIToken +} + // HasPlaintextAPIToken returns true if this repo's API token // is non-empty and does not come from an environment variable. func (repo *RemoteRepository) HasPlaintextAPIToken() bool { @@ -120,3 +159,20 @@ func (repo *RemoteRepository) TestConnection() error { } return client.TestConnection() } + +// ReportsAvailable returns a list of reports that can be retrieved +// from this remote repository. +func (repo *RemoteRepository) ReportsAvailable() ([]util.NameValuePair, error) { + reports := make([]util.NameValuePair, 0) + if util.LooksLikeUUID(repo.PluginID) { + return reports, fmt.Errorf("no client exists for this repo because plugin id is not a uuid") + } + client, err := GetRemoteRepoClient(repo) + if err != nil { + return reports, err + } + if client == nil { + return reports, fmt.Errorf("client for repo %s is nil", repo.Name) + } + return client.AvailableHTMLReports(), nil +} diff --git a/core/remote_repository_test.go b/core/remote_repository_test.go index eef7034..74bef36 100644 --- a/core/remote_repository_test.go +++ b/core/remote_repository_test.go @@ -2,6 +2,7 @@ package core_test import ( "database/sql" + "os" "testing" "github.com/APTrust/dart-runner/constants" @@ -149,3 +150,25 @@ func TestHasPlaintextAPIToken(t *testing.T) { repo.APIToken = "this-here-is-secret" assert.True(t, repo.HasPlaintextAPIToken()) } + +func TestRepoGetUserID(t *testing.T) { + os.Setenv("dart-repo-user-test-id", "Helen Talboys") + defer os.Unsetenv("dart-repo-user-test-id") + repo := &core.RemoteRepository{} + repo.UserID = "Lucy Graham" + assert.Equal(t, "Lucy Graham", repo.GetUserID()) + + repo.UserID = "env:dart-repo-user-test-id" + assert.Equal(t, "Helen Talboys", repo.GetUserID()) +} + +func TestRepoGetAPIToken(t *testing.T) { + os.Setenv("dart-repo-test-token", "George Talboys") + defer os.Unsetenv("dart-repo-test-token") + repo := &core.RemoteRepository{} + repo.APIToken = "Robert Audley" + assert.Equal(t, "Robert Audley", repo.GetAPIToken()) + + repo.APIToken = "env:dart-repo-test-token" + assert.Equal(t, "George Talboys", repo.GetAPIToken()) +} diff --git a/server/controllers/dashboard_controller.go b/server/controllers/dashboard_controller.go index 9f2e543..ac59b92 100644 --- a/server/controllers/dashboard_controller.go +++ b/server/controllers/dashboard_controller.go @@ -1,13 +1,22 @@ package controllers import ( + "encoding/json" "net/http" "github.com/APTrust/dart-runner/constants" "github.com/APTrust/dart-runner/core" + "github.com/APTrust/dart-runner/util" "github.com/gin-gonic/gin" ) +type DashboardReport struct { + RepositoryID string `json:"repositoryId"` + RepositoryName string `json:"repositoryName"` + ReportName string `json:"reportName"` + ReportDescription string `json:"reportDescription"` +} + // DashboardShow shows the DART dashboard. This is essentially // DART's homepage. // @@ -22,10 +31,16 @@ func DashboardShow(c *gin.Context) { return } - // TODO: Repo ids and report names + var reportListJson []byte + reports, err := getAvailableReports() + if len(reports) > 0 { + reportListJson, err = json.Marshal(reports) + } data := gin.H{ - "jobs": result.Jobs, + "jobs": result.Jobs, + "reports": string(reportListJson), + "reportsErr": err, } c.HTML(http.StatusOK, "dashboard/show.html", data) @@ -59,6 +74,33 @@ func DashboardGetReport(c *gin.Context) { c.JSON(status, data) } +func getAvailableReports() ([]DashboardReport, error) { + reports := make([]DashboardReport, 0) + result := core.ObjList(constants.TypeRemoteRepository, "obj_name", 100, 0) + if result.Error != nil { + return reports, result.Error + } + for _, repo := range result.RemoteRepositories { + if util.LooksLikeUUID(repo.PluginID) { + available, err := repo.ReportsAvailable() + if err != nil { + core.Dart.Log.Errorf("Error getting report list for repo %s (%s): %v", repo.Name, repo.ID, err) + continue + } + for _, report := range available { + report := DashboardReport{ + RepositoryID: repo.ID, + RepositoryName: repo.Name, + ReportName: report.Name, + ReportDescription: report.Value, + } + reports = append(reports, report) + } + } + } + return reports, nil +} + func getRepoReport(remoteRepoID, reportName string) (string, error) { result := core.ObjFind(remoteRepoID) if result.Error != nil { diff --git a/server/views/dashboard/show.html b/server/views/dashboard/show.html index c2598dc..b0d495a 100644 --- a/server/views/dashboard/show.html +++ b/server/views/dashboard/show.html @@ -31,24 +31,18 @@ -{{ range $index, $reports := .reportRows }} -
+ +
- {{ range $ix, $report := .reports }} -
-
-
{{ $report.title }}
-
-
-
-
- {{ end }} - -
+ -{{ end }} {{ template "partials/page_footer.html" .}}