diff --git a/.goreleaser.yaml b/.goreleaser.yaml index dc53359..5f510cd 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,4 +1,4 @@ -project_name: peribolos-owners-syncer +project_name: kamajicli before: hooks: @@ -50,21 +50,18 @@ signs: artifacts: all output: true -# create a docker image -# https://goreleaser.com/customization/docker -dockers: -- image_templates: - - 'ghcr.io/maxgio92/{{.ProjectName}}:{{ .Tag }}' - - 'ghcr.io/maxgio92/{{.ProjectName}}:v{{ .Major }}.{{ .Minor }}' - - 'ghcr.io/maxgio92/{{.ProjectName}}:latest' - use: buildx - build_flag_templates: - - "--pull" - - "--label=org.opencontainers.image.created={{.Date}}" - - "--label=org.opencontainers.image.name={{.ProjectName}}" - - "--label=org.opencontainers.image.revision={{.FullCommit}}" - - "--label=org.opencontainers.image.version={{.Version}}" - - "--label=org.opencontainers.image.source={{.GitURL}}" +kos: +- base_image: cgr.dev/chainguard/static + repository: ghcr.io/maxgio92/kamajicli + bare: true + tags: + - '{{ .Version }}' + - '{{ .Major }}.{{ .Minor }}' + - latest + platforms: + - linux/amd64 + - linux/arm64 + sbom: spdx # signs our docker image # https://goreleaser.com/customization/docker_sign @@ -72,7 +69,7 @@ docker_signs: - cmd: cosign env: - COSIGN_EXPERIMENTAL=1 - artifacts: images + artifacts: all output: true args: - 'sign' diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 12c8908..0000000 --- a/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM scratch -COPY peribolos-owners-syncer /peribolos-owners-syncer -ENTRYPOINT ["/peribolos-owners-syncer"] - diff --git a/Makefile b/Makefile index b96f4ec..466df4e 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,7 @@ APP := peribolos-syncer -VERSION := 0.1.1 user := maxgio92 -oci_image := quay.io/$(user)/$(APP) - -bins := docker git go gofumpt golangci-lint - -PACKAGE_NAME := github.com/$(user)/$(APP) -GOLANG_CROSS_VERSION ?= v$(shell sed -nE 's/go[[:space:]]+([[:digit:]]\.[[:digit:]]+)/\1/p' go.mod) - -GIT_HEAD_COMMIT ?= $$($(git) rev-parse --short HEAD) -GIT_TAG_COMMIT ?= $$($(git) rev-parse --short $(VERSION)) -GIT_MODIFIED_1 ?= $$($(git) diff $(GIT_HEAD_COMMIT) $(GIT_TAG_COMMIT) --quiet && echo "" || echo ".dev") -GIT_MODIFIED_2 ?= $$($(git) diff --quiet && echo "" || echo ".dirty") -GIT_MODIFIED ?= $$(echo "$(GIT_MODIFIED_1)$(GIT_MODIFIED_2)") -GIT_REPO ?= $$($(git) config --get remote.origin.url) -BUILD_DATE ?= $$($(git) log -1 --format="%at" | xargs -I{} date -d @{} +%Y-%m-%dT%H:%M:%S) +bins := git go gofumpt golangci-lint ginkgo define declare_binpaths $(1) = $(shell command -v 2>/dev/null $(1)) @@ -25,6 +11,14 @@ $(foreach bin,$(bins),\ $(eval $(call declare_binpaths,$(bin)))\ ) +.PHONY: ginkgo +ginkgo: + @$(go) install github.com/onsi/ginkgo/v2/ginkgo + +.PHONY: docs +docs: + @go run docs/docs.go + .PHONY: build build: @$(go) build . @@ -34,8 +28,8 @@ run: @$(go) run . .PHONY: test -test: - @$(go) test -v -cover -gcflags=-l ./... +test: ginkgo + @$(ginkgo) ./... .PHONY: lint lint: golangci-lint @@ -49,20 +43,6 @@ golangci-lint: gofumpt: @$(go) install mvdan.cc/gofumpt@v0.3.1 -.PHONY: oci/build -oci/build: test - @$(docker) build . -t $(oci_image):$(VERSION) -f Dockerfile \ - --build-arg GIT_HEAD_COMMIT=$(GIT_HEAD_COMMIT) \ - --build-arg GIT_TAG_COMMIT=$(GIT_TAG_COMMIT) \ - --build-arg GIT_MODIFIED=$(GIT_MODIFIED) \ - --build-arg GIT_REPO=$(GIT_REPO) \ - --build-arg GIT_LAST_TAG=$(VERSION) \ - --build-arg BUILD_DATE=$(BUILD_DATE) - -.PHONY: oci/push -oci/push: oci/build - @$(docker) push $(oci_image):$(VERSION) - .PHONY: clean clean: @rm -f $(APP) @@ -73,4 +53,3 @@ help: list .PHONY: list list: @LC_ALL=C $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' - diff --git a/cmd/contants.go b/cmd/contants.go new file mode 100644 index 0000000..11df9c6 --- /dev/null +++ b/cmd/contants.go @@ -0,0 +1,10 @@ +package cmd + +const ( + CommandName = "peribolos-syncer" + CommandLongDescription = ` +Tool to synchronize Peribolos configuration from external sources. + +It synchronize GitHub Team configurations with external GitHub people source of truth, like OWNERS files. +` +) diff --git a/cmd/root.go b/cmd/root.go index 71b1b82..db552b6 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,13 +24,12 @@ import ( "github.com/maxgio92/peribolos-syncer/internal/output" ) -var cfgFile string - // New returns a new root command. func New() *cobra.Command { cmd := &cobra.Command{} - cmd.Use = "orgs-owners-syncer" - cmd.Short = "A brief description of your application" + cmd.Use = CommandName + cmd.Long = CommandLongDescription + cmd.DisableAutoGenTag = true // Add subcommands. cmd.AddCommand(sync.New()) diff --git a/cmd/sync/contants.go b/cmd/sync/contants.go new file mode 100644 index 0000000..8679e94 --- /dev/null +++ b/cmd/sync/contants.go @@ -0,0 +1,6 @@ +package sync + +const ( + commandName = "sync" + commandShortDescription = "Synchronize Peribolos config with external GitHub people source of truth" +) diff --git a/cmd/sync/github/constants.go b/cmd/sync/github/constants.go index b8d4fd7..b1489ef 100644 --- a/cmd/sync/github/constants.go +++ b/cmd/sync/github/constants.go @@ -1,6 +1,17 @@ package github const ( + commandName = "github" + commandShortDescription = "Synchronize Peribolos config on remote GitHub repositories via Pull Request" + commandExample = ` +peribolos-syncer sync github --org=acme --team=app-maintainers +--peribolos-config-path=config/org.yaml --peribolos-config-repository=community --peribolos-config-git-ref=main +--owners-repository=app --owners-git-ref=main --owners-path=OWNERS +--github-username=bot --github-token-path=./bot_token +--git-author-name=bot --git-author-email="bot@acme.org" +--gpg-public-key=./bot.pub --gpg-private-key=./bot.asc +` + syncerSignature = "Autogenerated with [peribolos-syncer](https://github.com/maxgio92/peribolos-syncer)." ownersDoc = "https://docs.prow.k8s.io/docs/components/plugins/approve/approvers/#overview" peribolosConfigFile = "org.yaml" diff --git a/cmd/sync/github/sync_github.go b/cmd/sync/github/sync_github.go index 13a0dcc..cb4aeff 100644 --- a/cmd/sync/github/sync_github.go +++ b/cmd/sync/github/sync_github.go @@ -65,9 +65,10 @@ func New() *cobra.Command { } cmd := &cobra.Command{ - Use: "github", - Short: "Synchronize Peribolos org.yaml file from OWNERS file on remote github repositories via Pull Request", - RunE: o.Run, + Use: commandName, + Short: commandShortDescription, + Example: commandExample, + RunE: o.Run, } // Organization sync options. diff --git a/cmd/sync/local/constants.go b/cmd/sync/local/constants.go index a6ce0f3..613a1ca 100644 --- a/cmd/sync/local/constants.go +++ b/cmd/sync/local/constants.go @@ -17,6 +17,12 @@ limitations under the License. package local const ( + commandName = "local" + commandShortDescription = "Synchronize Peribolos config on local filesystem" + commandExample = ` +peribolos-syncer sync local --owners-file OWNERS --peribolos-config org.yaml --org acme --team app-maintainers +` + flagOwnersFilePath = "owners-file" flagPeribolosConfigFilepath = "orgs-config" defaultOwnersFilepath = "OWNERS" diff --git a/cmd/sync/local/sync_local.go b/cmd/sync/local/sync_local.go index 6398c34..c001325 100644 --- a/cmd/sync/local/sync_local.go +++ b/cmd/sync/local/sync_local.go @@ -44,8 +44,9 @@ func New() *cobra.Command { } cmd := &cobra.Command{ - Use: "local", - Short: "Synchronize Peribolos org.yaml file from OWNERS file in the local filesystem", + Use: commandName, + Short: commandShortDescription, + Example: commandExample, } cmd.RunE = o.Run diff --git a/cmd/sync/sync.go b/cmd/sync/sync.go index 0490c2a..470b405 100644 --- a/cmd/sync/sync.go +++ b/cmd/sync/sync.go @@ -26,8 +26,8 @@ import ( // New returns a new root command. func New() *cobra.Command { cmd := &cobra.Command{ - Use: "sync", - Short: "Synchronize Peribolos org,yaml file from OWNERS file", + Use: commandName, + Short: commandShortDescription, } // Add sync subcommand. diff --git a/docs/_index.md b/docs/_index.md new file mode 100644 index 0000000..5ca942a --- /dev/null +++ b/docs/_index.md @@ -0,0 +1,27 @@ +--- +title: peribolos-syncer +--- + +## peribolos-syncer + + + +### Synopsis + + +Tool to synchronize Peribolos configuration from external sources. + +It synchronize GitHub Team configurations with external GitHub people source of truth, like OWNERS files. + + +### Options + +``` + -h, --help help for peribolos-syncer +``` + +### SEE ALSO + +* [peribolos-syncer sync](peribolos-syncer_sync.md) - Synchronize Peribolos config with external GitHub people source of truth +* [peribolos-syncer version](peribolos-syncer_version.md) - Return the syncer version + diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..2cce6a1 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,52 @@ +package main + +import ( + "fmt" + "os" + "path" + "strings" + + "github.com/spf13/cobra/doc" + + "github.com/maxgio92/peribolos-syncer/cmd" +) + +const ( + docsDir = "docs" + fileTemplate = `--- +title: %s +--- + +` +) + +var ( + filePrepender = func(filename string) string { + title := strings.TrimPrefix(strings.TrimSuffix(strings.ReplaceAll(filename, "_", " "), ".md"), fmt.Sprintf("%s/", docsDir)) + return fmt.Sprintf(fileTemplate, title) + } + linkHandler = func(filename string) string { + if filename == cmd.CommandName+".md" { + return "_index.md" + } + return filename + } +) + +func main() { + if err := doc.GenMarkdownTreeCustom( + cmd.New(), + docsDir, + filePrepender, + linkHandler, + ); err != nil { + fmt.Println(err) + os.Exit(1) + } + + err := os.Rename(path.Join(docsDir, cmd.CommandName+".md"), path.Join(docsDir, "_index.md")) + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/docs/peribolos-syncer_sync.md b/docs/peribolos-syncer_sync.md new file mode 100644 index 0000000..cd2670b --- /dev/null +++ b/docs/peribolos-syncer_sync.md @@ -0,0 +1,20 @@ +--- +title: peribolos-syncer sync +--- + +## peribolos-syncer sync + +Synchronize Peribolos config with external GitHub people source of truth + +### Options + +``` + -h, --help help for sync +``` + +### SEE ALSO + +* [peribolos-syncer](_index.md) - +* [peribolos-syncer sync github](peribolos-syncer_sync_github.md) - Synchronize Peribolos config on remote GitHub repositories via Pull Request +* [peribolos-syncer sync local](peribolos-syncer_sync_local.md) - Synchronize Peribolos config on local filesystem + diff --git a/docs/peribolos-syncer_sync_github.md b/docs/peribolos-syncer_sync_github.md new file mode 100644 index 0000000..286b73b --- /dev/null +++ b/docs/peribolos-syncer_sync_github.md @@ -0,0 +1,63 @@ +--- +title: peribolos-syncer sync github +--- + +## peribolos-syncer sync github + +Synchronize Peribolos config on remote GitHub repositories via Pull Request + +``` +peribolos-syncer sync github [flags] +``` + +### Examples + +``` + +peribolos-syncer sync github --org=acme --team=app-maintainers +--peribolos-config-path=config/org.yaml --peribolos-config-repository=community --peribolos-config-git-ref=main +--owners-repository=app --owners-git-ref=main --owners-path=OWNERS +--github-username=bot --github-token-path=./bot_token +--git-author-name=bot --git-author-email="bot@acme.org" +--gpg-public-key=./bot.pub --gpg-private-key=./bot.asc + +``` + +### Options + +``` + --dry-run Dry run for testing. Uses API tokens but does not mutate. + --git-author-email string The Git author email with which write commits for the update of the Peribolos config + --git-author-name string The Git author name with which write commits for the update of the Peribolos config + --github-allowed-burst int Size of token consumption bursts. If set, --github-hourly-tokens must be positive too and set to a higher or equal number. + --github-app-id string ID of the GitHub app. If set, requires --github-app-private-key-path to be set and --github-token-path to be unset. + --github-app-private-key-path string Path to the private key of the github app. If set, requires --github-app-id to bet set and --github-token-path to be unset + --github-client.backoff-timeout duration Largest allowable Retry-After time for requests to the GitHub API. (default 2m0s) + --github-client.initial-delay duration Initial delay before retries begin for requests to the GitHub API. (default 2s) + --github-client.max-404-retries int Maximum number of retries that will be used for a 404-ing request to the GitHub API. (default 2) + --github-client.max-retries int Maximum number of retries that will be used for a failing request to the GitHub API. (default 8) + --github-client.request-timeout duration Timeout for any single request to the GitHub API. (default 2m0s) + --github-endpoint Strings GitHub's API endpoint (may differ for enterprise). (default https://api.github.com) + --github-graphql-endpoint string GitHub GraphQL API endpoint (may differ for enterprise). (default "https://api.github.com/graphql") + --github-host string GitHub's default host (may differ for enterprise) (default "github.com") + --github-hourly-tokens int If set to a value larger than zero, enable client-side throttling to limit hourly token consumption. If set, --github-allowed-burst must be positive too. + --github-throttle-org Strings Throttler settings for a specific org in org:hourlyTokens:burst format. Can be passed multiple times. Only valid when using github apps auth. + --github-token-path string Path to the file containing the GitHub OAuth secret. + --github-username string The GitHub username + --gpg-private-key string The path to the private GPG key for signing git commits + --gpg-public-key string The path to the public GPG key for signing git commits + -h, --help help for github + --org string The name of the GitHub organization to update configuration for + -r, --owners-git-ref string The base Git reference at which parse the OWNERS hierarchy (default "master") + -o, --owners-path string The path to the OWNERS file from the root of the Git repository. Ignored with sync-github. + --owners-repository string The name of the github repository from which parse OWNERS file + --peribolos-config-git-ref string The base Git reference at which pull the peribolos config repository (default "master") + -c, --peribolos-config-path string The path to the peribolos organization config file from the root of the Git repository (default "org.yaml") + --peribolos-config-repository string The name of the github repository that contains the peribolos organization config file + --team string The name of the GitHub team to update configuration for +``` + +### SEE ALSO + +* [peribolos-syncer sync](peribolos-syncer_sync.md) - Synchronize Peribolos config with external GitHub people source of truth + diff --git a/docs/peribolos-syncer_sync_local.md b/docs/peribolos-syncer_sync_local.md new file mode 100644 index 0000000..e9734c1 --- /dev/null +++ b/docs/peribolos-syncer_sync_local.md @@ -0,0 +1,34 @@ +--- +title: peribolos-syncer sync local +--- + +## peribolos-syncer sync local + +Synchronize Peribolos config on local filesystem + +``` +peribolos-syncer sync local [flags] +``` + +### Examples + +``` + +peribolos-syncer sync local --owners-file OWNERS --peribolos-config org.yaml --org acme --team app-maintainers + +``` + +### Options + +``` + -h, --help help for local + --org string The name of the GitHub organization to update + -c, --orgs-config string The path to the Peribolos org.yaml file (default "org.yaml") + -o, --owners-file string The path to the OWNERS file (default "OWNERS") + --team string The name of the GitHub organization to update +``` + +### SEE ALSO + +* [peribolos-syncer sync](peribolos-syncer_sync.md) - Synchronize Peribolos config with external GitHub people source of truth + diff --git a/docs/peribolos-syncer_version.md b/docs/peribolos-syncer_version.md new file mode 100644 index 0000000..4b813ce --- /dev/null +++ b/docs/peribolos-syncer_version.md @@ -0,0 +1,22 @@ +--- +title: peribolos-syncer version +--- + +## peribolos-syncer version + +Return the syncer version + +``` +peribolos-syncer version [flags] +``` + +### Options + +``` + -h, --help help for version +``` + +### SEE ALSO + +* [peribolos-syncer](_index.md) - + diff --git a/go.mod b/go.mod index 33a66eb..03acb73 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.20 require ( bitbucket.org/creachadair/stringset v0.0.9 github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 + github.com/go-git/go-billy/v5 v5.3.1 github.com/go-git/go-git/v5 v5.4.2 github.com/google/uuid v1.3.0 github.com/onsi/ginkgo/v2 v2.1.4 @@ -41,6 +42,7 @@ require ( github.com/blendle/zapdriver v1.3.1 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denormal/go-gitignore v0.0.0-20180930084346-ae8ad1d07817 // indirect @@ -54,7 +56,6 @@ require ( github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/fvbommel/sortorder v1.0.1 // indirect github.com/go-git/gcfg v1.5.0 // indirect - github.com/go-git/go-billy/v5 v5.3.1 // indirect github.com/go-kit/log v0.1.0 // indirect github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -105,6 +106,7 @@ require ( github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/prometheus/statsd_exporter v0.21.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sergi/go-diff v1.1.0 // indirect github.com/shurcooL/githubv4 v0.0.0-20210725200734-83ba7b4c9228 // indirect github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect diff --git a/go.sum b/go.sum index 9033bd4..a64e686 100644 --- a/go.sum +++ b/go.sum @@ -175,6 +175,7 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/staticfile v0.1.3/go.mod h1:a3qySzCIXEprDGxk6tSxSI+dBBdLzqeBOMhZ+o2d3pM= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -581,6 +582,7 @@ github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3M github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= diff --git a/internal/github/github.go b/internal/github/github.go index 08459d8..072352e 100644 --- a/internal/github/github.go +++ b/internal/github/github.go @@ -44,7 +44,7 @@ type GitHubOptions struct { } func (o *GitHubOptions) AddPFlags(pfs *pflag.FlagSet) { - pfs.BoolVar(&o.DryRun, "dry-run", true, "Dry run for testing. Uses API tokens but does not mutate.") + pfs.BoolVar(&o.DryRun, "dry-run", false, "Dry run for testing. Uses API tokens but does not mutate.") pfs.StringVar(&o.Username, "github-username", "", "The GitHub username") fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError) diff --git a/pkg/peribolos/config.go b/pkg/peribolos/config.go new file mode 100644 index 0000000..05f23fd --- /dev/null +++ b/pkg/peribolos/config.go @@ -0,0 +1,97 @@ +package peribolos + +import ( + "fmt" + "io" + + "bitbucket.org/creachadair/stringset" + "github.com/go-git/go-billy/v5" + "github.com/pkg/errors" + peribolos "k8s.io/test-infra/prow/config/org" + "sigs.k8s.io/yaml" +) + +// NewConfig returns a new orgs.FullConfig structure. +func NewConfig() *peribolos.FullConfig { + return &peribolos.FullConfig{Orgs: map[string]peribolos.Config{}} +} + +// LoadConfigFromFilesystem loads the peribolos config from the filesystem. +// It possibly returns an error. +func LoadConfigFromFilesystem(fs billy.Filesystem, configPath string) (*peribolos.FullConfig, error) { + r, err := fs.Open(configPath) + if err != nil { + return nil, errors.Wrap(err, "error opening peribolos config file") + } + + b, err := io.ReadAll(r) + if err != nil { + return nil, errors.Wrap(err, "error reading peribolos config file") + } + + config := NewConfig() + + if err = yaml.Unmarshal(b, config); err != nil { + return nil, errors.Wrap(err, "error unmarshaling peribolos config") + } + + return config, nil +} + +// AddTeamMaintainers updates the maintainers of the specified Team in the specified Organization, adding the maintainers +// list specified as agument. +func AddTeamMaintainers(config *peribolos.FullConfig, org, team string, maintainers []string) error { + orgConfig, ok := config.Orgs[org] + if !ok { + //nolint:goerr113 + return fmt.Errorf("organization not found in peribolos config") + } + + teamConfig, ok := orgConfig.Teams[team] + if !ok { + //nolint:goerr113 + return fmt.Errorf("team not fonud in organization %s peribolos config", org) + } + + m := teamConfig.Maintainers + for _, v := range maintainers { + if !stringset.Contains(m, v) { + m = append(m, v) + } + } + + teamConfig.Maintainers = m + orgConfig.Teams[team] = teamConfig + config.Orgs[org] = orgConfig + + return nil +} + +// AddTeamMembers updates the members of the specified Team in the specified Organization, adding the members list +// specified as argument. +func AddTeamMembers(config *peribolos.FullConfig, org, team string, members []string) error { + orgConfig, ok := config.Orgs[org] + if !ok { + //nolint:goerr113 + return errors.New("organization not found in peribolos config") + } + + teamConfig, ok := orgConfig.Teams[team] + if !ok { + //nolint:goerr113 + return fmt.Errorf("team not found in organization %s peribolos config", org) + } + + m := teamConfig.Members + for _, v := range members { + if !stringset.Contains(m, v) { + m = append(m, v) + } + } + + teamConfig.Members = m + orgConfig.Teams[team] = teamConfig + config.Orgs[org] = orgConfig + + return nil +} diff --git a/pkg/peribolos/peribolos.go b/pkg/peribolos/peribolos.go index 6845628..92c571f 100644 --- a/pkg/peribolos/peribolos.go +++ b/pkg/peribolos/peribolos.go @@ -18,14 +18,7 @@ package peribolos import ( "fmt" - "io" - - "bitbucket.org/creachadair/stringset" - "github.com/go-git/go-billy/v5" - "github.com/pkg/errors" "github.com/spf13/pflag" - peribolos "k8s.io/test-infra/prow/config/org" - "sigs.k8s.io/yaml" ) type PeribolosOptions struct { @@ -35,34 +28,11 @@ type PeribolosOptions struct { } const ( - baseRef = "master" + gitRef = "master" ) -// NewConfig returns a new orgs.FullConfig structure. -func NewConfig() *peribolos.FullConfig { - return &peribolos.FullConfig{Orgs: map[string]peribolos.Config{}} -} - -// LoadConfigFromFilesystem loads the peribolos config from the filesystem. -// It possibly returns an error. -func LoadConfigFromFilesystem(fs billy.Filesystem, configPath string) (*peribolos.FullConfig, error) { - r, err := fs.Open(configPath) - if err != nil { - return nil, errors.Wrap(err, "error opening peribolos config file") - } - - b, err := io.ReadAll(r) - if err != nil { - return nil, errors.Wrap(err, "error reading peribolos config file") - } - - config := NewConfig() - - if err = yaml.Unmarshal(b, config); err != nil { - return nil, errors.Wrap(err, "error unmarshaling peribolos config") - } - - return config, nil +func NewOptions() *PeribolosOptions { + return &PeribolosOptions{} } // Validate validates peribolos options. It possibly returns an error. @@ -79,63 +49,5 @@ func (o *PeribolosOptions) Validate() error { func (o *PeribolosOptions) AddPFlags(pfs *pflag.FlagSet) { pfs.StringVar(&o.ConfigRepo, "peribolos-config-repository", "", "The name of the github repository that contains the peribolos organization config file") pfs.StringVarP(&o.ConfigPath, "peribolos-config-path", "c", "org.yaml", "The path to the peribolos organization config file from the root of the Git repository") - pfs.StringVar(&o.ConfigBaseRef, "peribolos-config-git-ref", baseRef, "The base Git reference at which pull the peribolos config repository") -} - -// AddTeamMaintainers updates the maintainers of the specified Team in the specified Organization, adding the maintainers -// list specified as agument. -func AddTeamMaintainers(config *peribolos.FullConfig, org, team string, maintainers []string) error { - orgConfig, ok := config.Orgs[org] - if !ok { - //nolint:goerr113 - return fmt.Errorf("organization not found in peribolos config") - } - - teamConfig, ok := orgConfig.Teams[team] - if !ok { - //nolint:goerr113 - return fmt.Errorf("team not fonud in organization %s peribolos config", org) - } - - m := teamConfig.Maintainers - for _, v := range maintainers { - if !stringset.Contains(m, v) { - m = append(m, v) - } - } - - teamConfig.Maintainers = m - orgConfig.Teams[team] = teamConfig - config.Orgs[org] = orgConfig - - return nil -} - -// AddTeamMembers updates the members of the specified Team in the specified Organization, adding the members list -// specified as argument. -func AddTeamMembers(config *peribolos.FullConfig, org, team string, members []string) error { - orgConfig, ok := config.Orgs[org] - if !ok { - //nolint:goerr113 - return errors.New("organization not found in peribolos config") - } - - teamConfig, ok := orgConfig.Teams[team] - if !ok { - //nolint:goerr113 - return fmt.Errorf("team not found in organization %s peribolos config", org) - } - - m := teamConfig.Members - for _, v := range members { - if !stringset.Contains(m, v) { - m = append(m, v) - } - } - - teamConfig.Members = m - orgConfig.Teams[team] = teamConfig - config.Orgs[org] = orgConfig - - return nil + pfs.StringVar(&o.ConfigBaseRef, "peribolos-config-git-ref", gitRef, "The base Git reference at which pull the peribolos config repository") } diff --git a/testdata/OWNERS b/testdata/OWNERS deleted file mode 100644 index 7cd0f9e..0000000 --- a/testdata/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -approvers: - - PIPPO - - maxgio92 - - jonahjon - - leogr - - zuc - - fededp -emeritus_approvers: - - leodido - - fntlnz diff --git a/testdata/org.yaml b/testdata/org.yaml deleted file mode 100644 index 6756b9d..0000000 --- a/testdata/org.yaml +++ /dev/null @@ -1,728 +0,0 @@ -orgs: - falcosecurity: - admins: - - caniszczyk - - ldegio - - leogr - - mstemm - - poiana - - thelinuxfoundation - - jasondellaluce - - LucaGuerra - default_repository_permission: read - description: Falco is Container Native Runtime Security - has_organization_projects: true - has_repository_projects: true - members: - - admiral0 - - alacuku - - Andreagit97 - - araujof - - bencer - - cpanato - - cappellinsamuele - - darryk10 - - dwindsor - - ewilderj - - EXONER4TED - - FedeDP - - fjogeleit - - gnosek - - hbrueckner - - incertum - - Issif - - jonahjon - - Kaizhe - - krisnova - - leodido - - loresuso - - markyjackson-taulia - - maxgio92 - - mfdii - - mmat11 - - Molter73 - - terylt - - vjjmiras - - zuc - members_can_create_repositories: false - name: Falco - repos: - .github: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Default community health files - has_projects: false - has_wiki: false - advocacy: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - description: Advocacy machinery - has_projects: true - charts: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Community managed Helm charts for running Falco with Kubernetes - has_projects: true - has_wiki: false - client-go: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Go client and SDK for Falco - has_projects: true - client-py: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - description: Python client and SDK for Falco - has_projects: true - has_wiki: false - client-rs: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - description: The rust language implementation of the Falco client - has_projects: true - community: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: The Falco Project Community - has_projects: true - has_wiki: false - contrib: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Community sandbox to test-drive ideas/projects/code - has_projects: true - has_wiki: false - deploy-kubernetes: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Kubernetes deployment resources for Falco - has_projects: false - has_wiki: false - driverkit: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: 'Kit for building Falco drivers: kernel modules or eBPF probes' - has_projects: true - ebpf-probe: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - description: eBPF probe for syscall events - has_projects: true - event-generator: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Generate a variety of suspect actions that are detected by Falco - rulesets - has_projects: true - evolution: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Evolution process of The Falco Project - has_projects: true - has_wiki: false - falco: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Cloud Native Runtime Security - has_projects: true - has_wiki: false - homepage: https://falco.org - falco-aws-terraform: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Terraform Module for Falco AWS Resources - has_projects: true - falco-exporter: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Prometheus Metrics Exporter for Falco output events - has_projects: true - falco-website: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Source code of the official Falco website - has_projects: true - homepage: https://falco.org - falcoctl: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Administrative tooling for Falco - has_projects: true - has_wiki: false - falcosidekick: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Connect Falco to your ecosystem - has_projects: true - has_wiki: false - falcosidekick-ui: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: A simple WebUI with latest events from Falco - has_projects: true - has_wiki: false - flycheck-falco-rules: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Falco Rules Syntax Checker for Emacs, Using Flycheck - has_projects: true - kernel-crawler: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: A tool to crawl Linux kernel versions - has_projects: false - has_wiki: false - kernel-module: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - has_projects: true - kilt: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Kilt is a project that defines how to inject foreign apps into - containers - has_projects: true - has_wiki: false - libs: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: libsinsp, libscap, the kernel module driver, and the eBPF driver - sources - has_projects: true - has_wiki: false - libs-sdk-go: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Go SDK for Falco libs - has_projects: true - has_wiki: false - libscap: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - has_projects: true - libsinsp: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - description: 'System inspection library ' - has_projects: true - pdig: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - description: ptrace-based event producer for udig - has_projects: true - has_wiki: false - pigeon: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Secrets and config manager for Falco's infrastructure - has_projects: true - has_wiki: false - plugin-sdk-cpp: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Falco plugins SDK for C++ - has_projects: true - plugin-sdk-go: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: Falco plugins SDK for Go - has_projects: true - plugins: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Falco plugins registry - has_projects: true - rules: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Falco rule repository - has_projects: false - has_wiki: false - syscalls-bumper: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: A tool to automatically update supported syscalls in libs - has_projects: false - has_wiki: false - template-repository: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - archived: true - description: Acts as a template for new repositories - has_projects: true - test-infra: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - description: Falco workflow & testing infrastructure - has_projects: true - has_wiki: false - homepage: https://prow.falco.org - testing: - allow_merge_commit: false - allow_rebase_merge: true - allow_squash_merge: false - default_branch: main - description: All-purpose test suite for Falco and its ecosystem - has_projects: true - has_wiki: false - teams: - admins: - description: admins of the org - maintainers: - - caniszczyk - - ldegio - - leogr - - thelinuxfoundation - - mstemm - privacy: closed - repos: - advocacy: admin - charts-maintainers: - description: maintainers of falcosecurity/charts - maintainers: - - leogr - members: - - cpanato - - Issif - privacy: closed - repos: - charts: maintain - client-go-maintainers: - description: maintainers of falcosecurity/client-go - maintainers: - - leogr - members: - - leodido - privacy: closed - repos: - client-go: maintain - client-py-maintainers: - description: maintainers of falcosecurity/client-py - members: - - leodido - - mmat11 - privacy: closed - repos: - client-py: maintain - client-rs-maintainers: - description: maintainers of falcosecurity/client-rs - members: - - leodido - privacy: closed - repos: - client-rs: maintain - community-maintainers: - description: maintainers of falcosecurity/community - maintainers: - - leogr - members: - - Issif - - araujof - - maxgio92 - - terylt - - Andreagit97 - privacy: closed - repos: - community: maintain - contrib-maintainers: - description: maintainers of falcosecurity/contrib - maintainers: - - leogr - members: - - maxgio92 - - jasondellaluce - privacy: closed - repos: - contrib: maintain - core-maintainers: - description: Core maintainers of The Falco Project - maintainers: - - leogr - - mstemm - members: - - gnosek - - cpanato - - Issif - - FedeDP - - maxgio92 - - zuc - - jasondellaluce - - Molter73 - - LucaGuerra - - Andreagit97 - - incertum - privacy: closed - deploy-kubernetes-maintainers: - description: maintainers of falcosecurity/deploy-kubernetes - maintainers: - - leogr - members: - - maxgio92 - - zuc - - jasondellaluce - privacy: closed - repos: - deploy-kubernetes: maintain - driverkit-maintainers: - description: maintainers of falcosecurity/driverkit - members: - - leodido - - dwindsor - - FedeDP - - EXONER4TED - privacy: closed - repos: - driverkit: maintain - event-generator-maintainers: - description: maintainers of falcosecurity/event-generator - maintainers: - - leogr - members: - - FedeDP - privacy: closed - repos: - event-generator: maintain - evolution-maintainers: - description: maintainers of falcosecurity/evolution - maintainers: - - leogr - members: - - maxgio92 - - jasondellaluce - privacy: closed - repos: - evolution: maintain - falco-aws-terraform-maintainers: - description: maintainers of falcosecurity/falco-aws-terraform - maintainers: - - ldegio - - leogr - - mstemm - members: - - zuc - - jasondellaluce - privacy: closed - repos: - falco-aws-terraform: maintain - falco-exporter-maintainers: - description: maintainers of falcosecurity/falco-exporter - maintainers: - - leogr - members: - - jasondellaluce - privacy: closed - repos: - falco-exporter: maintain - falco-maintainers: - description: maintainers of falcosecurity/falco - maintainers: - - leogr - - mstemm - members: - - FedeDP - - jasondellaluce - - Andreagit97 - privacy: closed - repos: - falco: maintain - falco-website-maintainers: - description: maintainers of falcosecurity/falco-website - maintainers: - - leogr - members: - - Issif - - jasondellaluce - - vjjmiras - privacy: closed - repos: - falco-website: maintain - falcoctl-maintainers: - description: maintainers of falcosecurity/falcoctl - maintainers: - - leogr - members: - - zuc - - maxgio92 - - fededp - - cpanato - privacy: closed - repos: - falcoctl: maintain - falcosidekick-maintainers: - description: maintainers of falcosecurity/falcosidekick - maintainers: - - leogr - members: - - cpanato - - Issif - - fjogeleit - privacy: closed - repos: - falcosidekick: maintain - falcosidekick-ui-maintainers: - description: maintainers of falcosecurity/falcosidekick-ui - members: - - cpanato - - Issif - - fjogeleit - privacy: closed - repos: - falcosidekick-ui: maintain - flycheck-falco-rules-maintainers: - description: maintainers of falcosecurity/flycheck-falco-rules - maintainers: - - mstemm - - ewilderj - privacy: closed - repos: - flycheck-falco-rules: maintain - github-maintainers: - description: maintainers of falcosecurity/.github - maintainers: - - leogr - members: - - maxgio92 - - jasondellaluce - privacy: closed - repos: - .github: maintain - kernel-crawler-maintainers: - description: maintainers of falcosecurity/kernel-crawler - maintainers: - - leogr - members: - - FedeDP - - maxgio92 - - zuc - privacy: closed - repos: - kernel-crawler: maintain - kilt-maintainers: - description: maintainers of falcosecurity/kilt - members: - - gnosek - - leodido - - admiral0 - privacy: closed - repos: - kilt: maintain - libs-maintainers: - description: maintainers of falcosecurity/libs - maintainers: - - leogr - - mstemm - - jasondellaluce - members: - - gnosek - - FedeDP - - Molter73 - - LucaGuerra - - Andreagit97 - - hbrueckner - - incertum - privacy: closed - repos: - libs: maintain - libs-sdk-go-maintainers: - description: maintainers of falcosecurity/libs-sdk-go - maintainers: - - leogr - members: - - araujof - - jasondellaluce - - terylt - - Andreagit97 - privacy: closed - repos: - libs-sdk-go: maintain - machine_users: - description: bots - maintainers: - - poiana - privacy: closed - repos: - .github: admin - charts: admin - client-go: admin - client-py: admin - client-rs: admin - community: admin - contrib: admin - deploy-kubernetes: admin - driverkit: admin - event-generator: admin - evolution: admin - falco: admin - falco-aws-terraform: admin - falco-exporter: admin - falco-website: admin - falcoctl: admin - falcosidekick: admin - falcosidekick-ui: admin - flycheck-falco-rules: admin - kernel-crawler: admin - kilt: admin - libs: admin - libs-sdk-go: admin - pdig: admin - pigeon: admin - plugin-sdk-cpp: admin - plugin-sdk-go: admin - plugins: admin - syscalls-bumper: admin - test-infra: admin - testing: admin - pdig-maintainers: - description: maintainers of falcosecurity/pdig - maintainers: - - ldegio - members: - - gnosek - - leodido - privacy: closed - repos: - pdig: maintain - pigeon-maintainers: - description: maintainers of falcosecurity/pigeon - maintainers: - - jasondellaluce - members: - - cappellinsamuele - - fededp - privacy: closed - repos: - pigeon: maintain - plugin-sdk-cpp-maintainers: - description: maintainers of falcosecurity/plugin-sdk-cpp - maintainers: - - ldegio - - leogr - - mstemm - members: - - leodido - - FedeDP - privacy: closed - repos: - plugin-sdk-cpp: maintain - plugin-sdk-go-maintainers: - description: maintainers of falcosecurity/plugin-sdk-go - maintainers: - - leogr - members: - - jasondellaluce - privacy: closed - repos: - plugin-sdk-go: maintain - plugins-maintainers: - description: maintainers of falcosecurity/plugins - maintainers: - - leogr - - mstemm - members: - - jasondellaluce - privacy: closed - repos: - plugins: maintain - rules-maintainers: - description: maintainers of falcosecurity/rules - maintainers: - - leogr - - LucaGuerra - members: - - fededp - - jasondellaluce - - andreagit97 - - mstemm - privacy: closed - repos: - rules: maintain - syscalls-bumper-maintainers: - description: maintainers of falcosecurity/syscalls-bumper - maintainers: - - leogr - members: - - FedeDP - - Andreagit97 - privacy: closed - repos: - syscalls-bumper: maintain - test-infra-maintainers: - description: maintainers of falcosecurity/test-infra - maintainers: - - leogr - members: - - maxgio92 - - zuc - - jonahjon - - fededp - privacy: closed - repos: - test-infra: maintain - testing-maintainers: - description: maintainers of falcosecurity/testing - maintainers: - - jasondellaluce - - leogr - members: - - andreagit97 - - lucaguerra - privacy: closed - repos: - testing: maintain