Skip to content

Commit

Permalink
⭐️ github terraform discovery
Browse files Browse the repository at this point in the history
Signed-off-by: Ivan Milchev <[email protected]>
  • Loading branch information
imilchev committed May 27, 2024
1 parent a49f250 commit 70ccc76
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
2 changes: 1 addition & 1 deletion providers/github/connection/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
DiscoveryRepository = "repository" // deprecated: use repos
DiscoveryUser = "user" // deprecated: use users
DiscoveryOrganization = "organization"
DiscoveryTerraform = "terraform"
)

var (
Expand Down Expand Up @@ -62,7 +63,6 @@ func (c *GithubConnection) PlatformInfo() (*inventory.Platform, error) {
}

if userId := conf.Options["user"]; userId != "" {

return NewGithubUserPlatform(userId), nil
}

Expand Down
80 changes: 80 additions & 0 deletions providers/github/resources/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import (
"strings"

"github.com/gobwas/glob"
"github.com/google/go-github/v61/github"
"github.com/rs/zerolog/log"
"go.mondoo.com/cnquery/v11/llx"
"go.mondoo.com/cnquery/v11/providers-sdk/v1/inventory"
"go.mondoo.com/cnquery/v11/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/v11/providers-sdk/v1/vault"
"go.mondoo.com/cnquery/v11/providers/github/connection"
"go.mondoo.com/cnquery/v11/utils/stringx"
"google.golang.org/protobuf/proto"
)

func Discover(runtime *plugin.Runtime, opts map[string]string) (*inventory.Inventory, error) {
Expand Down Expand Up @@ -116,6 +119,14 @@ func org(runtime *plugin.Runtime, orgName string, conn *connection.GithubConnect
Labels: make(map[string]string),
Connections: []*inventory.Config{cfg},
})

if stringx.ContainsAnyOf(targets, connection.DiscoveryAll, connection.DiscoveryTerraform) {
terraformAssets, err := discoverTerraform(conn, repo)
if err != nil {
return nil, err
}
assetList = append(assetList, terraformAssets...)
}
}
}
if stringx.ContainsAnyOf(targets, connection.DiscoveryUsers, connection.DiscoveryUser) {
Expand Down Expand Up @@ -165,6 +176,14 @@ func repo(runtime *plugin.Runtime, repoName string, owner string, conn *connecti
Connections: []*inventory.Config{cfg},
})

if stringx.ContainsAnyOf(targets, connection.DiscoveryAll, connection.DiscoveryTerraform) {
terraformAssets, err := discoverTerraform(conn, repo)
if err != nil {
return nil, err
}
assetList = append(assetList, terraformAssets...)
}

return assetList, nil
}

Expand Down Expand Up @@ -257,3 +276,64 @@ func (f *ReposFilter) skipRepo(namespace string) bool {

return false
}

func discoverTerraform(conn *connection.GithubConnection, repo *mqlGithubRepository) ([]*inventory.Asset, error) {
// For git clone we need to set the user to oauth2 to be usable with the token.
conf := conn.Asset().Connections[0]
creds := make([]*vault.Credential, len(conf.Credentials))
for i := range conf.Credentials {
cred := conf.Credentials[i]
cc := proto.Clone(cred).(*vault.Credential)
if cc.User == "" {
cc.User = "oauth2"
}
creds[i] = cc
}

files := repo.GetFiles()
if files.Error != nil {
return nil, files.Error
}

var res []*inventory.Asset
hasTf, err := hasTerraformHcl(conn.Client(), files)
if err != nil {
log.Error().Err(err).Str("project", repo.FullName.Data).Msg("failed to discover terraform repo in gitlab")
} else if hasTf {
res = append(res, &inventory.Asset{
Connections: []*inventory.Config{{
Type: "terraform-hcl-git",
Options: map[string]string{
"ssh-url": repo.SshUrl.Data,
"http-url": repo.CloneUrl.Data,
},
Credentials: creds,
}},
})
}
return res, nil
}

// hasTerraformHcl will check if the repository contains terraform files
func hasTerraformHcl(client *github.Client, files *plugin.TValue[[]interface{}]) (bool, error) {
for _, f := range files.Data {
file := f.(*mqlGithubFile)
children := file.GetFiles()
if children.Error != nil {
return false, children.Error
}
hasTf, err := hasTerraformHcl(client, children)
if err != nil {
return false, err
}
if hasTf {
return true, nil
}

if strings.HasSuffix(file.Path.Data, ".tf") {
return true, nil
}
}

return false, nil
}

0 comments on commit 70ccc76

Please sign in to comment.