From 5f01cb9c04da6b7ad43287cdcdae08962fb80b3b Mon Sep 17 00:00:00 2001 From: TangBin Date: Wed, 5 Sep 2018 19:48:52 +0800 Subject: [PATCH 1/9] add climc --- cmd/climc/shell/parameters.go | 122 +++++++++++++++++++++++++ pkg/mcclient/modules/managers.go | 8 ++ pkg/mcclient/modules/mod_parameters.go | 17 ++++ 3 files changed, 147 insertions(+) create mode 100644 cmd/climc/shell/parameters.go create mode 100644 pkg/mcclient/modules/mod_parameters.go diff --git a/cmd/climc/shell/parameters.go b/cmd/climc/shell/parameters.go new file mode 100644 index 0000000000..2d1c49caa0 --- /dev/null +++ b/cmd/climc/shell/parameters.go @@ -0,0 +1,122 @@ +package shell + +import ( + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/mcclient/modules" + "yunion.io/x/onecloud/pkg/mcclient/options" +) + +func init() { + type ParametersListOptions struct { + options.BaseListOptions + } + + R(&ParametersListOptions{}, "parameter-list", "list parameters", func(s *mcclient.ClientSession, args *ParametersListOptions) error { + params, err := options.ListStructToParams(args) + if err != nil { + return err + } + + result, err := modules.Parameters.List(s, params) + if err != nil { + return err + } + printList(result, modules.Parameters.GetColumns(s)) + return nil + }) + + type ParametersShowOptions struct { + Admin bool `help:"Show parameter of all users, ADMIN only"` + UserId string `help:"Show parameter of a user, ADMIN only"` + NAME string `help:"The name of parameter"` + } + + R(&ParametersShowOptions{}, "parameter-show", "show a parameter", func(s *mcclient.ClientSession, args *ParametersShowOptions) error { + params := jsonutils.NewDict() + if args.Admin { + params.Add(jsonutils.JSONTrue, "admin") + } + + if len(args.UserId) > 0 { + params.Add(jsonutils.NewString(args.UserId), "user_id") + } + parameter, err := modules.Parameters.Get(s, args.NAME, params) + if err != nil { + return err + } + printObject(parameter) + return nil + }) + + type ParametersCreateOptions struct { + NAME string `help:"The name of parameter"` + VALUE string `help:"The content of parameter"` + } + + R(&ParametersCreateOptions{}, "parameter-create", "create a parameter", func(s *mcclient.ClientSession, args *ParametersCreateOptions) error { + params := jsonutils.NewDict() + params.Add(jsonutils.NewString(args.NAME), "name") + params.Add(jsonutils.NewString(args.VALUE), "value") + + parameter, err := modules.Parameters.Create(s, params) + if err != nil { + return err + } + printObject(parameter) + return nil + }) + + type ParametersUpdateOptions struct { + Admin bool `help:"Update parameter of all users, ADMIN only"` + UserId string `help:"Update parameter of a user, ADMIN only"` + NAME string `help:"The name of parameter"` + VALUE string `help:"The content of parameter"` + } + + R(&ParametersUpdateOptions{}, "parameter-update", "update parameter", func(s *mcclient.ClientSession, args *ParametersUpdateOptions) error { + params := jsonutils.NewDict() + if len(args.VALUE) > 0 { + params.Add(jsonutils.NewString(args.VALUE), "value") + } + + if args.Admin { + params.Add(jsonutils.JSONTrue, "admin") + } + + if len(args.UserId) > 0 { + params.Add(jsonutils.NewString(args.UserId), "user_id") + } + + parameter, err := modules.Parameters.Update(s, args.NAME, params) + if err != nil { + return err + } + printObject(parameter) + return nil + }) + + type ParametersDeleteOptions struct { + Admin bool `help:"delete parameter of a user, ADMIN only"` + UserId string `help:"delete parameter of a user, ADMIN only"` + NAME string `help:"The name of parameter"` + } + + R(&ParametersDeleteOptions{}, "parameter-delete", "delete notice", func(s *mcclient.ClientSession, args *ParametersDeleteOptions) error { + params := jsonutils.NewDict() + if args.Admin { + params.Add(jsonutils.JSONTrue, "admin") + } + + if len(args.UserId) > 0 { + params.Add(jsonutils.NewString(args.UserId), "user_id") + } + + parameter, err := modules.Notice.Delete(s, args.NAME, params) + if err != nil { + return err + } + printObject(parameter) + return nil + }) +} diff --git a/pkg/mcclient/modules/managers.go b/pkg/mcclient/modules/managers.go index b138009ed1..bc7e30dd93 100644 --- a/pkg/mcclient/modules/managers.go +++ b/pkg/mcclient/modules/managers.go @@ -115,3 +115,11 @@ func NewYunionAgentManager(keyword, keywordPlural string, columns, adminColumns serviceType: "yunionagent"}, Keyword: keyword, KeywordPlural: keywordPlural} } + +func NewYunionConfManager(keyword, keywordPlural string, columns, adminColumns []string) ResourceManager { + return ResourceManager{ + BaseManager: BaseManager{columns: columns, + adminColumns: adminColumns, + serviceType: "yunionconf"}, + Keyword: keyword, KeywordPlural: keywordPlural} +} \ No newline at end of file diff --git a/pkg/mcclient/modules/mod_parameters.go b/pkg/mcclient/modules/mod_parameters.go new file mode 100644 index 0000000000..7ae596c261 --- /dev/null +++ b/pkg/mcclient/modules/mod_parameters.go @@ -0,0 +1,17 @@ +package modules + +type ParametersManager struct { + ResourceManager +} + +var ( + Parameters ParametersManager +) + +func init() { + Parameters = ParametersManager{NewYunionConfManager("parameter", "parameters", + []string{"id", "created_at", "update_at", "name", "value"}, + []string{"user_id"}, + )} + register(&Parameters) +} \ No newline at end of file From 53a7a35f4c94d2f37ce9f85f6f7586165e39124b Mon Sep 17 00:00:00 2001 From: TangBin Date: Thu, 6 Sep 2018 20:08:32 +0800 Subject: [PATCH 2/9] temp!!withbugs --- cmd/climc/shell/parameters.go | 70 +++++++++++++++++--------- pkg/mcclient/modules/mod_parameters.go | 2 +- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/cmd/climc/shell/parameters.go b/cmd/climc/shell/parameters.go index 2d1c49caa0..ad9c5c6cdd 100644 --- a/cmd/climc/shell/parameters.go +++ b/cmd/climc/shell/parameters.go @@ -10,6 +10,7 @@ import ( func init() { type ParametersListOptions struct { options.BaseListOptions + NamespaceId string `help:"Show parameter of specificated namespace id, ADMIN only"` } R(&ParametersListOptions{}, "parameter-list", "list parameters", func(s *mcclient.ClientSession, args *ParametersListOptions) error { @@ -18,6 +19,11 @@ func init() { return err } + if len(args.NamespaceId) > 0 { + params.Add(jsonutils.JSONTrue, "admin") + params.Add(jsonutils.NewString(args.NamespaceId), "namespace_id") + } + result, err := modules.Parameters.List(s, params) if err != nil { return err @@ -27,19 +33,27 @@ func init() { }) type ParametersShowOptions struct { - Admin bool `help:"Show parameter of all users, ADMIN only"` - UserId string `help:"Show parameter of a user, ADMIN only"` - NAME string `help:"The name of parameter"` + Namespace string `help:"Show parameter of specificated namespace, ADMIN only"` + NamespaceId string `help:"Show parameter of specificated namespace id, ADMIN only"` + UserId string `help:"Show parameter created by specificated user, ADMIN only"` + NAME string `help:"The name of parameter"` } R(&ParametersShowOptions{}, "parameter-show", "show a parameter", func(s *mcclient.ClientSession, args *ParametersShowOptions) error { params := jsonutils.NewDict() - if args.Admin { + if len(args.Namespace) > 0 { params.Add(jsonutils.JSONTrue, "admin") + params.Add(jsonutils.NewString(args.Namespace), "namespace") + } + + if len(args.NamespaceId) > 0 { + params.Add(jsonutils.JSONTrue, "admin") + params.Add(jsonutils.NewString(args.NamespaceId), "namespace_id") } if len(args.UserId) > 0 { - params.Add(jsonutils.NewString(args.UserId), "user_id") + params.Add(jsonutils.JSONTrue, "admin") + params.Add(jsonutils.NewString(args.UserId), "created_by") } parameter, err := modules.Parameters.Get(s, args.NAME, params) if err != nil { @@ -50,8 +64,10 @@ func init() { }) type ParametersCreateOptions struct { - NAME string `help:"The name of parameter"` - VALUE string `help:"The content of parameter"` + User string `help:"Create parameter for specificated user, ADMIN only"` + Service string `help:"Create parameter for specificated service, ADMIN only"` + NAME string `help:"The name of parameter"` + VALUE string `help:"The content of parameter"` } R(&ParametersCreateOptions{}, "parameter-create", "create a parameter", func(s *mcclient.ClientSession, args *ParametersCreateOptions) error { @@ -59,6 +75,12 @@ func init() { params.Add(jsonutils.NewString(args.NAME), "name") params.Add(jsonutils.NewString(args.VALUE), "value") + if len(args.User) > 0 { + params.Add(jsonutils.NewString(args.User), "user_id") + } else if len(args.Service) > 0 { + params.Add(jsonutils.NewString(args.Service), "service_id") + } + parameter, err := modules.Parameters.Create(s, params) if err != nil { return err @@ -68,10 +90,10 @@ func init() { }) type ParametersUpdateOptions struct { - Admin bool `help:"Update parameter of all users, ADMIN only"` - UserId string `help:"Update parameter of a user, ADMIN only"` - NAME string `help:"The name of parameter"` - VALUE string `help:"The content of parameter"` + User string `help:"Update parameter for specificated user, ADMIN only"` + Service string `help:"Update parameter for specificated service, ADMIN only"` + NAME string `help:"The name of parameter"` + VALUE string `help:"The content of parameter"` } R(&ParametersUpdateOptions{}, "parameter-update", "update parameter", func(s *mcclient.ClientSession, args *ParametersUpdateOptions) error { @@ -80,12 +102,12 @@ func init() { params.Add(jsonutils.NewString(args.VALUE), "value") } - if args.Admin { + if len(args.User) > 0 { params.Add(jsonutils.JSONTrue, "admin") - } - - if len(args.UserId) > 0 { - params.Add(jsonutils.NewString(args.UserId), "user_id") + params.Add(jsonutils.NewString(args.User), "user_id") + } else if len(args.Service) > 0 { + params.Add(jsonutils.JSONTrue, "admin") + params.Add(jsonutils.NewString(args.Service), "service_id") } parameter, err := modules.Parameters.Update(s, args.NAME, params) @@ -97,19 +119,19 @@ func init() { }) type ParametersDeleteOptions struct { - Admin bool `help:"delete parameter of a user, ADMIN only"` - UserId string `help:"delete parameter of a user, ADMIN only"` - NAME string `help:"The name of parameter"` + User string `help:"Delete parameter for specificated user, ADMIN only"` + Service string `help:"Delete parameter for specificated service, ADMIN only"` + NAME string `help:"The name of parameter"` } R(&ParametersDeleteOptions{}, "parameter-delete", "delete notice", func(s *mcclient.ClientSession, args *ParametersDeleteOptions) error { params := jsonutils.NewDict() - if args.Admin { + if len(args.User) > 0 { params.Add(jsonutils.JSONTrue, "admin") - } - - if len(args.UserId) > 0 { - params.Add(jsonutils.NewString(args.UserId), "user_id") + params.Add(jsonutils.NewString(args.User), "user_id") + } else if len(args.Service) > 0 { + params.Add(jsonutils.JSONTrue, "admin") + params.Add(jsonutils.NewString(args.Service), "service_id") } parameter, err := modules.Notice.Delete(s, args.NAME, params) diff --git a/pkg/mcclient/modules/mod_parameters.go b/pkg/mcclient/modules/mod_parameters.go index 7ae596c261..dad5bfe83d 100644 --- a/pkg/mcclient/modules/mod_parameters.go +++ b/pkg/mcclient/modules/mod_parameters.go @@ -11,7 +11,7 @@ var ( func init() { Parameters = ParametersManager{NewYunionConfManager("parameter", "parameters", []string{"id", "created_at", "update_at", "name", "value"}, - []string{"user_id"}, + []string{"namespace", "namespace_id", "created_by", "updated_by"}, )} register(&Parameters) } \ No newline at end of file From aed6a23cfe1a596e881585f99810d497b25b83b5 Mon Sep 17 00:00:00 2001 From: TangBin Date: Mon, 10 Sep 2018 11:30:09 +0800 Subject: [PATCH 3/9] delete&update parameter in context --- cmd/climc/shell/parameters.go | 24 ++++++++++++++++++++++-- pkg/mcclient/session.go | 4 ++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/cmd/climc/shell/parameters.go b/cmd/climc/shell/parameters.go index ad9c5c6cdd..28ed9b1866 100644 --- a/cmd/climc/shell/parameters.go +++ b/cmd/climc/shell/parameters.go @@ -102,15 +102,25 @@ func init() { params.Add(jsonutils.NewString(args.VALUE), "value") } + var ctx modules.Manager + var ctxid string if len(args.User) > 0 { + ctxid = args.User + ctx = &modules.UsersV3 params.Add(jsonutils.JSONTrue, "admin") params.Add(jsonutils.NewString(args.User), "user_id") + } else if len(args.Service) > 0 { + ctxid = args.Service + ctx = &modules.ServicesV3 params.Add(jsonutils.JSONTrue, "admin") params.Add(jsonutils.NewString(args.Service), "service_id") + } else { + ctxid = s.GetUserId() + ctx = &modules.UsersV3 } - parameter, err := modules.Parameters.Update(s, args.NAME, params) + parameter, err := modules.Parameters.PutInContext(s, args.NAME, params, ctx, ctxid) if err != nil { return err } @@ -126,15 +136,25 @@ func init() { R(&ParametersDeleteOptions{}, "parameter-delete", "delete notice", func(s *mcclient.ClientSession, args *ParametersDeleteOptions) error { params := jsonutils.NewDict() + + var ctx modules.Manager + var ctxid string if len(args.User) > 0 { + ctxid = args.User + ctx = &modules.UsersV3 params.Add(jsonutils.JSONTrue, "admin") params.Add(jsonutils.NewString(args.User), "user_id") } else if len(args.Service) > 0 { + ctxid = args.Service + ctx = &modules.ServicesV3 params.Add(jsonutils.JSONTrue, "admin") params.Add(jsonutils.NewString(args.Service), "service_id") + } else { + ctxid = s.GetUserId() + ctx = &modules.UsersV3 } - parameter, err := modules.Notice.Delete(s, args.NAME, params) + parameter, err := modules.Parameters.DeleteInContext(s, args.NAME, params, ctx, ctxid) if err != nil { return err } diff --git a/pkg/mcclient/session.go b/pkg/mcclient/session.go index 527e05c4e4..4d5fac7974 100644 --- a/pkg/mcclient/session.go +++ b/pkg/mcclient/session.go @@ -151,6 +151,10 @@ func (this *ClientSession) GetRegion() string { return this.region } +func (this *ClientSession) GetUserId() string { + return this.token.GetUserId() +} + func (this *ClientSession) GetTenantId() string { return this.token.GetTenantId() } From 30f692b88de41a2df5f18c1793ab62146cb9a0e8 Mon Sep 17 00:00:00 2001 From: TangBin Date: Mon, 10 Sep 2018 15:03:31 +0800 Subject: [PATCH 4/9] add parameter climc --- cmd/climc/shell/parameters.go | 80 ++++++++++++++++------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/cmd/climc/shell/parameters.go b/cmd/climc/shell/parameters.go index 28ed9b1866..9b08647c12 100644 --- a/cmd/climc/shell/parameters.go +++ b/cmd/climc/shell/parameters.go @@ -10,7 +10,9 @@ import ( func init() { type ParametersListOptions struct { options.BaseListOptions - NamespaceId string `help:"Show parameter of specificated namespace id, ADMIN only"` + NamespaceId string `help:"List parameter of specificated namespace id, ADMIN only"` + User string `help:"List parameter of specificated user id/ name, ADMIN only"` + Service string `help:"List parameter of specificated service id/ name, ADMIN only"` } R(&ParametersListOptions{}, "parameter-list", "list parameters", func(s *mcclient.ClientSession, args *ParametersListOptions) error { @@ -19,12 +21,18 @@ func init() { return err } + var result *modules.ListResult if len(args.NamespaceId) > 0 { - params.Add(jsonutils.JSONTrue, "admin") params.Add(jsonutils.NewString(args.NamespaceId), "namespace_id") + result, err = modules.Parameters.List(s, params) + } else if len(args.User) > 0 { + result, err = modules.Parameters.ListInContext(s, params, &modules.UsersV3, args.User) + } else if len(args.Service) > 0 { + result, err = modules.Parameters.ListInContext(s, params, &modules.ServicesV3, args.Service) + } else { + result, err = modules.Parameters.List(s, params) } - result, err := modules.Parameters.List(s, params) if err != nil { return err } @@ -33,29 +41,32 @@ func init() { }) type ParametersShowOptions struct { - Namespace string `help:"Show parameter of specificated namespace, ADMIN only"` NamespaceId string `help:"Show parameter of specificated namespace id, ADMIN only"` - UserId string `help:"Show parameter created by specificated user, ADMIN only"` + User string `help:"Show parameter of specificated user or user id, ADMIN only"` + Service string `help:"Show parameter of specificated service or service id, ADMIN only"` NAME string `help:"The name of parameter"` } R(&ParametersShowOptions{}, "parameter-show", "show a parameter", func(s *mcclient.ClientSession, args *ParametersShowOptions) error { params := jsonutils.NewDict() - if len(args.Namespace) > 0 { - params.Add(jsonutils.JSONTrue, "admin") - params.Add(jsonutils.NewString(args.Namespace), "namespace") - } - if len(args.NamespaceId) > 0 { params.Add(jsonutils.JSONTrue, "admin") params.Add(jsonutils.NewString(args.NamespaceId), "namespace_id") } - if len(args.UserId) > 0 { - params.Add(jsonutils.JSONTrue, "admin") - params.Add(jsonutils.NewString(args.UserId), "created_by") + var parameter jsonutils.JSONObject + var err error + if len(args.NamespaceId) > 0 { + params.Add(jsonutils.NewString(args.NamespaceId), "namespace_id") + parameter, err = modules.Parameters.Get(s, args.NAME, params) + } else if len(args.User) > 0 { + parameter, err = modules.Parameters.GetInContext(s, args.NAME, params, &modules.UsersV3, args.User) + } else if len(args.Service) > 0 { + parameter, err = modules.Parameters.GetInContext(s, args.NAME, params, &modules.ServicesV3, args.Service) + } else { + parameter, err = modules.Parameters.Get(s, args.NAME, params) } - parameter, err := modules.Parameters.Get(s, args.NAME, params) + if err != nil { return err } @@ -64,8 +75,8 @@ func init() { }) type ParametersCreateOptions struct { - User string `help:"Create parameter for specificated user, ADMIN only"` - Service string `help:"Create parameter for specificated service, ADMIN only"` + User string `help:"Create parameter for specificated user or user id, ADMIN only"` + Service string `help:"Create parameter for specificated service or service id, ADMIN only"` NAME string `help:"The name of parameter"` VALUE string `help:"The content of parameter"` } @@ -102,25 +113,16 @@ func init() { params.Add(jsonutils.NewString(args.VALUE), "value") } - var ctx modules.Manager - var ctxid string + var parameter jsonutils.JSONObject + var err error if len(args.User) > 0 { - ctxid = args.User - ctx = &modules.UsersV3 - params.Add(jsonutils.JSONTrue, "admin") - params.Add(jsonutils.NewString(args.User), "user_id") - + parameter, err = modules.Parameters.PutInContext(s, args.NAME, params, &modules.UsersV3, args.User) } else if len(args.Service) > 0 { - ctxid = args.Service - ctx = &modules.ServicesV3 - params.Add(jsonutils.JSONTrue, "admin") - params.Add(jsonutils.NewString(args.Service), "service_id") + parameter, err = modules.Parameters.PutInContext(s, args.NAME, params, &modules.ServicesV3, args.Service) } else { - ctxid = s.GetUserId() - ctx = &modules.UsersV3 + parameter, err = modules.Parameters.PutInContext(s, args.NAME, params, &modules.UsersV3, s.GetUserId()) } - parameter, err := modules.Parameters.PutInContext(s, args.NAME, params, ctx, ctxid) if err != nil { return err } @@ -137,24 +139,16 @@ func init() { R(&ParametersDeleteOptions{}, "parameter-delete", "delete notice", func(s *mcclient.ClientSession, args *ParametersDeleteOptions) error { params := jsonutils.NewDict() - var ctx modules.Manager - var ctxid string + var parameter jsonutils.JSONObject + var err error if len(args.User) > 0 { - ctxid = args.User - ctx = &modules.UsersV3 - params.Add(jsonutils.JSONTrue, "admin") - params.Add(jsonutils.NewString(args.User), "user_id") + parameter, err = modules.Parameters.DeleteInContext(s, args.NAME, params, &modules.UsersV3, args.User) } else if len(args.Service) > 0 { - ctxid = args.Service - ctx = &modules.ServicesV3 - params.Add(jsonutils.JSONTrue, "admin") - params.Add(jsonutils.NewString(args.Service), "service_id") + parameter, err = modules.Parameters.DeleteInContext(s, args.NAME, params, &modules.ServicesV3, args.Service) } else { - ctxid = s.GetUserId() - ctx = &modules.UsersV3 + parameter, err = modules.Parameters.DeleteInContext(s, args.NAME, params, &modules.UsersV3, s.GetUserId()) } - parameter, err := modules.Parameters.DeleteInContext(s, args.NAME, params, ctx, ctxid) if err != nil { return err } From a8c70bd9a10cf471eccfad59cdea1f30ab007972 Mon Sep 17 00:00:00 2001 From: TangBin Date: Mon, 10 Sep 2018 19:10:00 +0800 Subject: [PATCH 5/9] bugfix --- cmd/climc/shell/parameters.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/climc/shell/parameters.go b/cmd/climc/shell/parameters.go index 9b08647c12..00b1008182 100644 --- a/cmd/climc/shell/parameters.go +++ b/cmd/climc/shell/parameters.go @@ -9,10 +9,10 @@ import ( func init() { type ParametersListOptions struct { - options.BaseListOptions NamespaceId string `help:"List parameter of specificated namespace id, ADMIN only"` User string `help:"List parameter of specificated user id/ name, ADMIN only"` Service string `help:"List parameter of specificated service id/ name, ADMIN only"` + options.BaseListOptions } R(&ParametersListOptions{}, "parameter-list", "list parameters", func(s *mcclient.ClientSession, args *ParametersListOptions) error { @@ -120,7 +120,7 @@ func init() { } else if len(args.Service) > 0 { parameter, err = modules.Parameters.PutInContext(s, args.NAME, params, &modules.ServicesV3, args.Service) } else { - parameter, err = modules.Parameters.PutInContext(s, args.NAME, params, &modules.UsersV3, s.GetUserId()) + parameter, err = modules.Parameters.Put(s, args.NAME, params) } if err != nil { @@ -146,7 +146,7 @@ func init() { } else if len(args.Service) > 0 { parameter, err = modules.Parameters.DeleteInContext(s, args.NAME, params, &modules.ServicesV3, args.Service) } else { - parameter, err = modules.Parameters.DeleteInContext(s, args.NAME, params, &modules.UsersV3, s.GetUserId()) + parameter, err = modules.Parameters.Delete(s, args.NAME, nil) } if err != nil { From b700a7bedcb619de6f0ec3c098b774a1491dd51c Mon Sep 17 00:00:00 2001 From: TangBin Date: Mon, 10 Sep 2018 19:27:11 +0800 Subject: [PATCH 6/9] fix help desc string --- cmd/climc/shell/parameters.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/climc/shell/parameters.go b/cmd/climc/shell/parameters.go index 00b1008182..3c99ce16fc 100644 --- a/cmd/climc/shell/parameters.go +++ b/cmd/climc/shell/parameters.go @@ -10,8 +10,8 @@ import ( func init() { type ParametersListOptions struct { NamespaceId string `help:"List parameter of specificated namespace id, ADMIN only"` - User string `help:"List parameter of specificated user id/ name, ADMIN only"` - Service string `help:"List parameter of specificated service id/ name, ADMIN only"` + User string `help:"List parameter of specificated user id, ADMIN only"` + Service string `help:"List parameter of specificated service id, ADMIN only"` options.BaseListOptions } @@ -42,8 +42,8 @@ func init() { type ParametersShowOptions struct { NamespaceId string `help:"Show parameter of specificated namespace id, ADMIN only"` - User string `help:"Show parameter of specificated user or user id, ADMIN only"` - Service string `help:"Show parameter of specificated service or service id, ADMIN only"` + User string `help:"Show parameter of specificated user id, ADMIN only"` + Service string `help:"Show parameter of specificated service id, ADMIN only"` NAME string `help:"The name of parameter"` } @@ -75,8 +75,8 @@ func init() { }) type ParametersCreateOptions struct { - User string `help:"Create parameter for specificated user or user id, ADMIN only"` - Service string `help:"Create parameter for specificated service or service id, ADMIN only"` + User string `help:"Create parameter for specificated user id, ADMIN only"` + Service string `help:"Create parameter for specificated service id, ADMIN only"` NAME string `help:"The name of parameter"` VALUE string `help:"The content of parameter"` } @@ -101,8 +101,8 @@ func init() { }) type ParametersUpdateOptions struct { - User string `help:"Update parameter for specificated user, ADMIN only"` - Service string `help:"Update parameter for specificated service, ADMIN only"` + User string `help:"Update parameter of specificated user id, ADMIN only"` + Service string `help:"Update parameter of specificated service id, ADMIN only"` NAME string `help:"The name of parameter"` VALUE string `help:"The content of parameter"` } @@ -131,8 +131,8 @@ func init() { }) type ParametersDeleteOptions struct { - User string `help:"Delete parameter for specificated user, ADMIN only"` - Service string `help:"Delete parameter for specificated service, ADMIN only"` + User string `help:"Delete parameter of specificated user id, ADMIN only"` + Service string `help:"Delete parameter of specificated service id, ADMIN only"` NAME string `help:"The name of parameter"` } From b7ca29581f77f2fce9cea13c317414a108bcae02 Mon Sep 17 00:00:00 2001 From: TangBin Date: Thu, 13 Sep 2018 14:24:20 +0800 Subject: [PATCH 7/9] add yunionconf service --- .../root/etc/yunion/yunionconf.conf.sample | 8 + .../yunionconf/yunion-yunionconf.service | 15 ++ build/yunionconf/vars | 1 + cmd/yunionconf/main.go | 14 ++ pkg/yunionconf/handlers.go | 20 ++ pkg/yunionconf/models/initdb.go | 19 ++ pkg/yunionconf/models/parameters.go | 214 ++++++++++++++++++ pkg/yunionconf/options/options.go | 11 + pkg/yunionconf/service/service.go | 38 ++++ 9 files changed, 340 insertions(+) create mode 100644 build/yunionconf/root/etc/yunion/yunionconf.conf.sample create mode 100644 build/yunionconf/root/opt/yunion/share/yunionconf/yunion-yunionconf.service create mode 100644 build/yunionconf/vars create mode 100644 cmd/yunionconf/main.go create mode 100644 pkg/yunionconf/handlers.go create mode 100644 pkg/yunionconf/models/initdb.go create mode 100644 pkg/yunionconf/models/parameters.go create mode 100644 pkg/yunionconf/options/options.go create mode 100644 pkg/yunionconf/service/service.go diff --git a/build/yunionconf/root/etc/yunion/yunionconf.conf.sample b/build/yunionconf/root/etc/yunion/yunionconf.conf.sample new file mode 100644 index 0000000000..0c93ae6372 --- /dev/null +++ b/build/yunionconf/root/etc/yunion/yunionconf.conf.sample @@ -0,0 +1,8 @@ +auth_url = http://10.168.222.251:35357/v3 +admin_user = sysadmin +admin_passwd = MxqhTC2VKe067jtD +admin_project = system +port = 9889 +cors_hosts = * +sql_connection = 'mysql+pymysql://yunionconf:PASSWORD@10.168.222.1:3306/yunionconf?charset=utf8' +auto_sync_table = True \ No newline at end of file diff --git a/build/yunionconf/root/opt/yunion/share/yunionconf/yunion-yunionconf.service b/build/yunionconf/root/opt/yunion/share/yunionconf/yunion-yunionconf.service new file mode 100644 index 0000000000..9f30d5322f --- /dev/null +++ b/build/yunionconf/root/opt/yunion/share/yunionconf/yunion-yunionconf.service @@ -0,0 +1,15 @@ +[Unit] +Description=Yunion Conf Service +Documentation=http://doc.yunionyun.com +After=network.target + +[Service] +Type=simple +User=yunion +Group=yunion +ExecStart=/opt/yunion/bin/yunionconf --config /etc/yunion/yunionconf.conf +WorkingDirectory=/opt/yunion +KillMode=process + +[Install] +WantedBy=multi-user.target diff --git a/build/yunionconf/vars b/build/yunionconf/vars new file mode 100644 index 0000000000..b18c428ecc --- /dev/null +++ b/build/yunionconf/vars @@ -0,0 +1 @@ +DESCRIPTION="Yunion Conf Service" diff --git a/cmd/yunionconf/main.go b/cmd/yunionconf/main.go new file mode 100644 index 0000000000..138cd057ab --- /dev/null +++ b/cmd/yunionconf/main.go @@ -0,0 +1,14 @@ +package main + +/* +Yunion Conf Service +“参数服务”在服务器端为指定用户持久化存储和管理个性化参数,例如 控制台的配置,列表的colume配置等,从而实现产品的个性化配置。 +*/ + +import ( + "yunion.io/x/yunionconf/pkg/yunionconf/service" +) + +func main() { + service.StartService() +} diff --git a/pkg/yunionconf/handlers.go b/pkg/yunionconf/handlers.go new file mode 100644 index 0000000000..8144733a66 --- /dev/null +++ b/pkg/yunionconf/handlers.go @@ -0,0 +1,20 @@ +package yunionconf + +import ( + "yunion.io/x/onecloud/pkg/appsrv" + "yunion.io/x/onecloud/pkg/appsrv/dispatcher" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/yunionconf/models" +) + +func InitHandlers(app *appsrv.Application) { + for _, manager := range []db.IModelManager{ + models.ParameterManager, + } { + db.RegisterModelManager(manager) + handler := db.NewModelHandler(manager) + dispatcher.AddModelDispatcher("", app, handler) + dispatcher.AddModelDispatcher("/users/", app, handler) + dispatcher.AddModelDispatcher("/services/", app, handler) + } +} diff --git a/pkg/yunionconf/models/initdb.go b/pkg/yunionconf/models/initdb.go new file mode 100644 index 0000000000..29e63b6006 --- /dev/null +++ b/pkg/yunionconf/models/initdb.go @@ -0,0 +1,19 @@ +package models + +import ( + "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon/db" +) + +func InitDB() error { + for _, manager := range []db.IModelManager{ + ParameterManager, + } { + err := manager.InitializeData() + if err != nil { + log.Errorf("Manager %s initializeData fail %s", manager.Keyword(), err) + return err + } + } + return nil +} \ No newline at end of file diff --git a/pkg/yunionconf/models/parameters.go b/pkg/yunionconf/models/parameters.go new file mode 100644 index 0000000000..fe8bd3a1d3 --- /dev/null +++ b/pkg/yunionconf/models/parameters.go @@ -0,0 +1,214 @@ +package models + +import ( + "context" + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/pkg/util/timeutils" + "yunion.io/x/pkg/utils" + "yunion.io/x/sqlchemy" +) + +const ( + NAMESPACE_USER = "user" + NAMESPACE_SERVICE = "service" +) + +type SParameterManager struct { + db.SResourceBaseManager +} + +type SParameter struct { + db.SResourceBase + + Id int64 `primary:"true" auto_increment:"true" list:"user"` // = Column(BigInteger, primary_key=True) + CreatedBy string `width:"128" charset:"ascii" nullable:"false" create:"required" list:"user"` // Column(VARCHAR(length=128, charset='ascii'), nullable=False) + UpdatedBy string `width:"128" charset:"ascii" nullable:"false" create:"required" update:"user" list:"user"` // Column(VARCHAR(length=128, charset='ascii'), nullable=False) "user"/ serviceName/ "admin" + Namespace string `width:"64" charset:"ascii" default:"user" nullable:"false" create:"required" list:"admin"` // Column(VARCHAR(length=128, charset='ascii'), nullable=False) user_id / serviceid + NamespaceId string `width:"128" charset:"ascii" nullable:"false" index:"true" create:"required" list:"admin"` // Column(VARCHAR(length=128, charset='ascii'), nullable=False) + Name string `width:"128" charset:"ascii" nullable:"false" index:"true" create:"required" list:"user"` // Column(VARCHAR(length=128, charset='ascii'), nullable=false) + Value string `charset:"utf8" create:"required" update:"user" update:"user" list:"user"` // Column(VARCHAR(charset='utf-8')) +} + +var ParameterManager *SParameterManager + +func init() { + ParameterManager = &SParameterManager{SResourceBaseManager: db.NewResourceBaseManager(SParameter{}, "paramters_tbl", "parameter", "parameters")} +} + +func isAdminQuery(query jsonutils.JSONObject) bool { + admin_fields := [3]string{"namespace_id", "user_id", "service_id"} + + for _, field := range admin_fields { + if s, _ := query.GetString(field); len(s) > 0 { + return true + } + } + + return false +} + +func getNamespaceInContext(userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (namespace string, namespaceId string, err error) { + // 优先匹配上线文中的参数, /users//parameters /services//parameters + if uid, _ := query.GetString("user_id"); len(uid) > 0 { + return NAMESPACE_USER, uid, nil + } else if sid, _ := query.GetString("service_id"); len(sid) > 0 { + return NAMESPACE_SERVICE, sid, nil + } + + // 匹配/parameters中的参数 + if uid, _ := data.GetString("user_id"); len(uid) > 0 { + return NAMESPACE_USER, uid, nil + } else if sid, _ := data.GetString("service_id"); len(sid) > 0 { + return NAMESPACE_SERVICE, sid, nil + } else { + return NAMESPACE_USER, userCred.GetUserId(), nil + } +} + +func getNamespace(userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (string, string, error) { + var namespace, namespace_id string + if userCred.IsSystemAdmin() { + if name, nameId, e := getNamespaceInContext(userCred, query, data); e != nil { + return "", "", e + } else { + namespace = name + namespace_id = nameId + } + } else { + namespace = NAMESPACE_USER + namespace_id = userCred.GetUserId() + } + + return namespace, namespace_id, nil +} + +func (manager *SParameterManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool { + if !isAdminQuery(query) { + return true + } + + return userCred.IsSystemAdmin() +} + +func (manager *SParameterManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + if !isAdminQuery(query) { + return true + } + + return userCred.IsSystemAdmin() +} + +func (manager *SParameterManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + // check duplication + name, _ := data.GetString("name") + uid := userCred.GetUserId() + if len(uid) < 0 { + return nil, httperrors.NewUserNotFoundError("user not found") + } + + namespace, namespace_id, e := getNamespace(userCred, query, data) + if e != nil { + return nil, e + } + + // check duplication, 同一个namespace下,name不能 重复 + q := manager.Query().Equals("name", name).Equals("namespace_id", namespace_id) + if q.Count() > 0 { + return nil, httperrors.NewDuplicateNameError("paramter %s has been created", name) + } + + data.Add(jsonutils.NewString(uid), "created_by") + data.Add(jsonutils.NewString(uid), "updated_by") + data.Add(jsonutils.NewString(namespace), "namespace") + data.Add(jsonutils.NewString(namespace_id), "namespace_id") + return data, nil +} + +func (manager *SParameterManager) GetOwnerId(userCred mcclient.TokenCredential) string { + return userCred.GetUserId() +} + +func (manager *SParameterManager) FilterByOwner(q *sqlchemy.SQuery, owner string) *sqlchemy.SQuery { + return q.Equals("created_by", owner) +} + +func (manager *SParameterManager) FilterById(q *sqlchemy.SQuery, idStr string) *sqlchemy.SQuery { + return q.Equals("name", idStr) +} + +func (manager *SParameterManager) FilterByName(q *sqlchemy.SQuery, name string) *sqlchemy.SQuery { + return q.Equals("name", name) +} + +func (manager *SParameterManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) { + if userCred.IsSystemAdmin() { + if id, _ := query.GetString("namespace_id"); len(id) > 0 { + q = q.Equals("namespace_id", id) + } else if id, _ := query.GetString("service_id"); len(id) > 0 { + q = q.Equals("namespace_id", id).Equals("namespace", NAMESPACE_SERVICE) + } else if id, _ := query.GetString("user_id"); len(id) > 0 { + q = q.Equals("namespace_id", id).Equals("namespace", NAMESPACE_USER) + } else { + // not admin + admin, _ := query.GetString("admin") + if !utils.ToBool(admin) { + q = q.Equals("namespace_id", userCred.GetUserId()).Equals("namespace", NAMESPACE_USER) + } + } + + return q, nil + } + return q.Equals("namespace_id", userCred.GetUserId()).Equals("namespace", NAMESPACE_USER), nil +} + +func (model *SParameter) IsOwner(userCred mcclient.TokenCredential) bool { + return model.CreatedBy == userCred.GetUserId() || (model.NamespaceId == userCred.GetUserId() && model.Namespace == NAMESPACE_USER) +} + +func (model *SParameter) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool { + return model.IsOwner(userCred) || userCred.IsSystemAdmin() +} + +func (model *SParameter) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + uid := userCred.GetUserId() + if len(uid) < 0 { + return nil, httperrors.NewUserNotFoundError("user not found") + } + + namespace, namespace_id, e := getNamespace(userCred, query, data) + if e != nil { + return nil, e + } + data.Add(jsonutils.NewString(uid), "updated_by") + data.Add(jsonutils.NewString(namespace_id), "namespace_id") + data.Add(jsonutils.NewString(namespace), "namespace") + return data, nil +} + +func (model *SParameter) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return model.IsOwner(userCred) || userCred.IsSystemAdmin() +} + +func (model *SParameter) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + return model.Delete(ctx, userCred) +} + +func (model *SParameter) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { + _, err := model.GetModelManager().TableSpec().Update(model, func() error { + model.Deleted = true + model.DeletedAt = timeutils.UtcNow() + return nil + }) + if err != nil { + log.Errorf("PendingDelete fail %s", err) + } + return err +} + +func (model *SParameter) AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool { + return model.IsOwner(userCred) || userCred.IsSystemAdmin() +} diff --git a/pkg/yunionconf/options/options.go b/pkg/yunionconf/options/options.go new file mode 100644 index 0000000000..edf1773e82 --- /dev/null +++ b/pkg/yunionconf/options/options.go @@ -0,0 +1,11 @@ +package options + +import "yunion.io/x/onecloud/pkg/cloudcommon" + +type YunionConfOptions struct { + cloudcommon.DBOptions +} + +var ( + Options YunionConfOptions +) \ No newline at end of file diff --git a/pkg/yunionconf/service/service.go b/pkg/yunionconf/service/service.go new file mode 100644 index 0000000000..d31ed89133 --- /dev/null +++ b/pkg/yunionconf/service/service.go @@ -0,0 +1,38 @@ +package service + +import ( + "os" + + _ "github.com/go-sql-driver/mysql" + + "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/yunionconf" + "yunion.io/x/onecloud/pkg/yunionconf/models" + "yunion.io/x/onecloud/pkg/yunionconf/options" +) + +func StartService() { + cloudcommon.ParseOptions(&options.Options, &options.Options.Options, os.Args, "yunionconf.conf") + cloudcommon.InitAuth(&options.Options.Options, nil) + + if options.Options.GlobalVirtualResourceNamespace { + db.EnableGlobalVirtualResourceNamespace() + } + + cloudcommon.InitDB(&options.Options.DBOptions) + defer cloudcommon.CloseDB() + + app := cloudcommon.InitApp(&options.Options.Options) + yunionconf.InitHandlers(app) + + if db.CheckSync(options.Options.AutoSyncTable) { + err := models.InitDB() + if err == nil { + cloudcommon.ServeForever(app, &options.Options.Options) + } else { + log.Errorf("InitDB fail: %s", err) + } + } +} \ No newline at end of file From d4ab9d8b69d366f60e78ab4232624e7c5c47917a Mon Sep 17 00:00:00 2001 From: TangBin Date: Thu, 13 Sep 2018 14:35:35 +0800 Subject: [PATCH 8/9] bugfix import path error --- cmd/yunionconf/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/yunionconf/main.go b/cmd/yunionconf/main.go index 138cd057ab..df2baf86b8 100644 --- a/cmd/yunionconf/main.go +++ b/cmd/yunionconf/main.go @@ -6,7 +6,7 @@ Yunion Conf Service */ import ( - "yunion.io/x/yunionconf/pkg/yunionconf/service" + "yunion.io/x/onecloud/pkg/yunionconf/service" ) func main() { From 96713696b82ebe866f7d91c867d051325d04deea Mon Sep 17 00:00:00 2001 From: TangBin Date: Thu, 13 Sep 2018 14:59:10 +0800 Subject: [PATCH 9/9] add auth complete callback --- pkg/yunionconf/service/service.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/yunionconf/service/service.go b/pkg/yunionconf/service/service.go index d31ed89133..a83c89a6d5 100644 --- a/pkg/yunionconf/service/service.go +++ b/pkg/yunionconf/service/service.go @@ -15,7 +15,9 @@ import ( func StartService() { cloudcommon.ParseOptions(&options.Options, &options.Options.Options, os.Args, "yunionconf.conf") - cloudcommon.InitAuth(&options.Options.Options, nil) + cloudcommon.InitAuth(&options.Options.Options, func() { + log.Infof("Auth complete!!") + }) if options.Options.GlobalVirtualResourceNamespace { db.EnableGlobalVirtualResourceNamespace()