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
93dc839b
Commit
93dc839b
authored
May 07, 2015
by
kargakis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Load input object for increased safety
parent
ca0f678b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
219 additions
and
64 deletions
+219
-64
cmd_test.go
pkg/kubectl/cmd/cmd_test.go
+8
-0
expose.go
pkg/kubectl/cmd/expose.go
+24
-15
expose_test.go
pkg/kubectl/cmd/expose_test.go
+98
-0
factory.go
pkg/kubectl/cmd/util/factory.go
+28
-49
factory_test.go
pkg/kubectl/cmd/util/factory_test.go
+61
-0
No files found.
pkg/kubectl/cmd/cmd_test.go
View file @
93dc839b
...
@@ -171,6 +171,10 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
...
@@ -171,6 +171,10 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
t
:=
&
testFactory
{
t
:=
&
testFactory
{
Validator
:
validation
.
NullSchema
{},
Validator
:
validation
.
NullSchema
{},
}
}
generators
:=
map
[
string
]
kubectl
.
Generator
{
"run-container/v1"
:
kubectl
.
BasicReplicationController
{},
"service/v1"
:
kubectl
.
ServiceGenerator
{},
}
return
&
cmdutil
.
Factory
{
return
&
cmdutil
.
Factory
{
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
return
latest
.
RESTMapper
,
api
.
Scheme
return
latest
.
RESTMapper
,
api
.
Scheme
...
@@ -200,6 +204,10 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
...
@@ -200,6 +204,10 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
ClientConfig
:
func
()
(
*
client
.
Config
,
error
)
{
ClientConfig
:
func
()
(
*
client
.
Config
,
error
)
{
return
t
.
ClientConfig
,
t
.
Err
return
t
.
ClientConfig
,
t
.
Err
},
},
Generator
:
func
(
name
string
)
(
kubectl
.
Generator
,
bool
)
{
generator
,
ok
:=
generators
[
name
]
return
generator
,
ok
},
},
t
,
testapi
.
Codec
()
},
t
,
testapi
.
Codec
()
}
}
...
...
pkg/kubectl/cmd/expose.go
View file @
93dc839b
...
@@ -86,8 +86,28 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
...
@@ -86,8 +86,28 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
return
err
return
err
}
}
generatorName
:=
cmdutil
.
GetFlagString
(
cmd
,
"generator"
)
// Get the input object
var
mapping
*
meta
.
RESTMapping
mapper
,
typer
:=
f
.
Object
()
v
,
k
,
err
:=
mapper
.
VersionAndKindForResource
(
res
)
if
err
!=
nil
{
return
err
}
mapping
,
err
=
mapper
.
RESTMapping
(
k
,
v
)
if
err
!=
nil
{
return
err
}
client
,
err
:=
f
.
RESTClient
(
mapping
)
if
err
!=
nil
{
return
err
}
inputObject
,
err
:=
resource
.
NewHelper
(
client
,
mapping
)
.
Get
(
namespace
,
name
)
if
err
!=
nil
{
return
err
}
// Get the generator, setup and validate all required parameters
generatorName
:=
cmdutil
.
GetFlagString
(
cmd
,
"generator"
)
generator
,
found
:=
f
.
Generator
(
generatorName
)
generator
,
found
:=
f
.
Generator
(
generatorName
)
if
!
found
{
if
!
found
{
return
cmdutil
.
UsageError
(
cmd
,
fmt
.
Sprintf
(
"generator %q not found."
,
generator
))
return
cmdutil
.
UsageError
(
cmd
,
fmt
.
Sprintf
(
"generator %q not found."
,
generator
))
...
@@ -99,19 +119,9 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
...
@@ -99,19 +119,9 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
}
else
{
}
else
{
params
[
"name"
]
=
cmdutil
.
GetFlagString
(
cmd
,
"service-name"
)
params
[
"name"
]
=
cmdutil
.
GetFlagString
(
cmd
,
"service-name"
)
}
}
var
mapping
*
meta
.
RESTMapping
if
s
,
found
:=
params
[
"selector"
];
!
found
||
len
(
s
)
==
0
||
cmdutil
.
GetFlagInt
(
cmd
,
"port"
)
<
1
{
if
s
,
found
:=
params
[
"selector"
];
!
found
||
len
(
s
)
==
0
||
cmdutil
.
GetFlagInt
(
cmd
,
"port"
)
<
1
{
mapper
,
_
:=
f
.
Object
()
v
,
k
,
err
:=
mapper
.
VersionAndKindForResource
(
res
)
if
err
!=
nil
{
return
err
}
mapping
,
err
=
mapper
.
RESTMapping
(
k
,
v
)
if
err
!=
nil
{
return
err
}
if
len
(
s
)
==
0
{
if
len
(
s
)
==
0
{
s
,
err
:=
f
.
PodSelectorFor
Resource
(
mapping
,
namespace
,
name
)
s
,
err
:=
f
.
PodSelectorFor
Object
(
inputObject
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -125,7 +135,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
...
@@ -125,7 +135,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
}
}
}
}
if
cmdutil
.
GetFlagInt
(
cmd
,
"port"
)
<
0
&&
!
noPorts
{
if
cmdutil
.
GetFlagInt
(
cmd
,
"port"
)
<
0
&&
!
noPorts
{
ports
,
err
:=
f
.
PortsFor
Resource
(
mapping
,
namespace
,
name
)
ports
,
err
:=
f
.
PortsFor
Object
(
inputObject
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -141,12 +151,12 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
...
@@ -141,12 +151,12 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
if
cmdutil
.
GetFlagBool
(
cmd
,
"create-external-load-balancer"
)
{
if
cmdutil
.
GetFlagBool
(
cmd
,
"create-external-load-balancer"
)
{
params
[
"create-external-load-balancer"
]
=
"true"
params
[
"create-external-load-balancer"
]
=
"true"
}
}
err
=
kubectl
.
ValidateParams
(
names
,
params
)
err
=
kubectl
.
ValidateParams
(
names
,
params
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
// Expose new object
object
,
err
:=
generator
.
Generate
(
params
)
object
,
err
:=
generator
.
Generate
(
params
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -162,7 +172,6 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
...
@@ -162,7 +172,6 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
// TODO: extract this flag to a central location, when such a location exists.
// TODO: extract this flag to a central location, when such a location exists.
if
!
cmdutil
.
GetFlagBool
(
cmd
,
"dry-run"
)
{
if
!
cmdutil
.
GetFlagBool
(
cmd
,
"dry-run"
)
{
mapper
,
typer
:=
f
.
Object
()
resourceMapper
:=
&
resource
.
Mapper
{
typer
,
mapper
,
f
.
ClientMapperForCommand
()}
resourceMapper
:=
&
resource
.
Mapper
{
typer
,
mapper
,
f
.
ClientMapperForCommand
()}
info
,
err
:=
resourceMapper
.
InfoForObject
(
object
)
info
,
err
:=
resourceMapper
.
InfoForObject
(
object
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
pkg/kubectl/cmd/expose_test.go
0 → 100644
View file @
93dc839b
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
cmd
import
(
"bytes"
"net/http"
"strings"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
func
TestRunExposeService
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
args
[]
string
input
runtime
.
Object
flags
map
[
string
]
string
output
runtime
.
Object
status
int
}{
{
name
:
"expose-service-from-service"
,
args
:
[]
string
{
"service"
,
"baz"
},
input
:
&
api
.
Service
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"baz"
,
Namespace
:
"test"
,
ResourceVersion
:
"12"
},
Spec
:
api
.
ServiceSpec
{
Selector
:
map
[
string
]
string
{
"app"
:
"go"
},
},
},
flags
:
map
[
string
]
string
{
"selector"
:
"func=stream"
,
"protocol"
:
"UDP"
,
"port"
:
"14"
,
"service-name"
:
"foo"
},
output
:
&
api
.
Service
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"foo"
,
Namespace
:
"test"
,
ResourceVersion
:
"12"
},
Spec
:
api
.
ServiceSpec
{
Ports
:
[]
api
.
ServicePort
{
{
Name
:
"default"
,
Protocol
:
api
.
Protocol
(
"UDP"
),
Port
:
14
,
},
},
Selector
:
map
[
string
]
string
{
"func"
:
"stream"
},
},
},
status
:
200
,
},
}
for
_
,
test
:=
range
tests
{
f
,
tf
,
codec
:=
NewAPIFactory
()
tf
.
Printer
=
&
testPrinter
{}
tf
.
Client
=
&
client
.
FakeRESTClient
{
Codec
:
codec
,
Client
:
client
.
HTTPClientFunc
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
switch
p
,
m
:=
req
.
URL
.
Path
,
req
.
Method
;
{
case
p
==
"/namespaces/test/services/baz"
&&
m
==
"GET"
:
return
&
http
.
Response
{
StatusCode
:
test
.
status
,
Body
:
objBody
(
codec
,
test
.
input
)},
nil
case
p
==
"/namespaces/test/services"
&&
m
==
"POST"
:
return
&
http
.
Response
{
StatusCode
:
test
.
status
,
Body
:
objBody
(
codec
,
test
.
output
)},
nil
default
:
t
.
Fatalf
(
"unexpected request: %#v
\n
%#v"
,
req
.
URL
,
req
)
return
nil
,
nil
}
}),
}
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
NewCmdExposeService
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
for
flag
,
value
:=
range
test
.
flags
{
cmd
.
Flags
()
.
Set
(
flag
,
value
)
}
cmd
.
Run
(
cmd
,
test
.
args
)
out
:=
buf
.
String
()
if
strings
.
Contains
(
out
,
"services/foo"
)
{
t
.
Errorf
(
"%s: unexpected output: %s"
,
test
.
name
,
out
)
}
}
}
pkg/kubectl/cmd/util/factory.go
View file @
93dc839b
...
@@ -69,11 +69,10 @@ type Factory struct {
...
@@ -69,11 +69,10 @@ type Factory struct {
Resizer
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
Resizer
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
// Returns a Reaper for gracefully shutting down resources.
// Returns a Reaper for gracefully shutting down resources.
Reaper
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Reaper
,
error
)
Reaper
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Reaper
,
error
)
// PodSelectorForResource returns the pod selector associated with the provided resource name
// PodSelectorForObject returns the pod selector associated with the provided object
// or an error.
PodSelectorForObject
func
(
object
runtime
.
Object
)
(
string
,
error
)
PodSelectorForResource
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
(
string
,
error
)
// PortsForObject returns the ports associated with the provided object
// PortForResource returns the ports associated with the provided resource name or an error
PortsForObject
func
(
object
runtime
.
Object
)
([]
string
,
error
)
PortsForResource
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
([]
string
,
error
)
// Returns a schema that can validate objects stored on disk.
// Returns a schema that can validate objects stored on disk.
Validator
func
()
(
validation
.
Schema
,
error
)
Validator
func
()
(
validation
.
Schema
,
error
)
// Returns the default namespace to use in cases where no other namespace is specified
// Returns the default namespace to use in cases where no other namespace is specified
...
@@ -145,62 +144,42 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
...
@@ -145,62 +144,42 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
Printer
:
func
(
mapping
*
meta
.
RESTMapping
,
noHeaders
bool
)
(
kubectl
.
ResourcePrinter
,
error
)
{
Printer
:
func
(
mapping
*
meta
.
RESTMapping
,
noHeaders
bool
)
(
kubectl
.
ResourcePrinter
,
error
)
{
return
kubectl
.
NewHumanReadablePrinter
(
noHeaders
),
nil
return
kubectl
.
NewHumanReadablePrinter
(
noHeaders
),
nil
},
},
PodSelectorFor
Resource
:
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
(
string
,
error
)
{
PodSelectorFor
Object
:
func
(
object
runtime
.
Object
)
(
string
,
error
)
{
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
client
,
err
:=
clients
.
ClientForVersion
(
""
)
switch
t
:=
object
.
(
type
)
{
if
err
!=
nil
{
case
*
api
.
ReplicationController
:
return
""
,
err
return
kubectl
.
MakeLabels
(
t
.
Spec
.
Selector
),
nil
}
case
*
api
.
Pod
:
switch
mapping
.
Kind
{
if
len
(
t
.
Labels
)
==
0
{
case
"ReplicationController"
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
return
kubectl
.
MakeLabels
(
rc
.
Spec
.
Selector
),
nil
case
"Pod"
:
pod
,
err
:=
client
.
Pods
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
if
len
(
pod
.
Labels
)
==
0
{
return
""
,
fmt
.
Errorf
(
"the pod has no labels and cannot be exposed"
)
return
""
,
fmt
.
Errorf
(
"the pod has no labels and cannot be exposed"
)
}
}
return
kubectl
.
MakeLabels
(
pod
.
Labels
),
nil
return
kubectl
.
MakeLabels
(
t
.
Labels
),
nil
case
"Service"
:
case
*
api
.
Service
:
svc
,
err
:=
client
.
Services
(
namespace
)
.
Get
(
name
)
if
t
.
Spec
.
Selector
==
nil
{
if
err
!=
nil
{
return
""
,
err
}
if
svc
.
Spec
.
Selector
==
nil
{
return
""
,
fmt
.
Errorf
(
"the service has no pod selector set"
)
return
""
,
fmt
.
Errorf
(
"the service has no pod selector set"
)
}
}
return
kubectl
.
MakeLabels
(
svc
.
Spec
.
Selector
),
nil
return
kubectl
.
MakeLabels
(
t
.
Spec
.
Selector
),
nil
default
:
default
:
return
""
,
fmt
.
Errorf
(
"it is not possible to get a pod selector from %s"
,
mapping
.
Kind
)
kind
,
err
:=
meta
.
NewAccessor
()
.
Kind
(
object
)
if
err
!=
nil
{
return
""
,
err
}
return
""
,
fmt
.
Errorf
(
"it is not possible to get a pod selector from %s"
,
kind
)
}
}
},
},
PortsFor
Resource
:
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
([]
string
,
error
)
{
PortsFor
Object
:
func
(
object
runtime
.
Object
)
([]
string
,
error
)
{
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
client
,
err
:=
clients
.
ClientForVersion
(
""
)
switch
t
:=
object
.
(
type
)
{
if
err
!=
nil
{
case
*
api
.
ReplicationController
:
return
nil
,
err
return
getPorts
(
t
.
Spec
.
Template
.
Spec
),
nil
}
case
*
api
.
Pod
:
switch
mapping
.
Kind
{
return
getPorts
(
t
.
Spec
),
nil
case
"ReplicationController"
:
default
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
kind
,
err
:=
meta
.
NewAccessor
()
.
Kind
(
object
)
if
err
!=
nil
{
return
nil
,
err
}
return
getPorts
(
rc
.
Spec
.
Template
.
Spec
),
nil
case
"Pod"
:
pod
,
err
:=
client
.
Pods
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
getPorts
(
pod
.
Spec
),
nil
return
nil
,
fmt
.
Errorf
(
"it is not possible to get ports from %s"
,
kind
)
default
:
return
nil
,
fmt
.
Errorf
(
"it is not possible to get ports from %s"
,
mapping
.
Kind
)
}
}
},
},
Resizer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
{
Resizer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
{
...
...
pkg/kubectl/cmd/util/factory_test.go
View file @
93dc839b
...
@@ -17,8 +17,10 @@ limitations under the License.
...
@@ -17,8 +17,10 @@ limitations under the License.
package
util
package
util
import
(
import
(
"sort"
"testing"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
clientcmdapi
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
clientcmdapi
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
)
)
...
@@ -39,3 +41,62 @@ func TestNewFactoryNoFlagBindings(t *testing.T) {
...
@@ -39,3 +41,62 @@ func TestNewFactoryNoFlagBindings(t *testing.T) {
t
.
Errorf
(
"Expected zero flags, but got %v"
,
factory
.
flags
)
t
.
Errorf
(
"Expected zero flags, but got %v"
,
factory
.
flags
)
}
}
}
}
func
TestPodSelectorForObject
(
t
*
testing
.
T
)
{
f
:=
NewFactory
(
nil
)
svc
:=
&
api
.
Service
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"baz"
,
Namespace
:
"test"
},
Spec
:
api
.
ServiceSpec
{
Selector
:
map
[
string
]
string
{
"foo"
:
"bar"
,
},
},
}
expected
:=
"foo=bar"
got
,
err
:=
f
.
PodSelectorForObject
(
svc
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
if
expected
!=
got
{
t
.
Fatalf
(
"Selector mismatch! Expected %s, got %s"
,
expected
,
got
)
}
}
func
TestPortsForObject
(
t
*
testing
.
T
)
{
f
:=
NewFactory
(
nil
)
pod
:=
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"baz"
,
Namespace
:
"test"
,
ResourceVersion
:
"12"
},
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{
{
Ports
:
[]
api
.
ContainerPort
{
{
ContainerPort
:
101
,
},
},
},
},
},
}
expected
:=
[]
string
{
"101"
}
got
,
err
:=
f
.
PortsForObject
(
pod
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
if
len
(
expected
)
!=
len
(
got
)
{
t
.
Fatalf
(
"Ports size mismatch! Expected %d, got %d"
,
len
(
expected
),
len
(
got
))
}
sort
.
Strings
(
expected
)
sort
.
Strings
(
got
)
for
i
,
port
:=
range
got
{
if
port
!=
expected
[
i
]
{
t
.
Fatalf
(
"Port mismatch! Expected %s, got %s"
,
expected
[
i
],
port
)
}
}
}
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