Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
0257a2bc
Unverified
Commit
0257a2bc
authored
Feb 01, 2019
by
juanvallejo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
allow re-usability of plugin handler, allow support for multiple valid plugin filename prefixes
parent
556c0b85
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
58 additions
and
21 deletions
+58
-21
cmd.go
pkg/kubectl/cmd/cmd.go
+35
-13
cmd_test.go
pkg/kubectl/cmd/cmd_test.go
+9
-6
plugin.go
pkg/kubectl/cmd/plugin/plugin.go
+14
-2
No files found.
pkg/kubectl/cmd/cmd.go
View file @
0257a2bc
...
@@ -293,7 +293,7 @@ var (
...
@@ -293,7 +293,7 @@ var (
// NewDefaultKubectlCommand creates the `kubectl` command with default arguments
// NewDefaultKubectlCommand creates the `kubectl` command with default arguments
func
NewDefaultKubectlCommand
()
*
cobra
.
Command
{
func
NewDefaultKubectlCommand
()
*
cobra
.
Command
{
return
NewDefaultKubectlCommandWithArgs
(
&
defaultPluginHandler
{}
,
os
.
Args
,
os
.
Stdin
,
os
.
Stdout
,
os
.
Stderr
)
return
NewDefaultKubectlCommandWithArgs
(
NewDefaultPluginHandler
(
plugin
.
ValidPluginFilenamePrefixes
)
,
os
.
Args
,
os
.
Stdin
,
os
.
Stdout
,
os
.
Stderr
)
}
}
// NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments
// NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments
...
@@ -310,7 +310,7 @@ func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string
...
@@ -310,7 +310,7 @@ func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string
// only look for suitable extension executables if
// only look for suitable extension executables if
// the specified command does not already exist
// the specified command does not already exist
if
_
,
_
,
err
:=
cmd
.
Find
(
cmdPathPieces
);
err
!=
nil
{
if
_
,
_
,
err
:=
cmd
.
Find
(
cmdPathPieces
);
err
!=
nil
{
if
err
:=
handleEndpointExtensions
(
pluginHandler
,
cmdPathPieces
);
err
!=
nil
{
if
err
:=
HandlePluginCommand
(
pluginHandler
,
cmdPathPieces
);
err
!=
nil
{
fmt
.
Fprintf
(
errout
,
"%v
\n
"
,
err
)
fmt
.
Fprintf
(
errout
,
"%v
\n
"
,
err
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
...
@@ -324,29 +324,51 @@ func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string
...
@@ -324,29 +324,51 @@ func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string
// and performing executable filename lookups to search
// and performing executable filename lookups to search
// for valid plugin files, and execute found plugins.
// for valid plugin files, and execute found plugins.
type
PluginHandler
interface
{
type
PluginHandler
interface
{
// Lookup receives a potential filename and returns
// exists at the given filename, or a boolean false.
// a full or relative path to an executable, if one
// Lookup will iterate over a list of given prefixes
// exists at the given filename, or an error.
// in order to recognize valid plugin filenames.
Lookup
(
filename
string
)
(
string
,
error
)
// The first filepath to match a prefix is returned.
Lookup
(
filename
string
)
(
string
,
bool
)
// Execute receives an executable's filepath, a slice
// Execute receives an executable's filepath, a slice
// of arguments, and a slice of environment variables
// of arguments, and a slice of environment variables
// to relay to the executable.
// to relay to the executable.
Execute
(
executablePath
string
,
cmdArgs
,
environment
[]
string
)
error
Execute
(
executablePath
string
,
cmdArgs
,
environment
[]
string
)
error
}
}
type
defaultPluginHandler
struct
{}
// DefaultPluginHandler implements PluginHandler
type
DefaultPluginHandler
struct
{
ValidPrefixes
[]
string
}
// NewDefaultPluginHandler instantiates the DefaultPluginHandler with a list of
// given filename prefixes used to identify valid plugin filenames.
func
NewDefaultPluginHandler
(
validPrefixes
[]
string
)
*
DefaultPluginHandler
{
return
&
DefaultPluginHandler
{
ValidPrefixes
:
validPrefixes
,
}
}
// Lookup implements PluginHandler
// Lookup implements PluginHandler
func
(
h
*
defaultPluginHandler
)
Lookup
(
filename
string
)
(
string
,
error
)
{
func
(
h
*
DefaultPluginHandler
)
Lookup
(
filename
string
)
(
string
,
bool
)
{
return
exec
.
LookPath
(
filename
)
for
_
,
prefix
:=
range
h
.
ValidPrefixes
{
path
,
err
:=
exec
.
LookPath
(
fmt
.
Sprintf
(
"%s-%s"
,
prefix
,
filename
))
if
err
!=
nil
||
len
(
path
)
==
0
{
continue
}
return
path
,
true
}
return
""
,
false
}
}
// Execute implements PluginHandler
// Execute implements PluginHandler
func
(
h
*
d
efaultPluginHandler
)
Execute
(
executablePath
string
,
cmdArgs
,
environment
[]
string
)
error
{
func
(
h
*
D
efaultPluginHandler
)
Execute
(
executablePath
string
,
cmdArgs
,
environment
[]
string
)
error
{
return
syscall
.
Exec
(
executablePath
,
cmdArgs
,
environment
)
return
syscall
.
Exec
(
executablePath
,
cmdArgs
,
environment
)
}
}
func
handleEndpointExtensions
(
pluginHandler
PluginHandler
,
cmdArgs
[]
string
)
error
{
// HandlePluginCommand receives a pluginHandler and command-line arguments and attempts to find
// a plugin executable on the PATH that satisfies the given arguments.
func
HandlePluginCommand
(
pluginHandler
PluginHandler
,
cmdArgs
[]
string
)
error
{
remainingArgs
:=
[]
string
{}
// all "non-flag" arguments
remainingArgs
:=
[]
string
{}
// all "non-flag" arguments
for
idx
:=
range
cmdArgs
{
for
idx
:=
range
cmdArgs
{
...
@@ -360,8 +382,8 @@ func handleEndpointExtensions(pluginHandler PluginHandler, cmdArgs []string) err
...
@@ -360,8 +382,8 @@ func handleEndpointExtensions(pluginHandler PluginHandler, cmdArgs []string) err
// attempt to find binary, starting at longest possible name with given cmdArgs
// attempt to find binary, starting at longest possible name with given cmdArgs
for
len
(
remainingArgs
)
>
0
{
for
len
(
remainingArgs
)
>
0
{
path
,
err
:=
pluginHandler
.
Lookup
(
fmt
.
Sprintf
(
"kubectl-%s"
,
strings
.
Join
(
remainingArgs
,
"-"
)
))
path
,
found
:=
pluginHandler
.
Lookup
(
strings
.
Join
(
remainingArgs
,
"-"
))
if
err
!=
nil
||
len
(
path
)
==
0
{
if
!
found
{
remainingArgs
=
remainingArgs
[
:
len
(
remainingArgs
)
-
1
]
remainingArgs
=
remainingArgs
[
:
len
(
remainingArgs
)
-
1
]
continue
continue
}
}
...
...
pkg/kubectl/cmd/cmd_test.go
View file @
0257a2bc
...
@@ -175,32 +175,35 @@ type testPluginHandler struct {
...
@@ -175,32 +175,35 @@ type testPluginHandler struct {
err
error
err
error
}
}
func
(
h
*
testPluginHandler
)
Lookup
(
filename
string
)
(
string
,
error
)
{
func
(
h
*
testPluginHandler
)
Lookup
(
filename
string
)
(
string
,
bool
)
{
// append supported plugin prefix to the filename
filename
=
fmt
.
Sprintf
(
"%s-%s"
,
"kubectl"
,
filename
)
dir
,
err
:=
os
.
Stat
(
h
.
pluginsDirectory
)
dir
,
err
:=
os
.
Stat
(
h
.
pluginsDirectory
)
if
err
!=
nil
{
if
err
!=
nil
{
h
.
err
=
err
h
.
err
=
err
return
""
,
err
return
""
,
false
}
}
if
!
dir
.
IsDir
()
{
if
!
dir
.
IsDir
()
{
h
.
err
=
fmt
.
Errorf
(
"expected %q to be a directory"
,
h
.
pluginsDirectory
)
h
.
err
=
fmt
.
Errorf
(
"expected %q to be a directory"
,
h
.
pluginsDirectory
)
return
""
,
h
.
err
return
""
,
false
}
}
plugins
,
err
:=
ioutil
.
ReadDir
(
h
.
pluginsDirectory
)
plugins
,
err
:=
ioutil
.
ReadDir
(
h
.
pluginsDirectory
)
if
err
!=
nil
{
if
err
!=
nil
{
h
.
err
=
err
h
.
err
=
err
return
""
,
err
return
""
,
false
}
}
for
_
,
p
:=
range
plugins
{
for
_
,
p
:=
range
plugins
{
if
p
.
Name
()
==
filename
{
if
p
.
Name
()
==
filename
{
return
fmt
.
Sprintf
(
"%s/%s"
,
h
.
pluginsDirectory
,
p
.
Name
()),
nil
return
fmt
.
Sprintf
(
"%s/%s"
,
h
.
pluginsDirectory
,
p
.
Name
()),
true
}
}
}
}
h
.
err
=
fmt
.
Errorf
(
"unable to find a plugin executable %q"
,
filename
)
h
.
err
=
fmt
.
Errorf
(
"unable to find a plugin executable %q"
,
filename
)
return
""
,
h
.
err
return
""
,
false
}
}
func
(
h
*
testPluginHandler
)
Execute
(
executablePath
string
,
cmdArgs
,
env
[]
string
)
error
{
func
(
h
*
testPluginHandler
)
Execute
(
executablePath
string
,
cmdArgs
,
env
[]
string
)
error
{
...
...
pkg/kubectl/cmd/plugin/plugin.go
View file @
0257a2bc
...
@@ -49,6 +49,8 @@ var (
...
@@ -49,6 +49,8 @@ var (
- anywhere on the user's PATH
- anywhere on the user's PATH
- begin with "kubectl-"
- begin with "kubectl-"
`
)
`
)
ValidPluginFilenamePrefixes
=
[]
string
{
"kubectl"
}
)
)
func
NewCmdPlugin
(
f
cmdutil
.
Factory
,
streams
genericclioptions
.
IOStreams
)
*
cobra
.
Command
{
func
NewCmdPlugin
(
f
cmdutil
.
Factory
,
streams
genericclioptions
.
IOStreams
)
*
cobra
.
Command
{
...
@@ -127,12 +129,12 @@ func (o *PluginListOptions) Run() error {
...
@@ -127,12 +129,12 @@ func (o *PluginListOptions) Run() error {
if
f
.
IsDir
()
{
if
f
.
IsDir
()
{
continue
continue
}
}
if
!
strings
.
HasPrefix
(
f
.
Name
(),
"kubectl-"
)
{
if
!
hasValidPrefix
(
f
.
Name
(),
ValidPluginFilenamePrefixes
)
{
continue
continue
}
}
if
isFirstFile
{
if
isFirstFile
{
fmt
.
Fprintf
(
o
.
ErrOut
,
"The following
kubectl-
compatible plugins are available:
\n\n
"
)
fmt
.
Fprintf
(
o
.
ErrOut
,
"The following compatible plugins are available:
\n\n
"
)
pluginsFound
=
true
pluginsFound
=
true
isFirstFile
=
false
isFirstFile
=
false
}
}
...
@@ -262,3 +264,13 @@ func uniquePathsList(paths []string) []string {
...
@@ -262,3 +264,13 @@ func uniquePathsList(paths []string) []string {
}
}
return
newPaths
return
newPaths
}
}
func
hasValidPrefix
(
filepath
string
,
validPrefixes
[]
string
)
bool
{
for
_
,
prefix
:=
range
validPrefixes
{
if
!
strings
.
HasPrefix
(
filepath
,
prefix
+
"-"
)
{
continue
}
return
true
}
return
false
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment