Merge pull request #168 in YUNIONIO/onecloud from ~LIZEXI/onecloud:feature/lzx-add-k8s-cli-v3 to release/2.1.0

* commit 'd36f20d5c923b201ca7511ae015df73eadf84f33':
  climc: k8s resource client api for nodes, namespace, statefulset, ingress
This commit is contained in:
李泽玺
2018-09-07 11:59:32 +08:00
21 changed files with 413 additions and 82 deletions
+19
View File
@@ -45,4 +45,23 @@ func initChart() {
PrintListResultTable(charts, k8s.Charts, s)
return nil
})
type getOpt struct {
REPO string `help:"Repo of the chart"`
NAME string `help:"Chart name"`
Version string `help:"Chart version"`
}
R(&getOpt{}, cmdN("show"), "Show details of a chart", func(s *mcclient.ClientSession, args *getOpt) error {
params := json.NewDict()
params.Add(json.NewString(args.REPO), "repo")
if args.Version != "" {
params.Add(json.NewString(args.Version), "version")
}
chart, err := k8s.Charts.Get(s, args.NAME, params)
if err != nil {
return err
}
printObjectYAML(chart)
return nil
})
}
+2 -2
View File
@@ -14,12 +14,12 @@ import (
func initCluster() {
cmdN := func(suffix string) string {
return resourceCmdN("cluster", suffix)
return kubeResourceCmdN("cluster", suffix)
}
type listOpt struct {
options.BaseListOptions
}
R(&listOpt{}, cmdN("list"), "List k8s clusters", func(s *mcclient.ClientSession, args *listOpt) error {
R(&listOpt{}, cmdN("list"), "List k8s infra clusters", func(s *mcclient.ClientSession, args *listOpt) error {
args.Details = options.Bool(true)
var params *jsonutils.JSONDict
{
+16 -10
View File
@@ -18,19 +18,12 @@ func initDeployment() {
return resourceCmdN("deployment", suffix)
}
type listOpt struct {
namespaceListOptions
baseListOptions
}
R(&listOpt{}, cmdN("list"), "List k8s deployment", func(s *mcclient.ClientSession, args *listOpt) error {
params := fetchNamespaceParams(args.namespaceListOptions)
params.Update(fetchPagingParams(args.baseListOptions))
params.Update(args.ClusterParams())
ret, err := k8s.Deployments.List(s, params)
R(&NamespaceResourceListOptions{}, cmdN("list"), "List k8s deployment", func(s *mcclient.ClientSession, args *NamespaceResourceListOptions) error {
ret, err := k8s.Deployments.List(s, args.Params())
if err != nil {
return err
}
printList(ret, k8s.Deployments.GetColumns(s))
PrintListResultTable(ret, k8s.Deployments, s)
return nil
})
@@ -68,6 +61,19 @@ func initDeployment() {
}
params.Add(portMappings, "portMappings")
}
envList := jsonutils.NewArray()
for _, env := range args.Env {
parts := strings.Split(env, "=")
if len(parts) != 2 {
return fmt.Errorf("Bad env value: %v", env)
}
envObj := jsonutils.NewDict()
envObj.Add(jsonutils.NewString(parts[0]), "name")
envObj.Add(jsonutils.NewString(parts[1]), "value")
envList.Add(envObj)
}
params.Add(envList, "variables")
if args.Net != "" {
net, err := parseNetConfig(args.Net)
if err != nil {
+40
View File
@@ -0,0 +1,40 @@
package k8s
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
)
func initIngress() {
cmdN := func(suffix string) string {
return resourceCmdN("statefulset", suffix)
}
R(&NamespaceResourceListOptions{}, cmdN("list"), "List k8s ingress", func(s *mcclient.ClientSession, args *NamespaceResourceListOptions) error {
ret, err := k8s.Ingresses.List(s, args.Params())
if err != nil {
return err
}
PrintListResultTable(ret, k8s.Ingresses, s)
return nil
})
type getOpt struct {
resourceGetOptions
}
R(&getOpt{}, cmdN("show"), "Get ingress details", func(s *mcclient.ClientSession, args *getOpt) error {
id := args.NAME
params := args.ClusterParams()
if args.Namespace != "" {
params.Add(jsonutils.NewString(args.Namespace), "namespace")
}
ret, err := k8s.Ingresses.Get(s, id, params)
if err != nil {
return err
}
printObjectYAML(ret)
return nil
})
}
+20
View File
@@ -25,8 +25,12 @@ func init() {
initRaw()
initConfigMap()
initDeployment()
initStatefulset()
initPod()
initService()
initIngress()
initNamespace()
initK8sNode()
}
type clusterBaseOptions struct {
@@ -44,6 +48,18 @@ type baseListOptions struct {
Offset int `default:"0" help:"page offset"`
}
type NamespaceResourceListOptions struct {
namespaceListOptions
baseListOptions
}
func (o NamespaceResourceListOptions) Params() *jsonutils.JSONDict {
params := fetchNamespaceParams(o.namespaceListOptions)
params.Update(fetchPagingParams(o.baseListOptions))
params.Update(o.ClusterParams())
return params
}
func fetchPagingParams(opt baseListOptions) *jsonutils.JSONDict {
params := jsonutils.NewDict()
if opt.Limit > 0 {
@@ -102,6 +118,10 @@ func resourceCmdN(prefix, suffix string) string {
return fmt.Sprintf("k8s-%s-%s", prefix, suffix)
}
func kubeResourceCmdN(prefix, suffix string) string {
return fmt.Sprintf("kube-%s-%s", prefix, suffix)
}
func clusterContext(clusterId string) modules.ManagerContext {
return modules.ManagerContext{
InstanceManager: k8s.Clusters,
+41
View File
@@ -0,0 +1,41 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
)
func initK8sNode() {
cmdN := func(suffix string) string {
return resourceCmdN("node", suffix)
}
type listOpt struct {
clusterBaseOptions
baseListOptions
}
R(&listOpt{}, cmdN("list"), "List k8s nodes resource", func(s *mcclient.ClientSession, args *listOpt) error {
params := fetchPagingParams(args.baseListOptions)
params.Update(args.ClusterParams())
ret, err := k8s.K8sNodes.List(s, params)
if err != nil {
return err
}
PrintListResultTable(ret, k8s.K8sNodes, s)
return nil
})
type getOpt struct {
clusterBaseOptions
NAME string `help:"Node name"`
}
R(&getOpt{}, cmdN("show"), "Show k8s node", func(s *mcclient.ClientSession, args *getOpt) error {
params := args.ClusterParams()
ret, err := k8s.K8sNodes.Get(s, args.NAME, params)
if err != nil {
return err
}
printObjectYAML(ret)
return nil
})
}
+41
View File
@@ -0,0 +1,41 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
)
func initNamespace() {
cmdN := func(suffix string) string {
return resourceCmdN("namespace", suffix)
}
type listOpt struct {
clusterBaseOptions
baseListOptions
}
R(&listOpt{}, cmdN("list"), "List k8s namespace", func(s *mcclient.ClientSession, args *listOpt) error {
params := fetchPagingParams(args.baseListOptions)
params.Update(args.ClusterParams())
ret, err := k8s.Namespaces.List(s, params)
if err != nil {
return err
}
PrintListResultTable(ret, k8s.Namespaces, s)
return nil
})
type getOpt struct {
clusterBaseOptions
NAME string `help:"Namespace name"`
}
R(&getOpt{}, cmdN("show"), "Show k8s namespace", func(s *mcclient.ClientSession, args *getOpt) error {
params := args.ClusterParams()
ret, err := k8s.Namespaces.Get(s, args.NAME, params)
if err != nil {
return err
}
printObjectYAML(ret)
return nil
})
}
+2 -2
View File
@@ -12,13 +12,13 @@ import (
func initNode() {
cmdN := func(suffix string) string {
return resourceCmdN("node", suffix)
return kubeResourceCmdN("node", suffix)
}
type listOpt struct {
options.BaseListOptions
Cluster string `help:"Filter by cluster"`
}
R(&listOpt{}, cmdN("list"), "List k8s node", func(s *mcclient.ClientSession, args *listOpt) error {
R(&listOpt{}, cmdN("list"), "List k8s infra nodes", func(s *mcclient.ClientSession, args *listOpt) error {
args.Details = options.Bool(true)
var params *jsonutils.JSONDict
{
+2 -9
View File
@@ -14,15 +14,8 @@ func initPod() {
return resourceCmdN("pod", suffix)
}
type listOpt struct {
namespaceListOptions
baseListOptions
}
R(&listOpt{}, cmdN("list"), "List k8s pod", func(s *mcclient.ClientSession, args *listOpt) error {
params := fetchNamespaceParams(args.namespaceListOptions)
params.Update(fetchPagingParams(args.baseListOptions))
params.Update(args.ClusterParams())
ret, err := k8s.Pods.List(s, params)
R(&NamespaceResourceListOptions{}, cmdN("list"), "List k8s pod", func(s *mcclient.ClientSession, args *NamespaceResourceListOptions) error {
ret, err := k8s.Pods.List(s, args.Params())
if err != nil {
return err
}
+4
View File
@@ -17,6 +17,7 @@ func initRelease() {
type listOpt struct {
namespaceListOptions
baseListOptions
Name string `help:"Search by name"`
Filter string `help:"Filter, split by space"`
Admin bool `help:"Admin to show all namespace releases"`
Deployed bool `help:"Show deployed status releases"`
@@ -36,6 +37,9 @@ func initRelease() {
if args.Namespace != "" {
params.Add(json.NewString(args.Namespace), "namespace")
}
if args.Name != "" {
params.Add(json.NewString(args.Name), "name")
}
params.Add(json.JSONTrue, "all")
if args.Admin {
params.Add(json.JSONTrue, "admin")
+1 -1
View File
@@ -36,7 +36,7 @@ func initRepo() {
type getOpt struct {
NAME string `help:"ID or name of the repo"`
}
R(&getOpt{}, cmdN("show"), "Show details fo a repo", func(s *mcclient.ClientSession, args *getOpt) error {
R(&getOpt{}, cmdN("show"), "Show details of a repo", func(s *mcclient.ClientSession, args *getOpt) error {
repo, err := k8s.Repos.Get(s, args.NAME, nil)
if err != nil {
return err
+40
View File
@@ -0,0 +1,40 @@
package k8s
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
)
func initStatefulset() {
cmdN := func(suffix string) string {
return resourceCmdN("statefulset", suffix)
}
R(&NamespaceResourceListOptions{}, cmdN("list"), "List k8s statefulset", func(s *mcclient.ClientSession, args *NamespaceResourceListOptions) error {
ret, err := k8s.StatefulSets.List(s, args.Params())
if err != nil {
return err
}
PrintListResultTable(ret, k8s.StatefulSets, s)
return nil
})
type getOpt struct {
resourceGetOptions
}
R(&getOpt{}, cmdN("show"), "Get statefulset details", func(s *mcclient.ClientSession, args *getOpt) error {
id := args.NAME
params := args.ClusterParams()
if args.Namespace != "" {
params.Add(jsonutils.NewString(args.Namespace), "namespace")
}
ret, err := k8s.StatefulSets.Get(s, id, params)
if err != nil {
return err
}
printObjectYAML(ret)
return nil
})
}
+27 -15
View File
@@ -36,24 +36,28 @@ func (man ClusterResourceManager) GetCluster(obj jsonutils.JSONObject) interface
return cluster
}
type NamespaceResourceManager struct {
type MetaResourceManager struct {
*ClusterResourceManager
nameGetter
ageGetter
labelGetter
}
func NewMetaResourceManager(kw, kwp string, columns, adminColumns *Columns) *MetaResourceManager {
newCols := NewMetaCols(columns.Array()...)
man := NewClusterResourceManager(kw, kwp, newCols, adminColumns)
return &MetaResourceManager{man, getName, getAge, getLabel}
}
type NamespaceResourceManager struct {
*MetaResourceManager
namespaceGetter
}
func NewNamespaceResourceManager(kw, kwp string, columns, adminColumns *Columns) *NamespaceResourceManager {
newCols := NewNamespaceCols(columns.Array()...)
man := NewClusterResourceManager(kw, kwp, newCols, adminColumns)
return &NamespaceResourceManager{man}
}
func (m NamespaceResourceManager) GetName(obj jsonutils.JSONObject) interface{} {
name, _ := obj.GetString("name")
return name
}
func (m NamespaceResourceManager) GetNamespace(obj jsonutils.JSONObject) interface{} {
ns, _ := obj.GetString("namespace")
return ns
man := NewMetaResourceManager(kw, kwp, newCols, adminColumns)
return &NamespaceResourceManager{man, getNamespace}
}
type Columns struct {
@@ -85,8 +89,16 @@ func (c Columns) Array() []string {
return c.cols
}
func NewNameCols(col ...string) *Columns {
return NewColumns("Name").Add(col...)
}
func NewMetaCols(col ...string) *Columns {
return NewNameCols("Age").Add(col...)
}
func NewNamespaceCols(col ...string) *Columns {
return NewColumns("Name", "Namespace").Add(col...)
return NewMetaCols("Namespace", "Labels").Add(col...)
}
func NewClusterCols(col ...string) *Columns {
@@ -94,7 +106,7 @@ func NewClusterCols(col ...string) *Columns {
}
func NewResourceCols(col ...string) *Columns {
return NewColumns("Name", "Id").Add(col...)
return NewNameCols("Id").Add(col...)
}
type ListPrinter interface {
+1 -1
View File
@@ -13,6 +13,6 @@ type DeploymentManager struct {
func init() {
Deployments = &DeploymentManager{
NewNamespaceResourceManager("deployment", "deployments",
NewColumns("labels"), NewColumns())}
NewNamespaceCols(), NewColumns())}
modules.Register(Deployments)
}
+70
View File
@@ -0,0 +1,70 @@
package k8s
import (
"fmt"
"strings"
"time"
"github.com/hako/durafmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
)
var (
getName nameGetter
getStatus statusGetter
getAge ageGetter
getNamespace namespaceGetter
getLabel labelGetter
)
type nameGetter struct{}
func (g nameGetter) GetName(obj jsonutils.JSONObject) interface{} {
name, _ := obj.GetString("name")
return name
}
type statusGetter struct{}
func (g statusGetter) GetStatus(obj jsonutils.JSONObject) interface{} {
status, _ := obj.GetString("status")
return status
}
type ageGetter struct{}
func (g ageGetter) GetAge(obj jsonutils.JSONObject) interface{} {
creationTimestamp, err := obj.GetString("creationTimestamp")
if err != nil {
log.Errorf("Get creationTimestamp error: %v", err)
return nil
}
t, _ := time.Parse(time.RFC3339, creationTimestamp)
dur := time.Since(t)
return durafmt.ParseShort(dur).String()
}
type namespaceGetter struct{}
func (g namespaceGetter) GetNamespace(obj jsonutils.JSONObject) interface{} {
ns, _ := obj.GetString("namespace")
return ns
}
type labelGetter struct{}
func (g labelGetter) GetLabels(obj jsonutils.JSONObject) interface{} {
labels, _ := obj.GetMap("labels")
str := ""
ls := []string{}
for k, v := range labels {
vs, _ := v.GetString()
ls = append(ls, fmt.Sprintf("%s=%s", k, vs))
}
if len(ls) != 0 {
str = strings.Join(ls, ",")
}
return str
}
+18
View File
@@ -0,0 +1,18 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var Ingresses *IngressManager
type IngressManager struct {
*NamespaceResourceManager
}
func init() {
Ingresses = &IngressManager{
NewNamespaceResourceManager("ingress", "ingresses",
NewNamespaceCols(), NewColumns())}
modules.Register(Ingresses)
}
+21
View File
@@ -0,0 +1,21 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var (
K8sNodes *K8sNodeManager
)
type K8sNodeManager struct {
*MetaResourceManager
}
func init() {
K8sNodes = &K8sNodeManager{
MetaResourceManager: NewMetaResourceManager("k8s_node", "k8s_nodes", NewColumns(), NewColumns()),
}
modules.Register(K8sNodes)
}
+21
View File
@@ -0,0 +1,21 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var Namespaces *NamespaceManager
type NamespaceManager struct {
*MetaResourceManager
statusGetter
}
func init() {
Namespaces = &NamespaceManager{
MetaResourceManager: NewMetaResourceManager("namespace", "namespaces", NewNameCols("Status"), NewClusterCols()),
statusGetter: getStatus,
}
modules.Register(Namespaces)
}
+6 -25
View File
@@ -1,9 +1,6 @@
package k8s
import (
"fmt"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/modules"
@@ -13,13 +10,16 @@ var Pods *PodManager
type PodManager struct {
*NamespaceResourceManager
statusGetter
}
func init() {
Pods = &PodManager{
NewNamespaceResourceManager("pod", "pods",
NewNamespaceCols("IP", "Status", "Restarts", "Labels"),
NewClusterCols("Node"))}
NamespaceResourceManager: NewNamespaceResourceManager("pod", "pods",
NewNamespaceCols("IP", "Status", "Restarts"),
NewClusterCols("Node")),
statusGetter: getStatus,
}
modules.Register(Pods)
}
@@ -29,30 +29,11 @@ func (m PodManager) GetIP(obj jsonutils.JSONObject) interface{} {
return ip
}
func (m PodManager) GetStatus(obj jsonutils.JSONObject) interface{} {
status, _ := obj.GetString("status")
return status
}
func (m PodManager) GetRestarts(obj jsonutils.JSONObject) interface{} {
count, _ := obj.Int("restartCount")
return count
}
func (m PodManager) GetLabels(obj jsonutils.JSONObject) interface{} {
labels, _ := obj.GetMap("labels")
str := ""
ls := []string{}
for k, v := range labels {
vs, _ := v.GetString()
ls = append(ls, fmt.Sprintf("%s=%s", k, vs))
}
if len(ls) != 0 {
str = strings.Join(ls, ",")
}
return str
}
func (m PodManager) GetNode(obj jsonutils.JSONObject) interface{} {
node, _ := obj.GetString("nodeName")
return node
+3 -17
View File
@@ -3,12 +3,8 @@ package k8s
import (
"fmt"
"strings"
"time"
"github.com/hako/durafmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
@@ -22,8 +18,9 @@ type ServiceManager struct {
func init() {
Services = &ServiceManager{NewNamespaceResourceManager(
"k8s_service", "k8s_services",
NewNamespaceCols("Type", "ClusterIP", "Ports", "Age", "Selector"),
NewColumns())}
NewNamespaceCols("Type", "ClusterIP", "Ports", "Selector"),
NewColumns()),
}
modules.Register(Services)
}
@@ -37,17 +34,6 @@ func (s ServiceManager) GetClusterIP(obj jsonutils.JSONObject) interface{} {
return clusterIp
}
func (s ServiceManager) GetAge(obj jsonutils.JSONObject) interface{} {
creationTimestamp, err := obj.GetString("creationTimestamp")
if err != nil {
log.Errorf("Get creationTimestamp error: %v", err)
return nil
}
t, _ := time.Parse(time.RFC3339, creationTimestamp)
dur := time.Since(t)
return durafmt.ParseShort(dur).String()
}
func (s ServiceManager) GetSelector(obj jsonutils.JSONObject) interface{} {
selectorObj, _ := obj.GetMap("selector")
var selectors []string
+18
View File
@@ -0,0 +1,18 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var StatefulSets *StatefulSetManager
type StatefulSetManager struct {
*NamespaceResourceManager
}
func init() {
StatefulSets = &StatefulSetManager{
NewNamespaceResourceManager("statefulset", "statefulsets",
NewNamespaceCols(), NewColumns())}
modules.Register(StatefulSets)
}