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
586eea06
Commit
586eea06
authored
Apr 26, 2016
by
jianhuiz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add get/create/delete for clusters
parent
a6812d18
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
107 additions
and
3 deletions
+107
-3
kubectl
contrib/completions/bash/kubectl
+10
-0
clientcache.go
pkg/kubectl/cmd/util/clientcache.go
+44
-3
factory.go
pkg/kubectl/cmd/util/factory.go
+17
-0
resource_printer.go
pkg/kubectl/resource_printer.go
+36
-0
No files found.
contrib/completions/bash/kubectl
View file @
586eea06
...
@@ -404,6 +404,7 @@ _kubectl_get()
...
@@ -404,6 +404,7 @@ _kubectl_get()
must_have_one_flag=()
must_have_one_flag=()
must_have_one_noun=()
must_have_one_noun=()
must_have_one_noun+=("cluster")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("configmap")
must_have_one_noun+=("configmap")
must_have_one_noun+=("daemonset")
must_have_one_noun+=("daemonset")
...
@@ -431,6 +432,7 @@ _kubectl_get()
...
@@ -431,6 +432,7 @@ _kubectl_get()
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresourcedata")
must_have_one_noun+=("thirdpartyresourcedata")
noun_aliases=()
noun_aliases=()
noun_aliases+=("clusters")
noun_aliases+=("componentstatuses")
noun_aliases+=("componentstatuses")
noun_aliases+=("configmaps")
noun_aliases+=("configmaps")
noun_aliases+=("cs")
noun_aliases+=("cs")
...
@@ -1186,6 +1188,7 @@ _kubectl_patch()
...
@@ -1186,6 +1188,7 @@ _kubectl_patch()
must_have_one_flag+=("--patch=")
must_have_one_flag+=("--patch=")
must_have_one_flag+=("-p")
must_have_one_flag+=("-p")
must_have_one_noun=()
must_have_one_noun=()
must_have_one_noun+=("cluster")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("configmap")
must_have_one_noun+=("configmap")
must_have_one_noun+=("daemonset")
must_have_one_noun+=("daemonset")
...
@@ -1213,6 +1216,7 @@ _kubectl_patch()
...
@@ -1213,6 +1216,7 @@ _kubectl_patch()
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresourcedata")
must_have_one_noun+=("thirdpartyresourcedata")
noun_aliases=()
noun_aliases=()
noun_aliases+=("clusters")
noun_aliases+=("componentstatuses")
noun_aliases+=("componentstatuses")
noun_aliases+=("configmaps")
noun_aliases+=("configmaps")
noun_aliases+=("cs")
noun_aliases+=("cs")
...
@@ -1317,6 +1321,7 @@ _kubectl_delete()
...
@@ -1317,6 +1321,7 @@ _kubectl_delete()
must_have_one_flag=()
must_have_one_flag=()
must_have_one_noun=()
must_have_one_noun=()
must_have_one_noun+=("cluster")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("configmap")
must_have_one_noun+=("configmap")
must_have_one_noun+=("daemonset")
must_have_one_noun+=("daemonset")
...
@@ -1344,6 +1349,7 @@ _kubectl_delete()
...
@@ -1344,6 +1349,7 @@ _kubectl_delete()
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresourcedata")
must_have_one_noun+=("thirdpartyresourcedata")
noun_aliases=()
noun_aliases=()
noun_aliases+=("clusters")
noun_aliases+=("componentstatuses")
noun_aliases+=("componentstatuses")
noun_aliases+=("configmaps")
noun_aliases+=("configmaps")
noun_aliases+=("cs")
noun_aliases+=("cs")
...
@@ -1444,6 +1450,7 @@ _kubectl_edit()
...
@@ -1444,6 +1450,7 @@ _kubectl_edit()
must_have_one_flag=()
must_have_one_flag=()
must_have_one_noun=()
must_have_one_noun=()
must_have_one_noun+=("cluster")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("configmap")
must_have_one_noun+=("configmap")
must_have_one_noun+=("daemonset")
must_have_one_noun+=("daemonset")
...
@@ -1471,6 +1478,7 @@ _kubectl_edit()
...
@@ -1471,6 +1478,7 @@ _kubectl_edit()
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresourcedata")
must_have_one_noun+=("thirdpartyresourcedata")
noun_aliases=()
noun_aliases=()
noun_aliases+=("clusters")
noun_aliases+=("componentstatuses")
noun_aliases+=("componentstatuses")
noun_aliases+=("configmaps")
noun_aliases+=("configmaps")
noun_aliases+=("cs")
noun_aliases+=("cs")
...
@@ -2769,6 +2777,7 @@ _kubectl_label()
...
@@ -2769,6 +2777,7 @@ _kubectl_label()
must_have_one_flag=()
must_have_one_flag=()
must_have_one_noun=()
must_have_one_noun=()
must_have_one_noun+=("cluster")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("configmap")
must_have_one_noun+=("configmap")
must_have_one_noun+=("daemonset")
must_have_one_noun+=("daemonset")
...
@@ -2796,6 +2805,7 @@ _kubectl_label()
...
@@ -2796,6 +2805,7 @@ _kubectl_label()
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresource")
must_have_one_noun+=("thirdpartyresourcedata")
must_have_one_noun+=("thirdpartyresourcedata")
noun_aliases=()
noun_aliases=()
noun_aliases+=("clusters")
noun_aliases+=("componentstatuses")
noun_aliases+=("componentstatuses")
noun_aliases+=("configmaps")
noun_aliases+=("configmaps")
noun_aliases+=("cs")
noun_aliases+=("cs")
...
...
pkg/kubectl/cmd/util/clientcache.go
View file @
586eea06
...
@@ -17,6 +17,7 @@ limitations under the License.
...
@@ -17,6 +17,7 @@ limitations under the License.
package
util
package
util
import
(
import
(
fed_clientset
"k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/restclient"
...
@@ -26,9 +27,10 @@ import (
...
@@ -26,9 +27,10 @@ import (
func
NewClientCache
(
loader
clientcmd
.
ClientConfig
)
*
ClientCache
{
func
NewClientCache
(
loader
clientcmd
.
ClientConfig
)
*
ClientCache
{
return
&
ClientCache
{
return
&
ClientCache
{
clients
:
make
(
map
[
unversioned
.
GroupVersion
]
*
client
.
Client
),
clients
:
make
(
map
[
unversioned
.
GroupVersion
]
*
client
.
Client
),
configs
:
make
(
map
[
unversioned
.
GroupVersion
]
*
restclient
.
Config
),
configs
:
make
(
map
[
unversioned
.
GroupVersion
]
*
restclient
.
Config
),
loader
:
loader
,
fedClientSets
:
make
(
map
[
unversioned
.
GroupVersion
]
fed_clientset
.
Interface
),
loader
:
loader
,
}
}
}
}
...
@@ -37,6 +39,7 @@ func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
...
@@ -37,6 +39,7 @@ func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
type
ClientCache
struct
{
type
ClientCache
struct
{
loader
clientcmd
.
ClientConfig
loader
clientcmd
.
ClientConfig
clients
map
[
unversioned
.
GroupVersion
]
*
client
.
Client
clients
map
[
unversioned
.
GroupVersion
]
*
client
.
Client
fedClientSets
map
[
unversioned
.
GroupVersion
]
fed_clientset
.
Interface
configs
map
[
unversioned
.
GroupVersion
]
*
restclient
.
Config
configs
map
[
unversioned
.
GroupVersion
]
*
restclient
.
Config
defaultConfig
*
restclient
.
Config
defaultConfig
*
restclient
.
Config
defaultClient
*
client
.
Client
defaultClient
*
client
.
Client
...
@@ -125,3 +128,41 @@ func (c *ClientCache) ClientForVersion(version *unversioned.GroupVersion) (*clie
...
@@ -125,3 +128,41 @@ func (c *ClientCache) ClientForVersion(version *unversioned.GroupVersion) (*clie
return
kubeclient
,
nil
return
kubeclient
,
nil
}
}
func
(
c
*
ClientCache
)
FederationClientSetForVersion
(
version
*
unversioned
.
GroupVersion
)
(
fed_clientset
.
Interface
,
error
)
{
if
version
!=
nil
{
if
clientSet
,
found
:=
c
.
fedClientSets
[
*
version
];
found
{
return
clientSet
,
nil
}
}
config
,
err
:=
c
.
ClientConfigForVersion
(
version
)
if
err
!=
nil
{
return
nil
,
err
}
// TODO: support multi versions of client with clientset
clientSet
,
err
:=
fed_clientset
.
NewForConfig
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
c
.
fedClientSets
[
*
config
.
GroupVersion
]
=
clientSet
if
version
!=
nil
{
configCopy
:=
*
config
clientSet
,
err
:=
fed_clientset
.
NewForConfig
(
&
configCopy
)
if
err
!=
nil
{
return
nil
,
err
}
c
.
fedClientSets
[
*
version
]
=
clientSet
}
return
clientSet
,
nil
}
func
(
c
*
ClientCache
)
FederationClientForVersion
(
version
*
unversioned
.
GroupVersion
)
(
*
restclient
.
RESTClient
,
error
)
{
fedClientSet
,
err
:=
c
.
FederationClientSetForVersion
(
version
)
if
err
!=
nil
{
return
nil
,
err
}
return
fedClientSet
.
(
*
fed_clientset
.
Clientset
)
.
FederationClient
.
RESTClient
,
nil
}
pkg/kubectl/cmd/util/factory.go
View file @
586eea06
...
@@ -36,6 +36,7 @@ import (
...
@@ -36,6 +36,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/pflag"
"k8s.io/kubernetes/federation/apis/federation"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
...
@@ -295,11 +296,13 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
...
@@ -295,11 +296,13 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
{
Group
:
api
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Resource
:
meta
.
AnyResource
},
{
Group
:
api
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Resource
:
meta
.
AnyResource
},
{
Group
:
extensions
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Resource
:
meta
.
AnyResource
},
{
Group
:
extensions
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Resource
:
meta
.
AnyResource
},
{
Group
:
metrics
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Resource
:
meta
.
AnyResource
},
{
Group
:
metrics
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Resource
:
meta
.
AnyResource
},
{
Group
:
federation
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Resource
:
meta
.
AnyResource
},
},
},
KindPriority
:
[]
unversioned
.
GroupVersionKind
{
KindPriority
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
api
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Kind
:
meta
.
AnyKind
},
{
Group
:
api
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Kind
:
meta
.
AnyKind
},
{
Group
:
extensions
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Kind
:
meta
.
AnyKind
},
{
Group
:
extensions
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Kind
:
meta
.
AnyKind
},
{
Group
:
metrics
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Kind
:
meta
.
AnyKind
},
{
Group
:
metrics
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Kind
:
meta
.
AnyKind
},
{
Group
:
federation
.
GroupName
,
Version
:
meta
.
AnyVersion
,
Kind
:
meta
.
AnyKind
},
},
},
}
}
return
priorityRESTMapper
,
api
.
Scheme
return
priorityRESTMapper
,
api
.
Scheme
...
@@ -334,6 +337,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
...
@@ -334,6 +337,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
return
c
.
RESTClient
,
nil
return
c
.
RESTClient
,
nil
case
extensions
.
SchemeGroupVersion
.
Group
:
case
extensions
.
SchemeGroupVersion
.
Group
:
return
c
.
ExtensionsClient
.
RESTClient
,
nil
return
c
.
ExtensionsClient
.
RESTClient
,
nil
case
federation
.
GroupName
:
return
clients
.
FederationClientForVersion
(
&
mappingVersion
)
default
:
default
:
if
!
registered
.
IsThirdPartyAPIGroupVersion
(
gvk
.
GroupVersion
())
{
if
!
registered
.
IsThirdPartyAPIGroupVersion
(
gvk
.
GroupVersion
())
{
return
nil
,
fmt
.
Errorf
(
"unknown api group/version: %s"
,
gvk
.
String
())
return
nil
,
fmt
.
Errorf
(
"unknown api group/version: %s"
,
gvk
.
String
())
...
@@ -612,8 +617,13 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
...
@@ -612,8 +617,13 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
}
}
dir
=
path
.
Join
(
cacheDir
,
version
.
String
())
dir
=
path
.
Join
(
cacheDir
,
version
.
String
())
}
}
fedClient
,
err
:=
clients
.
FederationClientForVersion
(
nil
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
clientSwaggerSchema
{
return
&
clientSwaggerSchema
{
c
:
client
,
c
:
client
,
fedc
:
fedClient
,
cacheDir
:
dir
,
cacheDir
:
dir
,
mapper
:
api
.
RESTMapper
,
mapper
:
api
.
RESTMapper
,
},
nil
},
nil
...
@@ -810,6 +820,7 @@ func getServiceProtocols(spec api.ServiceSpec) map[string]string {
...
@@ -810,6 +820,7 @@ func getServiceProtocols(spec api.ServiceSpec) map[string]string {
type
clientSwaggerSchema
struct
{
type
clientSwaggerSchema
struct
{
c
*
client
.
Client
c
*
client
.
Client
fedc
*
restclient
.
RESTClient
cacheDir
string
cacheDir
string
mapper
meta
.
RESTMapper
mapper
meta
.
RESTMapper
}
}
...
@@ -974,6 +985,12 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
...
@@ -974,6 +985,12 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
}
}
return
getSchemaAndValidate
(
c
.
c
.
ExtensionsClient
.
RESTClient
,
data
,
"apis/"
,
gvk
.
GroupVersion
()
.
String
(),
c
.
cacheDir
,
c
)
return
getSchemaAndValidate
(
c
.
c
.
ExtensionsClient
.
RESTClient
,
data
,
"apis/"
,
gvk
.
GroupVersion
()
.
String
(),
c
.
cacheDir
,
c
)
}
}
if
gvk
.
Group
==
federation
.
GroupName
{
if
c
.
fedc
==
nil
{
return
errors
.
New
(
"unable to validate: no federation client"
)
}
return
getSchemaAndValidate
(
c
.
fedc
,
data
,
"apis/"
,
gvk
.
GroupVersion
()
.
String
(),
c
.
cacheDir
,
c
)
}
return
getSchemaAndValidate
(
c
.
c
.
RESTClient
,
data
,
"api"
,
gvk
.
GroupVersion
()
.
String
(),
c
.
cacheDir
,
c
)
return
getSchemaAndValidate
(
c
.
c
.
RESTClient
,
data
,
"api"
,
gvk
.
GroupVersion
()
.
String
(),
c
.
cacheDir
,
c
)
}
}
...
...
pkg/kubectl/resource_printer.go
View file @
586eea06
...
@@ -32,6 +32,7 @@ import (
...
@@ -32,6 +32,7 @@ import (
"github.com/ghodss/yaml"
"github.com/ghodss/yaml"
"github.com/golang/glog"
"github.com/golang/glog"
"k8s.io/kubernetes/federation/apis/federation"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
...
@@ -442,6 +443,7 @@ var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print
...
@@ -442,6 +443,7 @@ var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print
var
deploymentColumns
=
[]
string
{
"NAME"
,
"DESIRED"
,
"CURRENT"
,
"UP-TO-DATE"
,
"AVAILABLE"
,
"AGE"
}
var
deploymentColumns
=
[]
string
{
"NAME"
,
"DESIRED"
,
"CURRENT"
,
"UP-TO-DATE"
,
"AVAILABLE"
,
"AGE"
}
var
configMapColumns
=
[]
string
{
"NAME"
,
"DATA"
,
"AGE"
}
var
configMapColumns
=
[]
string
{
"NAME"
,
"DATA"
,
"AGE"
}
var
podSecurityPolicyColumns
=
[]
string
{
"NAME"
,
"PRIV"
,
"CAPS"
,
"VOLUMEPLUGINS"
,
"SELINUX"
,
"RUNASUSER"
}
var
podSecurityPolicyColumns
=
[]
string
{
"NAME"
,
"PRIV"
,
"CAPS"
,
"VOLUMEPLUGINS"
,
"SELINUX"
,
"RUNASUSER"
}
var
clusterColumns
=
[]
string
{
"NAME"
,
"STATUS"
,
"VERSION"
,
"AGE"
}
// addDefaultHandlers adds print handlers for default Kubernetes types.
// addDefaultHandlers adds print handlers for default Kubernetes types.
func
(
h
*
HumanReadablePrinter
)
addDefaultHandlers
()
{
func
(
h
*
HumanReadablePrinter
)
addDefaultHandlers
()
{
...
@@ -497,6 +499,8 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
...
@@ -497,6 +499,8 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
h
.
Handler
(
podSecurityPolicyColumns
,
printPodSecurityPolicyList
)
h
.
Handler
(
podSecurityPolicyColumns
,
printPodSecurityPolicyList
)
h
.
Handler
(
thirdPartyResourceDataColumns
,
printThirdPartyResourceData
)
h
.
Handler
(
thirdPartyResourceDataColumns
,
printThirdPartyResourceData
)
h
.
Handler
(
thirdPartyResourceDataColumns
,
printThirdPartyResourceDataList
)
h
.
Handler
(
thirdPartyResourceDataColumns
,
printThirdPartyResourceDataList
)
h
.
Handler
(
clusterColumns
,
printCluster
)
h
.
Handler
(
clusterColumns
,
printClusterList
)
}
}
func
(
h
*
HumanReadablePrinter
)
unknown
(
data
[]
byte
,
w
io
.
Writer
)
error
{
func
(
h
*
HumanReadablePrinter
)
unknown
(
data
[]
byte
,
w
io
.
Writer
)
error
{
...
@@ -802,6 +806,38 @@ func printReplicaSetList(list *extensions.ReplicaSetList, w io.Writer, options P
...
@@ -802,6 +806,38 @@ func printReplicaSetList(list *extensions.ReplicaSetList, w io.Writer, options P
return
nil
return
nil
}
}
func
printCluster
(
c
*
federation
.
Cluster
,
w
io
.
Writer
,
options
PrintOptions
)
error
{
var
statuses
[]
string
for
_
,
condition
:=
range
c
.
Status
.
Conditions
{
if
condition
.
Status
==
api
.
ConditionTrue
{
statuses
=
append
(
statuses
,
string
(
condition
.
Type
))
}
else
{
statuses
=
append
(
statuses
,
"Not"
+
string
(
condition
.
Type
))
}
}
if
len
(
statuses
)
==
0
{
statuses
=
append
(
statuses
,
"Unknown"
)
}
if
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%s
\t
%s
\t
%s
\n
"
,
c
.
Name
,
strings
.
Join
(
statuses
,
","
),
c
.
Status
.
Version
,
translateTimestamp
(
c
.
CreationTimestamp
),
);
err
!=
nil
{
return
err
}
return
nil
}
func
printClusterList
(
list
*
federation
.
ClusterList
,
w
io
.
Writer
,
options
PrintOptions
)
error
{
for
_
,
rs
:=
range
list
.
Items
{
if
err
:=
printCluster
(
&
rs
,
w
,
options
);
err
!=
nil
{
return
err
}
}
return
nil
}
func
printJob
(
job
*
batch
.
Job
,
w
io
.
Writer
,
options
PrintOptions
)
error
{
func
printJob
(
job
*
batch
.
Job
,
w
io
.
Writer
,
options
PrintOptions
)
error
{
name
:=
job
.
Name
name
:=
job
.
Name
namespace
:=
job
.
Namespace
namespace
:=
job
.
Namespace
...
...
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