github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/flagutil/github_enablement.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package flagutil 18 19 import ( 20 "flag" 21 "fmt" 22 "strings" 23 24 utilerrors "k8s.io/apimachinery/pkg/util/errors" 25 "k8s.io/apimachinery/pkg/util/sets" 26 ) 27 28 // GitHubEnablementOptions allows enable/disable functionality on a github org or 29 // org/repo level. If either EnabledOrgs or EnabledRepos is set, only org/repos in 30 // those are allowed, otherwise everything that is not in DisabledOrgs or DisabledRepos 31 // is allowed. 32 type GitHubEnablementOptions struct { 33 enabledOrgs Strings 34 enabledRepos Strings 35 disabledOrgs Strings 36 disabledRepos Strings 37 } 38 39 func (o *GitHubEnablementOptions) AddFlags(fs *flag.FlagSet) { 40 fs.Var(&o.enabledOrgs, "github-enabled-org", "Enabled github org. Can be passed multiple times. If set, all orgs or repos that are not allowed via --gitbub-enabled-orgs or --github-enabled-repos will be ignored") 41 fs.Var(&o.enabledRepos, "github-enabled-repo", "Enabled github repo in org/repo format. Can be passed multiple times. If set, all orgs or repos that are not allowed via --gitbub-enabled-orgs or --github-enabled-repos will be ignored") 42 fs.Var(&o.disabledOrgs, "github-disabled-org", "Disabled github org. Can be passed multiple times. Orgs that are in this list will be ignored.") 43 fs.Var(&o.disabledRepos, "github-disabled-repo", "Disabled github repo in org/repo format. Can be passed multiple times. Repos that are in this list will be ignored.") 44 } 45 46 func (o *GitHubEnablementOptions) Validate(_ bool) error { 47 var errs []error 48 49 for _, enabledRepo := range o.enabledRepos.vals { 50 if err := validateOrgRepoFormat(enabledRepo); err != nil { 51 errs = append(errs, fmt.Errorf("--github-enabled-repo=%s is invalid: %w", enabledRepo, err)) 52 } 53 } 54 for _, disabledRepo := range o.disabledRepos.vals { 55 if err := validateOrgRepoFormat(disabledRepo); err != nil { 56 errs = append(errs, fmt.Errorf("--github-disabled-repo=%s is invalid: %w", disabledRepo, err)) 57 } 58 } 59 60 if intersection := o.enabledOrgs.StringSet().Intersection(o.disabledOrgs.StringSet()); len(intersection) != 0 { 61 errs = append(errs, fmt.Errorf("%v is in both --github-enabled-org and --github-disabled-org", sets.List(intersection))) 62 } 63 64 if intersection := o.enabledRepos.StringSet().Intersection(o.disabledRepos.StringSet()); len(intersection) != 0 { 65 errs = append(errs, fmt.Errorf("%v is in both --github-enabled-repo and --github-disabled-repo", sets.List(intersection))) 66 } 67 68 return utilerrors.NewAggregate(errs) 69 } 70 71 func validateOrgRepoFormat(orgRepo string) error { 72 components := strings.Split(orgRepo, "/") 73 if n := len(components); n != 2 || components[0] == "" || components[1] == "" { 74 return fmt.Errorf("%q is not in org/repo format", orgRepo) 75 } 76 77 return nil 78 } 79 80 func (o *GitHubEnablementOptions) EnablementChecker() func(org, repo string) bool { 81 enabledOrgs := o.enabledOrgs.StringSet() 82 enabledRepos := o.enabledRepos.StringSet() 83 disabledOrgs := o.disabledOrgs.StringSet() 84 diabledRepos := o.disabledRepos.StringSet() 85 return func(org, repo string) bool { 86 if len(enabledOrgs) > 0 || len(enabledRepos) > 0 { 87 if !enabledOrgs.Has(org) && !enabledRepos.Has(org+"/"+repo) { 88 return false 89 } 90 } 91 92 return !disabledOrgs.Has(org) && !diabledRepos.Has(org+"/"+repo) 93 } 94 }