Skip to content

Commit

Permalink
Added namespace column to list repositories which are not owned by th…
Browse files Browse the repository at this point in the history
…e authenticated user (#25)
  • Loading branch information
hebestreit committed Sep 4, 2024
1 parent fb61512 commit e963a41
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 7 deletions.
43 changes: 39 additions & 4 deletions dockerhub/table_dockerhub_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package dockerhub

import (
"context"

"github.com/docker/hub-tool/pkg/hub"
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
Expand All @@ -16,8 +16,17 @@ func tableDockerHubRepository(_ context.Context) *plugin.Table {
Description: "Get details of all the repositories in your DockerHub.",
List: &plugin.ListConfig{
Hydrate: listRepositories,
KeyColumns: []*plugin.KeyColumn{
{Name: "namespace", Require: plugin.Optional, Operators: []string{"="}},
},
},
Columns: commonColumns([]*plugin.Column{
{
Name: "namespace",
Type: proto.ColumnType_STRING,
Description: "Namespace of the repository.",
Transform: transform.From(fetchNamespaceFromRepository),
},
{
Name: "name",
Type: proto.ColumnType_STRING,
Expand Down Expand Up @@ -65,9 +74,9 @@ func tableDockerHubRepository(_ context.Context) *plugin.Table {
func listRepositories(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
logger := plugin.Logger(ctx)

user, err := getUserInfo(ctx, d)
// Get namespace from "Quals" if available otherwise use the authenticated user's namespace
namespace, err := getNamespace(ctx, d)
if err != nil {
logger.Error("dockerhub_repository.getUserInfo", "error", err)
return nil, err
}

Expand All @@ -78,7 +87,7 @@ func listRepositories(ctx context.Context, d *plugin.QueryData, h *plugin.Hydrat
return nil, err
}

repositories, _, err := client.GetRepositories(user.Name)
repositories, _, err := client.GetRepositories(namespace)
if err != nil {
logger.Error("dockerhub_repository.listRepositories", "api_error", err)
return nil, err
Expand All @@ -90,3 +99,29 @@ func listRepositories(ctx context.Context, d *plugin.QueryData, h *plugin.Hydrat

return nil, nil
}

func getNamespace(ctx context.Context, d *plugin.QueryData) (string, error) {
logger := plugin.Logger(ctx)

if d.Quals["namespace"] != nil {
for _, q := range d.Quals["namespace"].Quals {
if q.Operator == "=" {
return q.Value.GetStringValue(), nil
}
}
}

user, err := getUserInfo(ctx, d)
if err != nil {
logger.Error("dockerhub_repository.getUserInfo", "error", err)
return "", err
}

return user.Name, nil
}

func fetchNamespaceFromRepository(_ context.Context, d *transform.TransformData) (interface{}, error) {
repository := d.HydrateItem.(hub.Repository)
namespace, _ := splitRepositoryName(repository.Name)
return namespace, nil
}
16 changes: 15 additions & 1 deletion dockerhub/table_dockerhub_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dockerhub

import (
"context"

"github.com/docker/hub-tool/pkg/hub"
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
Expand All @@ -18,8 +17,17 @@ func tableDockerHubTag(_ context.Context) *plugin.Table {
List: &plugin.ListConfig{
ParentHydrate: listRepositories,
Hydrate: listTags,
KeyColumns: []*plugin.KeyColumn{
{Name: "namespace", Require: plugin.Optional, Operators: []string{"="}},
},
},
Columns: commonColumns([]*plugin.Column{
{
Name: "namespace",
Type: proto.ColumnType_STRING,
Description: "Namespace of the repository.",
Transform: transform.From(fetchNamespaceFromTag),
},
{
Name: "name",
Type: proto.ColumnType_STRING,
Expand Down Expand Up @@ -98,3 +106,9 @@ func listTags(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (

return nil, nil
}

func fetchNamespaceFromTag(_ context.Context, d *transform.TransformData) (interface{}, error) {
tag := d.HydrateItem.(hub.Tag)
namespace, _ := splitRepositoryName(tag.Name)
return namespace, nil
}
14 changes: 12 additions & 2 deletions dockerhub/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package dockerhub
import (
"context"
"errors"
"os"

"github.com/docker/hub-tool/pkg/hub"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"os"
"strings"
)

func getClient(ctx context.Context, d *plugin.QueryData) (*hub.Client, error) {
Expand Down Expand Up @@ -91,3 +91,13 @@ func GetUserInfoUncached(ctx context.Context, d *plugin.QueryData, _ *plugin.Hyd

return user, nil
}

// split the repository name into namespace and repository name
func splitRepositoryName(repository string) (string, string) {
parts := strings.Split(repository, "/")
if len(parts) > 1 {
return parts[0], parts[1]
}

return "", repository
}
33 changes: 33 additions & 0 deletions docs/tables/dockerhub_repository.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ DockerHub is a cloud-based registry service that allows you to link to code repo

The `dockerhub_repository` table provides insights into repositories within DockerHub. As a DevOps engineer, explore repository-specific details through this table, including repository name, description, star count, pull count, and last updated date. Utilize it to uncover information about repositories, such as those with high pull counts, the most starred repositories, and recently updated repositories.

## Specify a namespace

The `namespace` column in the `dockerhub_repository` table represents the repository namespace. By default, the namespace is set to the name of the authenticated user. To query repositories in a different namespace (e.g. `turbot` or `library`), you can specify the namespace in the `where` clause.

## Examples

### Basic info
Expand Down Expand Up @@ -67,6 +71,35 @@ where
is_private = 1;
```

### List public repositories owned by a different account
Explore public repositories on DockerHub which are not owned by the authenticated user and can be accessed by anyone. This query can help you get detailed information about public repositories in a specific namespace.

```sql+postgres
select
name,
pull_count,
star_count,
is_private,
last_updated
from
dockerhub_repository
where
namespace = 'turbot';
```

```sql+sqlite
select
name,
pull_count,
star_count,
is_private,
last_updated
from
dockerhub_repository
where
namespace = 'turbot';
```

### List repositories with no pulls or downloads
Explore which Docker repositories have not been pulled or downloaded. This can help identify unused or less-popular repositories, enabling you to better manage your resources and focus on active repositories.

Expand Down
37 changes: 37 additions & 0 deletions docs/tables/dockerhub_tag.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ DockerHub is a cloud-based registry service that allows you to link to code repo

The `dockerhub_tag` table provides insights into the tags within DockerHub repositories. As a DevOps engineer, you can explore tag-specific details through this table, including the associated DockerHub repository, the tag name, and its manifest. Utilize this table to manage and monitor your DockerHub repositories, ensuring that all tags are up-to-date and follow your organization's naming conventions.

## Specify a namespace

The `namespace` column in the `dockerhub_tag` table represents the repository namespace. By default, the namespace is set to the name of the authenticated user. To query tags in a different namespace (e.g. `turbot` or `library`), you can specify the namespace in the `where` clause.

## Examples

### Basic info
Expand Down Expand Up @@ -71,6 +75,39 @@ where
name like 'souravthe/test%';
```

### List tags which are from a particular repository owned by a different account
Discover the segments that are from a specific repository, allowing you to analyze the status, last update, and size of these segments. This can be useful to get detailed information about public repositories in a specific namespace.

```sql+postgres
select
name,
status,
last_updater_user_name,
last_pushed,
last_pulled,
full_size
from
dockerhub_tag
where
namespace = 'turbot'
and name like 'turbot/steampipe:0.21%';
```

```sql+sqlite
select
name,
status,
last_updater_user_name,
last_pushed,
last_pulled,
full_size
from
dockerhub_tag
where
namespace = 'turbot'
and name like 'turbot/steampipe:0.21%';
```

### List tags with no pulls or downloads
Discover the segments that contain tags with no pulls or downloads in order to identify potentially unused or unpopular resources. This can be useful in optimizing resource allocation and improving overall system efficiency.

Expand Down

0 comments on commit e963a41

Please sign in to comment.