Skip to content

Commit

Permalink
⭐ github.packages resource (#4303)
Browse files Browse the repository at this point in the history
* feat: github.packages resource

* define consts for visibility
  • Loading branch information
slntopp authored Jul 2, 2024
1 parent 502dcd0 commit 37b604d
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 1 deletion.
11 changes: 11 additions & 0 deletions providers/github/resources/github.lr
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,17 @@ private github.package @defaults("id name") {
repository() github.repository
}

// GitHub packages
github.packages {
[]github.package
// Public packages
public() []github.package
// Private packages
private() []github.package
// Internal packages
internal() []github.package
}

// GitHub repository
private github.repository @defaults("fullName") {
init(name string) // can only be used when logged in to github as a user
Expand Down
148 changes: 148 additions & 0 deletions providers/github/resources/github.lr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions providers/github/resources/github.lr.manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,13 @@ resources:
visibility: {}
is_private: true
min_mondoo_version: 6.11.0
github.packages:
fields:
internal: {}
list: {}
private: {}
public: {}
min_mondoo_version: 9.0.0
github.release:
fields:
name: {}
Expand Down
111 changes: 110 additions & 1 deletion providers/github/resources/github_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,23 @@

package resources

import "strconv"
import (
"context"
"strconv"
"strings"

"github.com/google/go-github/v62/github"
"go.mondoo.com/cnquery/v11/llx"
"go.mondoo.com/cnquery/v11/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/v11/providers-sdk/v1/util/convert"
"go.mondoo.com/cnquery/v11/providers/github/connection"
)

const (
GITHUB_PACKAGE_VISIBILITY_PUBLIC = "public"
GITHUB_PACKAGE_VISIBILITY_PRIVATE = "private"
GITHUB_PACKAGE_VISIBILITY_INTERNAL = "internal"
)

func (g *mqlGithubPackage) id() (string, error) {
if g.Id.Error != nil {
Expand All @@ -12,3 +28,96 @@ func (g *mqlGithubPackage) id() (string, error) {
id := g.Id.Data
return "github.package/" + strconv.FormatInt(id, 10), nil
}

func (g *mqlGithubPackages) id() (string, error) {
return "github.packages", nil
}

func (g *mqlGithubPackages) list() ([]any, error) {
return newMqlGithubPackages(g.MqlRuntime, nil)
}

func (g *mqlGithubPackages) public() ([]any, error) {
visibility := GITHUB_PACKAGE_VISIBILITY_PUBLIC
return newMqlGithubPackages(g.MqlRuntime, &visibility)
}

func (g *mqlGithubPackages) private() ([]any, error) {
visibility := GITHUB_PACKAGE_VISIBILITY_PRIVATE
return newMqlGithubPackages(g.MqlRuntime, &visibility)
}

func (g *mqlGithubPackages) internal() ([]any, error) {
visibility := GITHUB_PACKAGE_VISIBILITY_INTERNAL
return newMqlGithubPackages(g.MqlRuntime, &visibility)
}

func newMqlGithubPackages(runtime *plugin.Runtime, visibility *string) ([]any, error) {
conn := runtime.Connection.(*connection.GithubConnection)
orgId, err := conn.Organization()
if err != nil {
return nil, err
}

pkgTypes := []string{"npm", "maven", "rubygems", "docker", "nuget", "container"}
res := []any{}
for i := range pkgTypes {
listOpts := &github.PackageListOptions{
ListOptions: github.ListOptions{PerPage: paginationPerPage},
PackageType: github.String(pkgTypes[i]),
Visibility: visibility,
}

var allPackages []*github.Package
for {
packages, resp, err := conn.Client().Organizations.ListPackages(context.Background(), orgId.Name, listOpts)
if err != nil {
if strings.Contains(err.Error(), "404") {
return nil, nil
}
return nil, err
}
allPackages = append(allPackages, packages...)
if resp.NextPage == 0 {
break
}
listOpts.Page = resp.NextPage
}

for i := range allPackages {
p := allPackages[i]

owner, err := NewResource(runtime, "github.user", map[string]*llx.RawData{
"id": llx.IntData(p.GetOwner().GetID()),
"login": llx.StringData(p.GetOwner().GetLogin()),
})
if err != nil {
return nil, err
}

mqlGhPackage, err := CreateResource(runtime, "github.package", map[string]*llx.RawData{
"id": llx.IntDataPtr(p.ID),
"name": llx.StringDataPtr(p.Name),
"packageType": llx.StringDataPtr(p.PackageType),
"owner": llx.ResourceData(owner, owner.MqlName()),
"createdAt": llx.TimeDataPtr(githubTimestamp(p.CreatedAt)),
"updatedAt": llx.TimeDataPtr(githubTimestamp(p.UpdatedAt)),
"versionCount": llx.IntDataPtr(p.VersionCount),
"visibility": llx.StringDataPtr(p.Visibility),
})
if err != nil {
return nil, err
}
pkg := mqlGhPackage.(*mqlGithubPackage)

// NOTE: we need to fetch repo separately because the Github repo object is not complete, instead of
// call the repo fetching all the time, we make this lazy loading
if p.Repository != nil && p.Repository.Name != nil {
pkg.packageRepository = convert.ToString(p.Repository.Name)
}
res = append(res, pkg)
}
}

return res, nil
}
9 changes: 9 additions & 0 deletions providers/github/resources/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,12 @@ func TestResource_Github(t *testing.T) {
assert.Equal(t, string(""), res[0].Data.Value)
})
}

func TestResource_GithubPackages(t *testing.T) {
t.Run("github packages", func(t *testing.T) {
res := x.TestQuery(t, "github.packages")
assert.NotEmpty(t, res)
assert.Empty(t, res[0].Result().Error)
assert.Equal(t, string(""), res[0].Data.Value)
})
}

0 comments on commit 37b604d

Please sign in to comment.