-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* bump kafka-go to include acl apis * add acl interfaces and aclinfo type stub * pull latest kafka-go and use kafka-go aclresource type * wip * fix test * fix typos * get acls working * getacls working * upgrade cobra to latest * finish separating get into separate subcommands * remove unneeded variables * wip * pr feedback * Revert "upgrade cobra to latest" This reverts commit 7b8ee42. * use getCliRunnerAndCtx in get acls * more consistent variable names * custom cobra type * bring in new kafka-go * support resource pattern type * add support for acloperationtype and remove options for unknown * improve descriptions * support permissiontype and host filters * add resource name filter and fix permission type formatting * support principal filtering * improve docs * add examples * remove comment * remove TODOs that are complete * remove TODOs that are complete * update README * fix test * wip * fix error handling * error handling for zk * more consistent error msg * clean up createacl * add TestBrokerClientCreateACLReadOnly * improve zk tests * run acl tests in ci * enable acls for kafka 2.4.1 in ci * fix zk tests * skip TestBrokerClientCreateACLReadOnly on old versions of kafka * try to debug * handle nested errors from createacls * operations -> operation * operations -> operation * remove setting log level in test * clean up allowed types in help command * fix merge conflict * fix test * add json annotations * bump kafka-go to version on main * wip * basic tests * start on getusers cmd * add json annotations * get users working * wip * add todos and fix type annotaitons * improve test * use CanTestBrokerAdminSecurity to feature flag test * update README * remove duplicate test from merge conflicts * fix more merge conflicts * create user working * add uncommitted files * start adding validation * meta validation for users * wip * support dry run and skip confirm * wip * wip * add more files * resourcemta * consistency checking for acls * remove emacs backups * remove user stuff * remove diff from cluster.yaml file * remove diff from topic file * remove debug log * smaller diff * remove completed todos * remove unused error helper * add missing meta file * skip ACL tests when ACLs cannot be used due to kafka version limitations * fix loadacls test * add more todos * add validation and set defaults * don't use ioutil * move confirm to util package * move confirm to util package * add create to README * use validation and setdefaults * add example acl * fix formatting in readme * use released version of kafka-go * fix spelling * make invalid field more obvious * fix dryrun and skip confirm * fix grammar
- Loading branch information
1 parent
4e44ea4
commit e9241f4
Showing
32 changed files
with
1,546 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,3 +17,6 @@ vendor/ | |
build/ | ||
|
||
.vscode | ||
|
||
# Emacs backups | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
package subcmd | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"os/signal" | ||
"path/filepath" | ||
"syscall" | ||
|
||
"github.com/segmentio/topicctl/pkg/admin" | ||
"github.com/segmentio/topicctl/pkg/cli" | ||
"github.com/segmentio/topicctl/pkg/config" | ||
"github.com/segmentio/topicctl/pkg/create" | ||
log "github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var createCmd = &cobra.Command{ | ||
Use: "create [resource type]", | ||
Short: "creates one or more resources", | ||
PersistentPreRunE: createPreRun, | ||
} | ||
|
||
type createCmdConfig struct { | ||
dryRun bool | ||
pathPrefix string | ||
skipConfirm bool | ||
|
||
shared sharedOptions | ||
} | ||
|
||
var createConfig createCmdConfig | ||
|
||
func init() { | ||
createCmd.PersistentFlags().BoolVar( | ||
&createConfig.dryRun, | ||
"dry-run", | ||
false, | ||
"Do a dry-run", | ||
) | ||
createCmd.PersistentFlags().StringVar( | ||
&createConfig.pathPrefix, | ||
"path-prefix", | ||
os.Getenv("TOPICCTL_ACL_PATH_PREFIX"), | ||
"Prefix for ACL config paths", | ||
) | ||
createCmd.PersistentFlags().BoolVar( | ||
&createConfig.skipConfirm, | ||
"skip-confirm", | ||
false, | ||
"Skip confirmation prompts during creation process", | ||
) | ||
|
||
addSharedFlags(createCmd, &createConfig.shared) | ||
createCmd.AddCommand( | ||
createACLsCmd(), | ||
) | ||
RootCmd.AddCommand(createCmd) | ||
} | ||
|
||
func createPreRun(cmd *cobra.Command, args []string) error { | ||
if err := RootCmd.PersistentPreRunE(cmd, args); err != nil { | ||
return err | ||
} | ||
return createConfig.shared.validate() | ||
} | ||
|
||
func createACLsCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "acls [acl configs]", | ||
Short: "creates ACLs from configuration files", | ||
Args: cobra.MinimumNArgs(1), | ||
RunE: createACLRun, | ||
PreRunE: createPreRun, | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
func createACLRun(cmd *cobra.Command, args []string) error { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
|
||
sigChan := make(chan os.Signal, 1) | ||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) | ||
go func() { | ||
<-sigChan | ||
cancel() | ||
}() | ||
|
||
// Keep a cache of the admin clients with the cluster config path as the key | ||
adminClients := map[string]admin.Client{} | ||
|
||
defer func() { | ||
for _, adminClient := range adminClients { | ||
adminClient.Close() | ||
} | ||
}() | ||
|
||
matchCount := 0 | ||
|
||
for _, arg := range args { | ||
if createConfig.pathPrefix != "" && !filepath.IsAbs(arg) { | ||
arg = filepath.Join(createConfig.pathPrefix, arg) | ||
} | ||
|
||
matches, err := filepath.Glob(arg) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, match := range matches { | ||
matchCount++ | ||
if err := createACL(ctx, match, adminClients); err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
|
||
if matchCount == 0 { | ||
return fmt.Errorf("No ACL configs match the provided args (%+v)", args) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func createACL( | ||
ctx context.Context, | ||
aclConfigPath string, | ||
adminClients map[string]admin.Client, | ||
) error { | ||
clusterConfigPath, err := clusterConfigForACLCreate(aclConfigPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
aclConfigs, err := config.LoadACLsFile(aclConfigPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
clusterConfig, err := config.LoadClusterFile(clusterConfigPath, createConfig.shared.expandEnv) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
adminClient, ok := adminClients[clusterConfigPath] | ||
if !ok { | ||
adminClient, err = clusterConfig.NewAdminClient( | ||
ctx, | ||
nil, | ||
createConfig.dryRun, | ||
createConfig.shared.saslUsername, | ||
createConfig.shared.saslPassword, | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
adminClients[clusterConfigPath] = adminClient | ||
} | ||
|
||
cliRunner := cli.NewCLIRunner(adminClient, log.Infof, false) | ||
|
||
for _, aclConfig := range aclConfigs { | ||
aclConfig.SetDefaults() | ||
log.Infof( | ||
"Processing ACL %s in config %s with cluster config %s", | ||
aclConfig.Meta.Name, | ||
aclConfigPath, | ||
clusterConfigPath, | ||
) | ||
|
||
creatorConfig := create.ACLCreatorConfig{ | ||
DryRun: createConfig.dryRun, | ||
SkipConfirm: createConfig.skipConfirm, | ||
ACLConfig: aclConfig, | ||
ClusterConfig: clusterConfig, | ||
} | ||
|
||
if err := cliRunner.CreateACL(ctx, creatorConfig); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func clusterConfigForACLCreate(aclConfigPath string) (string, error) { | ||
if createConfig.shared.clusterConfig != "" { | ||
return createConfig.shared.clusterConfig, nil | ||
} | ||
|
||
return filepath.Abs( | ||
filepath.Join( | ||
filepath.Dir(aclConfigPath), | ||
"..", | ||
"cluster.yaml", | ||
), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
meta: | ||
name: acl-default | ||
cluster: local-cluster-auth | ||
environment: local-env | ||
region: local-region | ||
description: | | ||
This is a default ACL for the local cluster. | ||
It grants read and describe access to the topic `my-topic` and read access to the group `my-group` | ||
to the user `default`. | ||
spec: | ||
acls: | ||
- resource: | ||
type: topic | ||
name: my-topic | ||
patternType: literal | ||
principal: 'User:default' | ||
host: '*' | ||
permission: allow | ||
operations: | ||
- Read | ||
- Describe | ||
- resource: | ||
type: group | ||
name: my-group | ||
patternType: prefixed | ||
principal: 'User:default' | ||
host: '*' | ||
permission: allow | ||
operations: | ||
- Read |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.