Skip to content

Commit

Permalink
Feature: Add Registry ops to query private Providers and Modules (#46) (
Browse files Browse the repository at this point in the history
#62)

* Feature: Add Registry operations to query private Providers and Modules (#46)

* Fix: typo in filter flag in policy_set.go

* Fix: "failedd" typo in README

* Fix: simplify WorkspaceDetail struct, remove comments

* Fix: remove comment

* Fix: bump go version

* Fix: Quote go version
  • Loading branch information
sharathrnair87 committed Feb 5, 2024
1 parent 481d17e commit e6ea793
Show file tree
Hide file tree
Showing 32 changed files with 845 additions and 119 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: setup-go
uses: actions/setup-go@v5
with:
go-version: 1.19
go-version: "1.20"

- name: lint
run: make fmt
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: setup-go
uses: actions/setup-go@v5
with:
go-version: 1.19
go-version: "1.20"

- name: build
uses: goreleaser/goreleaser-action@v5
Expand Down
85 changes: 84 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,8 @@ Use "tfectl [command] --help" for more information about a command.
}
}
```
* To query only those checks which have failedd

* To query only those checks which have failed
```bash
$ tfectl policy-check show --run-id run-Wxk42edRCCLB5fMi --query '.result.sentinel.data | to_entries | .[].value.policies | .[] | select(.result|not) | .policy'
[
Expand All @@ -670,6 +671,88 @@ Use "tfectl [command] --help" for more information about a command.
```
</details>

### Registry Modules
<details>
<summary>Private Registry Module Operations</summary>

* Query Private Modules in the Organization registry

* #### 1. List
* List all available Modules in the Organization registry
```bash
$ tfectl registry-module list --query '.[] | select(.provider == "azurerm")'
[
{
"id": "mod-DHAq8Casdas32uC",
"module_latest_version": "2.0.4",
"name": "windows-instance",
"namespace": "MyNamespace",
"provider": "azurerm",
"publishing_mechanism": "git_tag",
"registry_name": "private",
"status": "setup_complete",
"test_config": true,
"vcs_repo": "MyGHOrg/terraform-azurerm-windows-instance"
}
]
```
</details>

### Registry Providers
<details>
<summary>Private Provider Registry Operations</summary>

* Query Private Providers in Organization Registry

* #### 1. List
* List all available Private Providers in the Organization Registry
```bash
$ tfectl registry-provider list
[
{
"id": "prov-5fws9JKkNQZDz2Gf",
"name": "aws",
"namespace": "MyTFCOrg",
"registry_name": "private"
},
{
"id": "prov-bGhLiwy6APQ9r4dZ",
"name": "azure",
"namespace": "MyTFCOrg",
"registry_name": "private"
}
]
```

* #### 2. Get
* Get details of given Private provider
```bash
$ tfectl registry-provider get --name aws
{
"id": "prov-5fws9JKkNQZDz2Gf",
"name": "aws",
"namespace": "MyTFCOrg",
"registry_name": "private",
"provider_latest_version": "5.32.2",
"provider_platforms": [
{
"id": "provpltfrm-wCCMzzy91Rfdj6PW",
"os": "linux",
"arch": "amd64",
"filename": "terraform-provider-awx_5.32.2_linux_amd64.zip"
},
{
"id": "provpltfrm-c9jhJ2tmwEbbwuTV",
"os": "windows",
"arch": "amd64",
"filename": "terraform-provider-awx_5.32.2_windows_amd64.zip"
}
]
}
```
</details>


### Build
GoReleaser is used to produce binaries for multiple platforms (Windows, Mac, Linux).

Expand Down
2 changes: 1 addition & 1 deletion cmd/policy_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func init() {
policySetCmd.AddCommand(policySetListCmd)

// List sub-command
policySetListCmd.Flags().String("fitler", "", "Search for policy sets by name")
policySetListCmd.Flags().String("filter", "", "Search for policy sets by name")
}

func listPolicySets(client *tfe.Client, organization string, filter string) ([]*tfe.PolicySet, error) {
Expand Down
115 changes: 115 additions & 0 deletions cmd/registry_modules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package cmd

import (
"context"
"encoding/json"
"fmt"

"github.com/AGLEnergyPublic/tfectl/resources"
tfe "github.com/hashicorp/go-tfe"

log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

type RegistryModule struct {
ID string `json:"id"`
Name string `json:"name"`
Provider string `json:"provider"`
RegistryName tfe.RegistryName `json:"registry_name"`
Namespace string `json:"namespace"`
PublishingMechanism tfe.PublishingMechanism `json:"publishing_mechanism"`
Status tfe.RegistryModuleStatus `json:"status"`
TestConfig bool `json:"test_config"`
VCSRepo string `json:"vcs_repo"`
ModuleLatestVersion string `json:"module_latest_version"`
}

var registryModuleCmd = &cobra.Command{
Use: "registry-module",
Short: "Query/Manage TFE private module registry",
Long: `Query/Manage TFE private module regsistry.`,
}

var registryModuleListCmd = &cobra.Command{
Use: "list",
Short: "List private modules in TFE Organization",
Long: `List private modules in TFE Organization.`,
Run: func(cmd *cobra.Command, args []string) {

organization, client, err := resources.Setup(cmd)
check(err)

query, _ := cmd.Flags().GetString("query")

moduleList, err := listPrivateModules(client, organization)
check(err)

moduleListJson, _ := json.MarshalIndent(moduleList, "", " ")

if query != "" {
resources.JqRun(moduleListJson, query)
} else {
fmt.Println(string(moduleListJson))
}
},
}

func init() {
rootCmd.AddCommand(registryModuleCmd)
registryModuleCmd.AddCommand(registryModuleListCmd)
}

func listPrivateModules(client *tfe.Client, organization string) ([]RegistryModule, error) {
results := []RegistryModule{}
result := RegistryModule{}
currentPage := 1

for {
log.Debugf("Processing page %d\n", currentPage)
options := &tfe.RegistryModuleListOptions{
ListOptions: tfe.ListOptions{
PageNumber: currentPage,
PageSize: 50,
},
}

rms, err := client.RegistryModules.List(context.Background(), organization, options)
if err != nil {
return nil, err
}

for _, rmItem := range rms.Items {
result.RegistryName = rmItem.RegistryName
result.ID = rmItem.ID
result.Name = rmItem.Name
result.Namespace = rmItem.Namespace
result.VCSRepo = rmItem.VCSRepo.DisplayIdentifier
result.PublishingMechanism = rmItem.PublishingMechanism
result.Provider = rmItem.Provider
result.Status = rmItem.Status

if rmItem.TestConfig != nil {
result.TestConfig = rmItem.TestConfig.TestsEnabled
}

for _, rmvs := range rmItem.VersionStatuses {
if rmvs.Status == "ok" {
// get latest module version which published without errors
result.ModuleLatestVersion = rmvs.Version
break
}
}

results = append(results, result)
}

if rms.NextPage == 0 {
break
}

currentPage++
}

return results, nil
}
28 changes: 28 additions & 0 deletions cmd/registry_modules_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmd

import (
"testing"
)

func TestRegistryModulesListCmd(t *testing.T) {

tt := []struct {
args []string
err error
}{
{
args: []string{"registry-module", "list"},
err: nil,
},
}

r := rootCmd
c1 := registryModuleCmd
c2 := registryModuleListCmd
r.AddCommand(c1, c2)

runTestCasesNoOutput(t, r, tt)

r.RemoveCommand(c1, c2)
r.AddCommand(c1)
}
Loading

0 comments on commit e6ea793

Please sign in to comment.