Skip to content

Commit

Permalink
🔧 add configuration for providers in dev env
Browse files Browse the repository at this point in the history
This has now happened a few too many times: You get a PR with a change to a provider, but forgot to update your builtin.go file. After 30min you realize you have been testing the providers on disk, instead of the ones in the repo. Also configuring providers is a bit annoying (with all the things you need to change in `builtin.go`).

This is now streamlined in `make providers/config`. You can configure it in `providers.yaml` in the root folder.

Signed-off-by: Dominik Richter <[email protected]>
  • Loading branch information
arlimus committed Sep 14, 2023
1 parent b1cc364 commit 5602c92
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 81 deletions.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ define gomodtidyProvider
endef

.PHONY: providers
providers: providers/proto providers/build
providers: providers/proto providers/config providers/build

.PHONY: providers/proto
providers/proto:
Expand All @@ -145,6 +145,11 @@ providers/proto:
go generate ./providers-sdk/v1/inventory
go generate ./providers-sdk/v1/plugin

.PHONY: providers/config
providers/config:
go run ./providers-sdk/v1/util/configure/configure.go -f providers.yaml -o providers/builtin.go
gofmt -w providers/builtin.go

.PHONY: providers/lr
providers/lr:
go build -o lr ./providers-sdk/v1/lr/cli/main.go
Expand Down
134 changes: 134 additions & 0 deletions providers-sdk/v1/util/configure/configure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package main

import (
"fmt"
"os"

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"go.mondoo.com/cnquery/logger"
"sigs.k8s.io/yaml"
)

type ProvidersConf struct {
Builtin []string `json:"builtin"`
}

var rootCmd = &cobra.Command{
Use: "configure [-f config] [-o file]",
Short: "configure providers for cnquery",
Run: func(cmd *cobra.Command, args []string) {
confPath, err := cmd.Flags().GetString("file")
if err != nil {
log.Fatal().Err(err).Msg("Can't get --file")
}
outPath, err := cmd.Flags().GetString("output")
if err != nil {
log.Fatal().Err(err).Msg("Can't get --output")
}

raw, err := os.ReadFile(confPath)
if err != nil {
log.Fatal().Err(err).Str("path", confPath).Msg("failed to read config file")
}

var conf ProvidersConf
err = yaml.Unmarshal(raw, &conf)
if err != nil {
log.Fatal().Err(err).Str("path", confPath).Msg("failed to parse config file")
}

builtinGo, err := genBuiltinGo(conf)

if err = os.WriteFile(outPath, []byte(builtinGo), 0o644); err != nil {
log.Fatal().Err(err).Str("path", outPath).Msg("failed to write output")
}
log.Info().Str("path", outPath).Strs("providers", conf.Builtin).Msg("configured builtin providers")
},
}

func genBuiltinGo(conf ProvidersConf) (string, error) {
var imports string
var infos string
var configs string

for _, provider := range conf.Builtin {
imports += fmt.Sprintf("\t%sconf \"go.mondoo.com/cnquery/providers/%s/config\"\n", provider, provider)
imports += fmt.Sprintf("\t%s \"go.mondoo.com/cnquery/providers/%s/provider\"\n", provider, provider)
infos += fmt.Sprintf(
"//go:embed %s/resources/%s.resources.json\n"+
"var %sInfo []byte\n",
provider, provider, provider)
configs += fmt.Sprintf(`
%sconf.Config.ID: {
Runtime: &RunningProvider{
Name: %sconf.Config.Name,
ID: %sconf.Config.ID,
Plugin: %s.Init(),
Schema: MustLoadSchema("%s", %sInfo),
isClosed: false,
},
Config: &%sconf.Config,
},
`, provider, provider, provider, provider, provider, provider, provider)
}

return fmt.Sprintf(template, imports, infos, configs), nil
}

const template = `// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1
//
// This file is auto-generated by 'make providers/config'
package providers
// Uncomment any provider you want to load directly into the binary.
// This is primarily useful for debugging purposes, if you want to
// trace into any provider without having to debug the plugin
// connection separately.
import (
_ "embed"
coreconf "go.mondoo.com/cnquery/providers/core/config"
core "go.mondoo.com/cnquery/providers/core/provider"
%s)
//go:embed core/resources/core.resources.json
var coreInfo []byte
%s
var builtinProviders = map[string]*builtinProvider{
coreconf.Config.ID: {
Runtime: &RunningProvider{
Name: coreconf.Config.Name,
ID: coreconf.Config.ID,
Plugin: core.Init(),
Schema: MustLoadSchema("core", coreInfo),
isClosed: false,
},
Config: &coreconf.Config,
},
%s
}
`

func init() {
rootCmd.Flags().StringP("file", "f", "providers.yaml", "config file for providers")
rootCmd.Flags().StringP("output", "o", "providers/builtin.go", "output builtin.go file")
}

func main() {
logger.CliCompactLogger(logger.LogOutputWriter)
zerolog.SetGlobalLevel(zerolog.InfoLevel)

if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
15 changes: 15 additions & 0 deletions providers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) Mondoo, Inc.
# SPDX-License-Identifier: BUSL-1.1

# Configure builtin providers for the dev environment.
# This only covers additional builtin providers, ie those
# that are normally not builtin. Things like `core` are
# always builtin.
#
# Builtin providers are great testing. Example: if you
# review a PR where someone changed the `os` provider,
# you'll want to set it as builtin for fast testing.
# In this case it will be pulled from your local repo
# instead of using the pre-installed provider in
# your OS (like ~/.mondoo/providers/os).
builtin: []
82 changes: 2 additions & 80 deletions providers/builtin.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1
//
// This file is auto-generated by 'make providers/config'

package providers

Expand All @@ -10,34 +12,14 @@ package providers

import (
_ "embed"
"encoding/json"
osfs "os"

"go.mondoo.com/cnquery/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/providers-sdk/v1/resources"
coreconf "go.mondoo.com/cnquery/providers/core/config"
core "go.mondoo.com/cnquery/providers/core/provider"
// osconf "go.mondoo.com/cnquery/providers/os/config"
// os "go.mondoo.com/cnquery/providers/os/provider"
)

var BuiltinCoreID = coreconf.Config.ID

//go:embed core/resources/core.resources.json
var coreInfo []byte

// //go:embed os/resources/os.resources.json
// var osInfo []byte

// //go:embed network/resources/network.resources.json
// var networkInfo []byte

// //go:embed k8s/resources/k8s.resources.json
// var k8sInfo []byte

// //go:embed azure.resources.json
// var azureInfo []byte

var builtinProviders = map[string]*builtinProvider{
coreconf.Config.ID: {
Runtime: &RunningProvider{
Expand All @@ -49,64 +31,4 @@ var builtinProviders = map[string]*builtinProvider{
},
Config: &coreconf.Config,
},
// osconf.Config.ID: {
// Runtime: &RunningProvider{
// Name: osconf.Config.Name,
// ID: osconf.Config.ID,
// Plugin: os.Init(),
// Schema: MustLoadSchema("os", osInfo),
// isClosed: false,
// },
// Config: &osconf.Config,
// },
// networkconf.Config.ID: {
// Runtime: &RunningProvider{
// Name: networkconf.Config.Name,
// ID: networkconf.Config.ID,
// Plugin: network.Init(),
// Schema: MustLoadSchema("network", networkInfo),
// isClosed: false,
// },
// Config: &networkconf.Config,
// },
// k8sconf.Config.ID: {
// Runtime: &RunningProvider{
// Name: k8sconf.Config.Name,
// ID: k8sconf.Config.ID,
// Plugin: k8s.Init(),
// Schema: MustLoadSchema("k8s", k8sInfo),
// isClosed: false,
// },
// Config: &k8sconf.Config,
// },
// azureconf.Config.ID: {
// Runtime: &RunningProvider{
// Name: azureconf.Config.Name,
// ID: azureconf.Config.ID,
// Plugin: azure.Init(),
// Schema: MustLoadSchema("azure", azureInfo),
// isClosed: false,
// },
// Config: &azureconf.Config,
}

type builtinProvider struct {
Runtime *RunningProvider
Config *plugin.Provider
}

func MustLoadSchema(name string, data []byte) *resources.Schema {
var res resources.Schema
if err := json.Unmarshal(data, &res); err != nil {
panic("failed to embed schema for " + name)
}
return &res
}

func MustLoadSchemaFromFile(name string, path string) *resources.Schema {
raw, err := osfs.ReadFile(path)
if err != nil {
panic("cannot read schema file: " + path)
}
return MustLoadSchema(name, raw)
}
8 changes: 8 additions & 0 deletions providers/coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ import (
"github.com/rs/zerolog/log"
pp "go.mondoo.com/cnquery/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/providers-sdk/v1/resources"
coreconf "go.mondoo.com/cnquery/providers/core/config"
"go.mondoo.com/cnquery/providers/core/resources/versions/semver"
)

var BuiltinCoreID = coreconf.Config.ID

var Coordinator = coordinator{
Running: []*RunningProvider{},
}
Expand All @@ -28,6 +31,11 @@ type coordinator struct {
mutex sync.Mutex
}

type builtinProvider struct {
Runtime *RunningProvider
Config *pp.Provider
}

type RunningProvider struct {
Name string
ID string
Expand Down
17 changes: 17 additions & 0 deletions providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"io"
"net/http"
"os"
osfs "os"
"path/filepath"
"runtime"
"strings"
Expand Down Expand Up @@ -567,3 +568,19 @@ func (p Providers) Add(nu *Provider) {
p[nu.ID] = nu
}
}

func MustLoadSchema(name string, data []byte) *resources.Schema {
var res resources.Schema
if err := json.Unmarshal(data, &res); err != nil {
panic("failed to embed schema for " + name)
}
return &res
}

func MustLoadSchemaFromFile(name string, path string) *resources.Schema {
raw, err := osfs.ReadFile(path)
if err != nil {
panic("cannot read schema file: " + path)
}
return MustLoadSchema(name, raw)
}

0 comments on commit 5602c92

Please sign in to comment.