From a2b762549f0b734d4f6866fc9a04c3cea1a7f16e Mon Sep 17 00:00:00 2001 From: Anil Chandra <120965339+acx1729@users.noreply.github.com> Date: Sat, 21 Dec 2024 00:14:30 -0500 Subject: [PATCH] updating container package --- provider/describer/container_package.go | 390 ++++++++-- provider/describer/repository.go | 1 + provider/model/model.go | 17 + provider/resource_types.go | 706 +++++++++--------- .../github/table_github_repository.go | 6 +- 5 files changed, 680 insertions(+), 440 deletions(-) diff --git a/provider/describer/container_package.go b/provider/describer/container_package.go index 80261943..cc82e4d2 100644 --- a/provider/describer/container_package.go +++ b/provider/describer/container_package.go @@ -4,6 +4,12 @@ import ( "context" "encoding/json" "fmt" + "log" + "net/url" + "strconv" + "strings" + "sync" + "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/remote" @@ -11,13 +17,17 @@ import ( "github.com/opengovern/og-describer-github/provider/model" resilientbridge "github.com/opengovern/resilient-bridge" "github.com/opengovern/resilient-bridge/adapters" - "log" - "net/url" - "strconv" - "strings" ) -func GetContainerPackageList(ctx context.Context, githubClient GitHubClient, organizationName string, stream *models.StreamSender) ([]models.Resource, error) { +// ----------------------------------------------------------------------------- +// 1. GetContainerPackageList +// ----------------------------------------------------------------------------- +func GetContainerPackageList( + ctx context.Context, + githubClient GitHubClient, + organizationName string, + stream *models.StreamSender, +) ([]models.Resource, error) { sdk := resilientbridge.NewResilientBridge() sdk.RegisterProvider("github", adapters.NewGitHubAdapter(githubClient.Token), &resilientbridge.ProviderConfig{ UseProviderLimits: true, @@ -27,54 +37,201 @@ func GetContainerPackageList(ctx context.Context, githubClient GitHubClient, org org := organizationName + // [UPDATED] fetchPackages now does pagination packages := fetchPackages(sdk, org, "container") maxVersions := 1 + var allValues []models.Resource - var values []models.Resource - + // Loop through each package and version for _, p := range packages { packageName := p.Name + + // [UPDATED] fetchVersions now does pagination versions := fetchVersions(sdk, org, "container", packageName) + if len(versions) > maxVersions { versions = versions[:maxVersions] } + for _, v := range versions { - packageValues := getVersionOutput(githubClient.Token, org, packageName, v, stream) - values = append(values, packageValues...) + + packageValues, err := getVersionOutput(githubClient.Token, org, packageName, v, stream) + + if err != nil { + // If you want to fail fast, return err. Or just log and continue. + log.Printf("Error getting version output for %s/%s: %v", packageName, v.Name, err) + continue + } + //fmt.Println(packageValues) + allValues = append(allValues, packageValues...) } } - - return values, nil + fmt.Println(allValues) + return allValues, nil } -func getVersionOutput(apiToken, org, packageName string, version model.PackageVersion, stream *models.StreamSender) []models.Resource { - var values []models.Resource +// ----------------------------------------------------------------------------- +// 2. getVersionOutput +// - fetches details for each tag in a given version concurrently +// - after concurrency, deduplicate by (version.ID, actualDigest) +// +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +func getVersionOutput( + apiToken, org, packageName string, + version model.PackageVersion, + stream *models.StreamSender, +) ([]models.Resource, error) { + + var concurrentResults []models.Resource normalizedPackageName := strings.ToLower(packageName) + tags := version.Metadata.Container.Tags + if len(tags) == 0 { + return concurrentResults, nil + } - for _, tag := range version.Metadata.Container.Tags { - normalizedTag := strings.ToLower(tag) - imageRef := fmt.Sprintf("ghcr.io/%s/%s:%s", org, normalizedPackageName, normalizedTag) - ov := fetchAndAssembleOutput(apiToken, org, normalizedPackageName, version, imageRef) - value := models.Resource{ - ID: strconv.Itoa(ov.ID), - Name: ov.Name, - Description: JSONAllFieldsMarshaller{ - Value: ov, - }, - } + // Prepare concurrency + var wg sync.WaitGroup + resultsChan := make(chan models.Resource, len(tags)) + errChan := make(chan error, 1) + + // For each tag, fetch the container details in a goroutine + for _, tag := range tags { + wg.Add(1) + go func(t string) { + defer wg.Done() + normalizedTag := strings.ToLower(t) + imageRef := fmt.Sprintf("ghcr.io/%s/%s:%s", org, normalizedPackageName, normalizedTag) + + ov, err := fetchAndAssembleOutput(apiToken, org, normalizedPackageName, version, imageRef) + if err != nil { + select { + case errChan <- err: + default: + } + return + } + + // Convert ov -> models.Resource + value := models.Resource{ + ID: strconv.Itoa(ov.ID), + Name: ov.Name, + Description: JSONAllFieldsMarshaller{ + Value: ov, + }, + } + resultsChan <- value + }(tag) + } + + // Wait for goroutines + go func() { + wg.Wait() + close(resultsChan) + close(errChan) + }() + + // If any goroutine sends an error, return the first one + if err := <-errChan; err != nil { + return nil, err + } + + // Collect concurrency results + for res := range resultsChan { + // Always append to concurrentResults so it can be returned + concurrentResults = append(concurrentResults, res) + + // If streaming, also stream each item if stream != nil { - if err := (*stream)(value); err != nil { - return nil + if e := (*stream)(res); e != nil { + return nil, e } + } + } + + // Deduplicate by (version.ID + actualDigest) + deduped := deduplicateVersionOutputsByDigest(concurrentResults, version.ID) + return deduped, nil +} + +// ----------------------------------------------------------------------------- +// deduplicateVersionOutputsByDigest +// - Expects an array of Resources whose .Description is ContainerPackageDescription. +// - Collapses duplicates by (ID, actualDigest). +// +// ----------------------------------------------------------------------------- +func deduplicateVersionOutputsByDigest(resources []models.Resource, versionID int) []models.Resource { + // Key = "versionID|digest" + type dedupKey struct { + versionID string + digest string + } + + dedupMap := make(map[dedupKey]*model.ContainerPackageDescription) + var finalResults []models.Resource + + for _, r := range resources { + // Type-assert .Description to JSONAllFieldsMarshaller + desc, ok := r.Description.(JSONAllFieldsMarshaller) + if !ok { + // Not the type we expected + continue + } + + // Marshal then unmarshal so we can read it into ContainerPackageDescription + rawBytes, err := json.Marshal(desc.Value) + if err != nil { + continue + } + + var cpd model.ContainerPackageDescription + if err := json.Unmarshal(rawBytes, &cpd); err != nil { + continue + } + + dk := dedupKey{ + versionID: fmt.Sprintf("%d", versionID), + digest: cpd.ActualDigest(), + } + + // If we already have this digest, append to AdditionalPackageURIs + if existing, exists := dedupMap[dk]; exists { + existing.AdditionalPackageURIs = append(existing.AdditionalPackageURIs, cpd.PackageURI) } else { - values = append(values, value) + dedupMap[dk] = &cpd + } + } + + // Convert the deduped map back to a []models.Resource + for _, cpdPtr := range dedupMap { + cpd := *cpdPtr + res := models.Resource{ + ID: strconv.Itoa(cpd.ID), + Name: cpd.Name, + Description: JSONAllFieldsMarshaller{ + Value: cpd, + }, } + finalResults = append(finalResults, res) } - return values + + return finalResults } -func fetchAndAssembleOutput(apiToken, org, packageName string, version model.PackageVersion, imageRef string) model.ContainerPackageDescription { +// ----------------------------------------------------------------------------- +// 4. fetchAndAssembleOutput +// - no signature changes +// - adds "AdditionalPackageURIs" field to ContainerPackageDescription, plus we +// store real Docker digest from remote. (We do that by overriding cpd.Digest.) +// +// ----------------------------------------------------------------------------- +func fetchAndAssembleOutput( + apiToken, org, packageName string, + version model.PackageVersion, + imageRef string, +) (model.ContainerPackageDescription, error) { + authOption := remote.WithAuth(&authn.Basic{ Username: "github", Password: apiToken, @@ -82,14 +239,19 @@ func fetchAndAssembleOutput(apiToken, org, packageName string, version model.Pac ref, err := name.ParseReference(imageRef) if err != nil { - log.Fatalf("Error parsing reference %s: %v", imageRef, err) + return model.ContainerPackageDescription{}, + fmt.Errorf("error parsing reference %s: %w", imageRef, err) } desc, err := remote.Get(ref, authOption) if err != nil { - log.Fatalf("Error fetching manifest for %s: %v", imageRef, err) + return model.ContainerPackageDescription{}, + fmt.Errorf("error fetching manifest for %s: %w", imageRef, err) } + // [UPDATED] We read the actual Docker registry digest from desc.Descriptor.Digest + actualDigest := desc.Descriptor.Digest.String() + var manifestStruct struct { SchemaVersion int `json:"schemaVersion"` MediaType string `json:"mediaType"` @@ -105,7 +267,8 @@ func fetchAndAssembleOutput(apiToken, org, packageName string, version model.Pac } `json:"layers"` } if err := json.Unmarshal(desc.Manifest, &manifestStruct); err != nil { - log.Fatalf("Error unmarshaling manifest JSON: %v", err) + return model.ContainerPackageDescription{}, + fmt.Errorf("error unmarshaling manifest JSON: %w", err) } totalSize := manifestStruct.Config.Size @@ -115,64 +278,129 @@ func fetchAndAssembleOutput(apiToken, org, packageName string, version model.Pac var manifestInterface interface{} if err := json.Unmarshal(desc.Manifest, &manifestInterface); err != nil { - log.Fatalf("Error unmarshaling manifest for output: %v", err) - } - - return model.ContainerPackageDescription{ - ID: version.ID, - Digest: version.Name, - PackageURI: imageRef, - PackageHTMLURL: version.PackageHTMLURL, - CreatedAt: version.CreatedAt, - UpdatedAt: version.UpdatedAt, - HTMLURL: version.HTMLURL, - Name: imageRef, - MediaType: string(desc.Descriptor.MediaType), - TotalSize: totalSize, - Metadata: version.Metadata, - Manifest: manifestInterface, + return model.ContainerPackageDescription{}, + fmt.Errorf("error unmarshaling manifest for output: %w", err) } + + // [UPDATED] The "digest" from the GitHub version might be inaccurate or just a tag name. + // We'll store the real Docker digest in a separate field (ActualDigest). + // For uniqueness, we’ll define "Digest" as the GH “version.Name” if you still want that. + // Or store "Digest" as actualDigest if you prefer. Below we store GH’s version.Name in + // GHVersionName, and store the actual registry digest in "Digest". + // We'll also add AdditionalPackageURIs []string (will be deduplicated in a later step). + + ov := model.ContainerPackageDescription{ + ID: version.ID, + Digest: actualDigest, // store the real Docker digest + GHVersionName: version.Name, // store the GH "version.Name" if desired + PackageURI: imageRef, + AdditionalPackageURIs: []string{}, // Will be appended after dedup + PackageHTMLURL: version.PackageHTMLURL, + CreatedAt: version.CreatedAt, + UpdatedAt: version.UpdatedAt, + HTMLURL: version.HTMLURL, + Name: imageRef, + MediaType: string(desc.Descriptor.MediaType), + TotalSize: totalSize, + Metadata: version.Metadata, + Manifest: manifestInterface, + } + return ov, nil } +// ----------------------------------------------------------------------------- +// 5. fetchPackages - updated to do pagination +// ----------------------------------------------------------------------------- func fetchPackages(sdk *resilientbridge.ResilientBridge, org, packageType string) []model.Package { - listReq := &resilientbridge.NormalizedRequest{ - Method: "GET", - Endpoint: fmt.Sprintf("/orgs/%s/packages?package_type=%s", org, packageType), - Headers: map[string]string{"Accept": "application/vnd.github+json"}, - } - listResp, err := sdk.Request("github", listReq) - if err != nil { - log.Fatalf("Error listing packages: %v", err) - } - if listResp.StatusCode >= 400 { - log.Fatalf("HTTP error %d: %s", listResp.StatusCode, string(listResp.Data)) - } - var packages []model.Package - if err := json.Unmarshal(listResp.Data, &packages); err != nil { - log.Fatalf("Error parsing packages list response: %v", err) + var allPackages []model.Package + page := 1 + perPage := 100 + + for { + req := &resilientbridge.NormalizedRequest{ + Method: "GET", + Endpoint: fmt.Sprintf("/orgs/%s/packages?package_type=%s&per_page=%d&page=%d", + org, packageType, perPage, page), + Headers: map[string]string{"Accept": "application/vnd.github+json"}, + } + + resp, err := sdk.Request("github", req) + if err != nil { + log.Fatalf("Error listing packages: %v", err) + } + if resp.StatusCode >= 400 { + log.Fatalf("HTTP error %d: %s", resp.StatusCode, string(resp.Data)) + } + + var packages []model.Package + if err := json.Unmarshal(resp.Data, &packages); err != nil { + log.Fatalf("Error parsing packages list response: %v", err) + } + if len(packages) == 0 { + // no more data + break + } + + allPackages = append(allPackages, packages...) + + if len(packages) < perPage { + // we got fewer than 100, so no more pages + break + } + page++ } - return packages + return allPackages } -func fetchVersions(sdk *resilientbridge.ResilientBridge, org, packageType, packageName string) []model.PackageVersion { +// ----------------------------------------------------------------------------- +// 6. fetchVersions - updated to do pagination +// ----------------------------------------------------------------------------- +func fetchVersions( + sdk *resilientbridge.ResilientBridge, + org, packageType, packageName string, +) []model.PackageVersion { + packageNameEncoded := url.PathEscape(packageName) - versionsReq := &resilientbridge.NormalizedRequest{ - Method: "GET", - Endpoint: fmt.Sprintf("/orgs/%s/packages/%s/%s/versions", org, packageType, packageNameEncoded), - Headers: map[string]string{"Accept": "application/vnd.github+json"}, - } + var allVersions []model.PackageVersion + page := 1 + perPage := 100 - versionsResp, err := sdk.Request("github", versionsReq) - if err != nil { - log.Fatalf("Error listing package versions: %v", err) - } - if versionsResp.StatusCode >= 400 { - log.Fatalf("HTTP error %d: %s", versionsResp.StatusCode, string(versionsResp.Data)) - } + for { + req := &resilientbridge.NormalizedRequest{ + Method: "GET", + Endpoint: fmt.Sprintf( + "/orgs/%s/packages/%s/%s/versions?per_page=%d&page=%d", + org, packageType, packageNameEncoded, perPage, page, + ), + Headers: map[string]string{"Accept": "application/vnd.github+json"}, + } + + resp, err := sdk.Request("github", req) + if err != nil { + log.Fatalf("Error listing package versions: %v", err) + } + if resp.StatusCode >= 400 { + log.Fatalf("HTTP error %d: %s", resp.StatusCode, string(resp.Data)) + } + + var versions []model.PackageVersion + if err := json.Unmarshal(resp.Data, &versions); err != nil { + log.Fatalf("Error parsing package versions response: %v", err) + } - var versions []model.PackageVersion - if err := json.Unmarshal(versionsResp.Data, &versions); err != nil { - log.Fatalf("Error parsing package versions response: %v", err) + if len(versions) == 0 { + // no more data + break + } + + allVersions = append(allVersions, versions...) + + if len(versions) < perPage { + // we got fewer than 100, so no more pages + break + } + page++ } - return versions + + return allVersions } diff --git a/provider/describer/repository.go b/provider/describer/repository.go index 6776550b..dd822db1 100644 --- a/provider/describer/repository.go +++ b/provider/describer/repository.go @@ -171,6 +171,7 @@ func GetRepository( Value: finalDetail, }, } + fmt.Println(value) // If a stream is provided, send the resource through the stream if stream != nil { diff --git a/provider/model/model.go b/provider/model/model.go index 48474745..ab14da2c 100755 --- a/provider/model/model.go +++ b/provider/model/model.go @@ -1056,6 +1056,23 @@ type ContainerPackageDescription struct { TotalSize int64 `json:"total_size"` Metadata ContainerMetadata `json:"metadata"` Manifest interface{} `json:"manifest"` + + // -- Add these new fields/methods: -- + + // The GitHub "version.Name" or tag, + // if you want to store that separately from the real Docker digest. + GHVersionName string `json:"gh_version_name,omitempty"` + + // When deduplicating, any subsequent tags for the same (ID,digest) + // can be appended here. + AdditionalPackageURIs []string `json:"additional_package_uris,omitempty"` +} + +// Provide a helper so that code calling `cpd.ActualDigest()` compiles: +func (c ContainerPackageDescription) ActualDigest() string { + // If you want the *Docker* digest, we simply return `c.Digest` + // because your code is already overwriting .Digest with the real Docker digest + return c.Digest } type PackageVersion struct { diff --git a/provider/resource_types.go b/provider/resource_types.go index 66f71b24..10a9dd0c 100644 --- a/provider/resource_types.go +++ b/provider/resource_types.go @@ -1,25 +1,26 @@ package provider + import ( - "github.com/opengovern/og-describer-github/provider/describer" - "github.com/opengovern/og-describer-github/provider/configs" model "github.com/opengovern/og-describer-github/pkg/sdk/models" + "github.com/opengovern/og-describer-github/provider/configs" + "github.com/opengovern/og-describer-github/provider/describer" ) + var ResourceTypes = map[string]model.ResourceType{ "Github/Actions/Artifact": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Actions/Artifact", - Tags: map[string][]string{ - "category": {"Action"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllArtifacts), - GetDescriber: DescribeSingleByRepo(describer.GetArtifact), - }, - + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Actions/Artifact", + Tags: map[string][]string{ + "category": {"Action"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllArtifacts), + GetDescriber: DescribeSingleByRepo(describer.GetArtifact), + }, + +<<<<<<< HEAD "Github/Actions/Runner": { IntegrationType: configs.IntegrationName, ResourceName: "Github/Actions/Runner", @@ -60,439 +61,428 @@ var ResourceTypes = map[string]model.ResourceType{ }, ListDescriber: DescribeByGithub(describer.GetAllWorkflowRuns), GetDescriber: nil, +======= + "Github/Actions/Repository/Runner": { + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Actions/Repository/Runner", + Tags: map[string][]string{ + "category": {"Action"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRunners), + GetDescriber: DescribeSingleByRepo(describer.GetActionRunner), + }, + + "Github/Actions/Repository/Secret": { + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Actions/Repository/Secret", + Tags: map[string][]string{ + "category": {"Action"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllSecrets), + GetDescriber: DescribeSingleByRepo(describer.GetRepoActionSecret), + }, + + "Github/Actions/Repository/Workflow_run": { + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Actions/Repository/Workflow_run", + Tags: map[string][]string{ + "category": {"Action"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllWorkflowRuns), + GetDescriber: nil, +>>>>>>> 2f991e7 (updating container package) }, "Github/Blob": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Blob", - Tags: map[string][]string{ - "category": {"Blob"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllBlobs), - GetDescriber: DescribeSingleByRepo(describer.GetBlob), + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Blob", + Tags: map[string][]string{ + "category": {"Blob"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllBlobs), + GetDescriber: DescribeSingleByRepo(describer.GetBlob), }, "Github/Branch": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Branch", - Tags: map[string][]string{ - "category": {"Branch"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllBranches), - GetDescriber: DescribeSingleByRepo(describer.GetBlob), + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Branch", + Tags: map[string][]string{ + "category": {"Branch"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllBranches), + GetDescriber: DescribeSingleByRepo(describer.GetBlob), }, "Github/Branch/Protection": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Branch/Protection", - Tags: map[string][]string{ - "category": {"Branch"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllBranchProtections), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Branch/Protection", + Tags: map[string][]string{ + "category": {"Branch"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllBranchProtections), + GetDescriber: nil, }, "Github/Commit": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Commit", - Tags: map[string][]string{ - "category": {"Commit"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.ListCommits), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Commit", + Tags: map[string][]string{ + "category": {"Commit"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.ListCommits), + GetDescriber: nil, }, "Github/Issue": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Issue", - Tags: map[string][]string{ - "category": {"Issue"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetIssueList), - GetDescriber: DescribeSingleByRepo(describer.GetIssue), + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Issue", + Tags: map[string][]string{ + "category": {"Issue"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetIssueList), + GetDescriber: DescribeSingleByRepo(describer.GetIssue), }, "Github/License": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/License", - Tags: map[string][]string{ - "category": {"License"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetLicenseList), - GetDescriber: DescribeSingleByRepo(describer.GetLicense), + IntegrationType: configs.IntegrationName, + ResourceName: "Github/License", + Tags: map[string][]string{ + "category": {"License"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetLicenseList), + GetDescriber: DescribeSingleByRepo(describer.GetLicense), }, "Github/Organization": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Organization", - Tags: map[string][]string{ - "category": {"Organization"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetOrganizationList), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Organization", + Tags: map[string][]string{ + "category": {"Organization"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetOrganizationList), + GetDescriber: nil, }, "Github/Organization/Collaborator": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Organization/Collaborator", - Tags: map[string][]string{ - "category": {"Organization"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllOrganizationsCollaborators), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Organization/Collaborator", + Tags: map[string][]string{ + "category": {"Organization"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllOrganizationsCollaborators), + GetDescriber: nil, }, "Github/Organization/Dependabot/Alert": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Organization/Dependabot/Alert", - Tags: map[string][]string{ - "category": {"Organization"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllOrganizationsDependabotAlerts), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Organization/Dependabot/Alert", + Tags: map[string][]string{ + "category": {"Organization"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllOrganizationsDependabotAlerts), + GetDescriber: nil, }, "Github/Organization/External/Identity": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Organization/External/Identity", - Tags: map[string][]string{ - "category": {"Organization"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllExternalIdentities), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Organization/External/Identity", + Tags: map[string][]string{ + "category": {"Organization"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllExternalIdentities), + GetDescriber: nil, }, "Github/Organization/Member": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Organization/Member", - Tags: map[string][]string{ - "category": {"Organization"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllMembers), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Organization/Member", + Tags: map[string][]string{ + "category": {"Organization"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllMembers), + GetDescriber: nil, }, "Github/PullRequest": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/PullRequest", - Tags: map[string][]string{ - "category": {"PullRequest"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllPullRequests), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/PullRequest", + Tags: map[string][]string{ + "category": {"PullRequest"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllPullRequests), + GetDescriber: nil, }, "Github/Release": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Release", - Tags: map[string][]string{ - "category": {"Release"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetReleaseList), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Release", + Tags: map[string][]string{ + "category": {"Release"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetReleaseList), + GetDescriber: nil, }, "Github/Repository": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetRepositoryList), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetRepositoryList), + GetDescriber: DescribeSingleByRepo(describer.GetRepository), }, "Github/Repository/Collaborator": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository/Collaborator", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllRepositoriesCollaborators), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository/Collaborator", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRepositoriesCollaborators), + GetDescriber: nil, }, "Github/Repository/DependabotAlert": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository/DependabotAlert", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllRepositoriesDependabotAlerts), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository/DependabotAlert", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRepositoriesDependabotAlerts), + GetDescriber: nil, }, "Github/Repository/Deployment": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository/Deployment", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllRepositoriesDeployments), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository/Deployment", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRepositoriesDeployments), + GetDescriber: nil, }, "Github/Repository/Environment": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository/Environment", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllRepositoriesEnvironments), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository/Environment", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRepositoriesEnvironments), + GetDescriber: nil, }, "Github/Repository/Ruleset": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository/Ruleset", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllRepositoriesRuleSets), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository/Ruleset", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRepositoriesRuleSets), + GetDescriber: nil, }, "Github/Repository/SBOM": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository/SBOM", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllRepositoriesSBOMs), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository/SBOM", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRepositoriesSBOMs), + GetDescriber: nil, }, "Github/Repository/VulnerabilityAlert": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Repository/VulnerabilityAlert", - Tags: map[string][]string{ - "category": {"Repository"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllRepositoriesVulnerabilities), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Repository/VulnerabilityAlert", + Tags: map[string][]string{ + "category": {"Repository"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllRepositoriesVulnerabilities), + GetDescriber: nil, }, "Github/Tag": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Tag", - Tags: map[string][]string{ - "category": {"Tag"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllTags), - GetDescriber: nil, - }, - + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Tag", + Tags: map[string][]string{ + "category": {"Tag"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllTags), + GetDescriber: nil, + }, + +<<<<<<< HEAD +======= + "Github/Team": { + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Team", + Tags: map[string][]string{ + "category": {"Team"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetTeamList), + GetDescriber: nil, + }, + +>>>>>>> 2f991e7 (updating container package) "Github/Team/Member": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Team/Member", - Tags: map[string][]string{ - "category": {"Team"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllTeamsMembers), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Team/Member", + Tags: map[string][]string{ + "category": {"Team"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllTeamsMembers), + GetDescriber: nil, }, "Github/Tree": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Tree", - Tags: map[string][]string{ - "category": {"tree"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllTrees), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Tree", + Tags: map[string][]string{ + "category": {"tree"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllTrees), + GetDescriber: nil, }, "Github/User": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/User", - Tags: map[string][]string{ - "category": {"user"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetUser), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/User", + Tags: map[string][]string{ + "category": {"user"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetUser), + GetDescriber: nil, }, "Github/Workflow": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Workflow", - Tags: map[string][]string{ - "category": {"workflow"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetAllWorkflows), - GetDescriber: DescribeSingleByRepo(describer.GetRepositoryWorkflow), + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Workflow", + Tags: map[string][]string{ + "category": {"workflow"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetAllWorkflows), + GetDescriber: DescribeSingleByRepo(describer.GetRepositoryWorkflow), }, "Github/Container/Package": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Container/Package", - Tags: map[string][]string{ - "category": {"package"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetContainerPackageList), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Container/Package", + Tags: map[string][]string{ + "category": {"package"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetContainerPackageList), + GetDescriber: nil, }, "Github/Package/Maven": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Package/Maven", - Tags: map[string][]string{ - "category": {"package"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetMavenPackageList), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Package/Maven", + Tags: map[string][]string{ + "category": {"package"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetMavenPackageList), + GetDescriber: nil, }, "Github/NPM/Package": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/NPM/Package", - Tags: map[string][]string{ - "category": {"package"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetNPMPackageList), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/NPM/Package", + Tags: map[string][]string{ + "category": {"package"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetNPMPackageList), + GetDescriber: nil, }, "Github/Nuget/Package": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Nuget/Package", - Tags: map[string][]string{ - "category": {"package"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.GetNugetPackageList), - GetDescriber: DescribeSingleByRepo(describer.GetNugetPackage), + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Nuget/Package", + Tags: map[string][]string{ + "category": {"package"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.GetNugetPackageList), + GetDescriber: DescribeSingleByRepo(describer.GetNugetPackage), }, "Github/Artifact/DockerFile": { - IntegrationType: configs.IntegrationName, - ResourceName: "Github/Artifact/DockerFile", - Tags: map[string][]string{ - "category": {"artifact_dockerfile"}, - }, - Labels: map[string]string{ - }, - Annotations: map[string]string{ - }, - ListDescriber: DescribeByGithub(describer.ListArtifactDockerFiles), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Github/Artifact/DockerFile", + Tags: map[string][]string{ + "category": {"artifact_dockerfile"}, + }, + Labels: map[string]string{}, + Annotations: map[string]string{}, + ListDescriber: DescribeByGithub(describer.ListArtifactDockerFiles), + GetDescriber: nil, }, } diff --git a/steampipe-plugin-github/github/table_github_repository.go b/steampipe-plugin-github/github/table_github_repository.go index 7179aa5e..77efb0aa 100644 --- a/steampipe-plugin-github/github/table_github_repository.go +++ b/steampipe-plugin-github/github/table_github_repository.go @@ -181,6 +181,10 @@ func tableGitHubRepository() *plugin.Table { List: &plugin.ListConfig{ Hydrate: opengovernance.ListRepository, }, - Columns: commonColumns(sharedRepositoryColumns()), + Get: &plugin.GetConfig{ + KeyColumns: plugin.AllColumns([]string{"repository_full_name", "number"}), + Hydrate: opengovernance.GetRepository, + }, + Columns: commonColumns(gitHubIssueColumns()), } }