Unverified Commit 4430246f authored by ambition's avatar ambition Committed by GitHub
Browse files

1. BCS_APISERVER新增协议限制 (#1926)

2. client连接serve新增http
2. 新增鉴权
parent d7b230cd
Showing with 441 additions and 139 deletions
+441 -139
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 edit
import (
"github.com/spf13/cobra"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
var (
editLong = templates.LongDesc(i18n.T(`
Edit a resource from the default editor.
The edit command allows you to directly edit any API resource you can retrieve via the
command-line tools. It will open the editor 'vi' for Linux or 'notepad' for Windows.`))
editExample = templates.Examples(i18n.T(`
# Edit a project or project variable
kubectl-bcs-project-manager edit project/variable`))
)
func NewCmdEdit() *cobra.Command {
cmd := &cobra.Command{
Use: "edit",
Short: i18n.T("Edit a resource on the server"),
Long: editLong,
Example: editExample,
}
// edit subcommands
cmd.AddCommand(editProject())
return cmd
}
......@@ -11,7 +11,7 @@
*
*/
package cmd
package edit
import (
"bytes"
......@@ -26,74 +26,41 @@ import (
"k8s.io/klog"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/cmd/util/editor"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
"sigs.k8s.io/yaml"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/cmd/printer"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/pkg"
"github.com/Tencent/bk-bcs/bcs-services/bcs-project-manager/proto/bcsproject"
)
func newUpdateCmd() *cobra.Command {
editCmd := &cobra.Command{
Use: "edit",
Short: "edit project from bcs-project-manager",
Long: "edit project from bcs-project-manager",
}
editCmd.AddCommand(updateProject())
return editCmd
}
var (
editProjectLong = templates.LongDesc(i18n.T(`
Edit a project from the default editor.`))
//定义不能编辑的参数
type readOnlyParam struct {
CreateTime string `json:"createTime"`
UpdateTime string `json:"updateTime"`
Creator string `json:"creator"`
Updater string `json:"updater"`
Managers string `json:"managers"`
ProjectID string `json:"projectID"`
Name string `json:"name"`
ProjectCode string `json:"projectCode"`
UseBKRes bool `json:"useBKRes"`
IsOffline bool `json:"isOffline"`
Kind string `json:"kind"`
IsSecret bool `json:"isSecret"`
ProjectType uint32 `json:"projectType"`
DeployType uint32 `json:"deployType"`
BGID string `json:"BGID"`
BGName string `json:"BGName"`
DeptID string `json:"deptID"`
DeptName string `json:"deptName"`
CenterID string `json:"centerID"`
CenterName string `json:"centerName"`
BusinessID string `json:"businessID"`
Description string `json:"description"`
}
editProjectExample = templates.Examples(i18n.T(`
# Edit project by PROJECT_ID or PROJECT_CODE
kubectl-bcs-project-manager edit project PROJECT_ID/PROJECT_CODE`))
)
func updateProject() *cobra.Command {
subCmd := &cobra.Command{
func editProject() *cobra.Command {
cmd := &cobra.Command{
Use: "project (ID/CODE)",
DisableFlagsInUseLine: true,
Short: "",
Long: "edit infos from bcs-project-manager",
Short: i18n.T("Edit project by ID or CODE"),
Long: editProjectLong,
Example: editProjectExample,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
klog.Fatalf("edit project requires project ID or code")
}
ctx, cancel := context.WithCancel(context.Background())
client, cliCtx, err := pkg.NewClientWithConfiguration(ctx)
if err != nil {
klog.Fatalf("init client failed: %v", err.Error())
}
defer cancel()
// 先获取当前项目
getProjectResp, err := client.GetProject(cliCtx, &bcsproject.GetProjectRequest{ProjectIDOrCode: args[0]})
client := pkg.NewClientWithConfiguration(context.Background())
resp, err := client.GetProject(args[0])
if err != nil {
klog.Fatalf("get project failed: %v", err)
}
if getProjectResp != nil && getProjectResp.Code != 0 {
klog.Fatal("get project response code not 0 but %d: %s", getProjectResp.Code, getProjectResp.Message)
}
projectInfo := getProjectResp.Data
projectInfo := resp.Data
// 原内容
marshal, err := json.Marshal(projectInfo)
if err != nil {
......@@ -125,8 +92,8 @@ func updateProject() *cobra.Command {
}
var (
editBefore readOnlyParam
editAfter readOnlyParam
editBefore pkg.UpdateProjectRequest
editAfter pkg.UpdateProjectRequest
)
{
......@@ -156,38 +123,32 @@ func updateProject() *cobra.Command {
isSecret.Value = projectInfo.GetIsSecret()
// 保证只修改描述和业务ID
updateData := &bcsproject.UpdateProjectRequest{
ProjectID: projectInfo.GetProjectID(),
Name: projectInfo.GetName(),
UseBKRes: useBKRes,
Description: editBefore.Description,
IsOffline: isOffline,
Kind: projectInfo.GetKind(),
BusinessID: editBefore.BusinessID,
IsSecret: isSecret,
DeployType: projectInfo.GetDeployType(),
ProjectType: projectInfo.GetProjectType(),
updateData := &pkg.UpdateProjectRequest{
BGID: projectInfo.GetBGID(),
BGName: projectInfo.GetBGName(),
DeptID: projectInfo.GetDeptID(),
DeptName: projectInfo.GetDeptName(),
BusinessID: editBefore.BusinessID,
CenterID: projectInfo.GetCenterID(),
CenterName: projectInfo.GetCenterName(),
CreateTime: projectInfo.GetCreateTime(),
Creator: projectInfo.GetCreator(),
DeptID: projectInfo.GetDeptID(),
DeptName: projectInfo.GetDeptName(),
Description: editBefore.Description,
IsSecret: projectInfo.GetIsSecret(),
Kind: projectInfo.GetKind(),
Managers: projectInfo.GetManagers(),
Name: projectInfo.GetName(),
ProjectCode: projectInfo.GetProjectCode(),
ProjectID: projectInfo.GetProjectID(),
UpdateTime: projectInfo.GetUpdateTime(),
}
updateProjectResp, err := client.UpdateProject(cliCtx, updateData)
updateProjectResp, err := client.UpdateProject(updateData)
if err != nil {
klog.Fatalf("update project failed: %v", err)
}
if updateProjectResp != nil && updateProjectResp.Code != 0 {
klog.Fatal("update project response code not 0 but %d: %s", updateProjectResp.Code, updateProjectResp.Message)
}
printer.PrintUpdateProjectInJSON(updateProjectResp)
printer.PrintInJSON(updateProjectResp)
},
}
return subCmd
}
func getProjectInfo() {
return cmd
}
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 get
import (
"github.com/spf13/cobra"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
var (
flagOutput string
getLong = templates.LongDesc(i18n.T(`
Display one or many from bcs-project-manager.
Prints a table of the most important information about the specified resources.`))
getExample = templates.Examples(i18n.T(`
# List all project in ps output format
kubectl-bcs-project-manager list project
# List all project variable in ps output format
kubectl-bcs-project-manager list variable`))
)
func NewCmdGet() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: i18n.T("List infos from bcs-project-manager"),
Long: getLong,
Example: getExample,
}
cmd.PersistentFlags().StringVarP(&flagOutput, "output", "o", "wide",
"optional parameter: json/wide, json will print the json string to stdout")
// get subcommands
cmd.AddCommand(listProject())
return cmd
}
......@@ -11,69 +11,61 @@
*
*/
package cmd
package get
import (
"context"
"github.com/spf13/cobra"
"k8s.io/klog"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/cmd/printer"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/pkg"
"github.com/Tencent/bk-bcs/bcs-services/bcs-project-manager/proto/bcsproject"
)
func newListCmd() *cobra.Command {
listCmd := &cobra.Command{
Use: "list",
Short: "list infos from bcs-project-manager",
Long: "list infos from bcs-project-manager",
}
listCmd.AddCommand(listProject())
return listCmd
}
var (
getProjectLong = templates.LongDesc(i18n.T(`
Display one or many project.
Prints a table of the most important information about the specified resources.`))
getProjectExample = templates.Examples(i18n.T(`
# List all project in ps output format
kubectl-bcs-project-manager list project`))
)
func listProject() *cobra.Command {
var all bool
request := new(bcsproject.ListProjectsRequest)
subCmd := &cobra.Command{
request := new(pkg.ListProjectsRequest)
cmd := &cobra.Command{
Use: "project",
Aliases: []string{"project", "p"},
Short: "",
Long: "list projects info with full-data or paging support",
Short: i18n.T("Display one or many project"),
Long: getProjectLong,
Example: getProjectExample,
Run: func(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
client, cliCtx, err := pkg.NewClientWithConfiguration(ctx)
resp, err := pkg.NewClientWithConfiguration(context.Background()).ListProjects(request)
if err != nil {
klog.Fatalf("init client failed: %v", err.Error())
}
request.SearchName = request.Names
resp, err := client.ListProjects(cliCtx, request)
if err != nil {
klog.Fatalf("list projects failed: %v", err)
}
if resp != nil && resp.Code != 0 {
klog.Fatal("list projects response code not 0 but %d: %s", resp.Code, resp.Message)
klog.Fatalf("list variable definitions failed: %v", err)
}
printer.PrintProjectsListInTable(flagOutput, resp)
},
}
subCmd.PersistentFlags().StringVarP(&request.ProjectIDs, "project_ids", "", "",
"the project ids that query, multiple separated by commas")
subCmd.PersistentFlags().StringVarP(&request.Names, "name", "", "",
"the project chinese name, multiple separated by commas")
subCmd.PersistentFlags().StringVarP(&request.ProjectCode, "project_code", "", "",
"project code query")
subCmd.PersistentFlags().StringVarP(&request.Kind, "kind", "", "",
"the cluster kind")
subCmd.PersistentFlags().Int64VarP(&request.Limit, "limit", "", 10,
"number of queries")
subCmd.PersistentFlags().Int64VarP(&request.Offset, "offset", "", 0,
"start query from offset")
subCmd.PersistentFlags().BoolVarP(&all, "all", "", false,
"get all projects, default: false")
return subCmd
cmd.PersistentFlags().StringVarP(&request.ProjectIDs, "project_ids", "", "",
"The project ids that query, multiple separated by commas")
cmd.PersistentFlags().StringVarP(&request.SearchName, "name", "", "",
"The project chinese name, multiple separated by commas")
cmd.PersistentFlags().StringVarP(&request.ProjectCode, "project_code", "", "",
"Project code query")
cmd.PersistentFlags().StringVarP(&request.Kind, "kind", "", "",
"The cluster kind")
cmd.PersistentFlags().Int64VarP(&request.Limit, "limit", "", 10,
"Number of queries")
cmd.PersistentFlags().Int64VarP(&request.Offset, "offset", "", 0,
"Start query from offset")
cmd.PersistentFlags().BoolVarP(&all, "all", "", false,
"Get all projects, default: false")
return cmd
}
......@@ -59,13 +59,52 @@ func PrintProjectsListInTable(flagOutput string, resp *bcsproject.ListProjectsRe
tw.Render()
}
// PrintUpdateProjectInJSON prints the response that edit project
func PrintUpdateProjectInJSON(project *bcsproject.ProjectResponse) {
if project == nil {
// PrintProjectVariablesListInTable prints the response that list projects variables definitions
func PrintProjectVariablesListInTable(flagOutput string, resp *bcsproject.ListVariableDefinitionsResponse) {
if flagOutput == outputTypeJSON {
if err := encodeJSON(resp); err != nil {
klog.Fatalf("list projects output json to stdout failed: %s", err.Error())
}
}
tw := tablewriter.NewWriter(os.Stdout)
tw.SetHeader(func() []string {
return []string{
"ID", "KEY", "NAME", "DEFAULT", "DEFAULT_VALUE", "SCOPE", "SCOPE_NAME", "CATEGORY", "CATEGORY_NAME", "CREATOR", "UPDATER", "CREATE", "UPDATE",
}
}())
// 添加页脚
tw.SetFooter([]string{"", "", "", "", "", "", "", "", "", "", "", "Total", strconv.Itoa(int(resp.Data.Total))})
// 合并相同值的列
//tw.SetAutoMergeCells(true)
for _, item := range resp.Data.Results {
tw.Append(func() []string {
return []string{
item.GetId(),
item.GetKey(),
item.GetName(),
item.GetDefault(),
item.GetDefaultValue(),
item.GetScope(),
item.GetScopeName(),
item.GetCategory(),
item.GetCategoryName(),
item.GetCreator(),
item.GetUpdater(),
item.GetCreated(),
item.GetUpdated(),
}
}())
}
tw.Render()
}
// PrintInJSON prints the response
func PrintInJSON(response interface{}) {
if response == nil {
return
}
var data []byte
_ = encodeJSONWithIndent(4, project, &data)
_ = encodeJSONWithIndent(4, response, &data)
fmt.Println(string(pretty.Color(pretty.Pretty(data), nil)))
}
......@@ -16,22 +16,20 @@ package cmd
import (
"fmt"
"log"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/klog"
"github.com/Tencent/bk-bcs/bcs-common/common/version"
)
const (
defaultCfgFile = "/etc/bcs/bcs-project-manager.yaml"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/cmd/edit"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/cmd/get"
)
var (
cfgFile string
flagOutput string
rootCmd = &cobra.Command{
cfgFile string
rootCmd = &cobra.Command{
Use: "kubectl-bcs-project-manager",
Short: "kubectl-bcs-project-manager used to operate bcs-project-manager service",
Long: `
......@@ -48,12 +46,11 @@ func Execute() {
}
func ensureConfig() {
if cfgFile == "" {
cfgFile = defaultCfgFile
}
viper.SetConfigFile(cfgFile)
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
err := viper.ReadInConfig()
if cfgFile != "" && err != nil {
klog.Fatalf("read config from '%s' failed,err: %s", cfgFile, err.Error())
}
}
......@@ -68,10 +65,8 @@ func init() {
fmt.Println(version.GetVersion())
},
})
rootCmd.AddCommand(newListCmd())
rootCmd.AddCommand(newUpdateCmd())
rootCmd.AddCommand(get.NewCmdGet())
rootCmd.AddCommand(edit.NewCmdEdit())
rootCmd.PersistentFlags().StringVarP(
&cfgFile, "config", "c", defaultCfgFile, "config file")
rootCmd.PersistentFlags().StringVarP(&flagOutput, "output", "o", "wide",
"optional parameter: json/wide, json will print the json string to stdout")
&cfgFile, "config", "c", "", "config file, optional")
}
......@@ -10,9 +10,11 @@ replace (
)
require (
github.com/Tencent/bk-bcs/bcs-common v0.0.0-20220913140949-31c175590547
github.com/Tencent/bk-bcs/bcs-services/bcs-project-manager v0.0.0-20221011125034-2ada1f2db5ed
github.com/Tencent/bk-bcs/bcs-common v0.0.0-20221018081229-065aeef813e6
github.com/Tencent/bk-bcs/bcs-services/bcs-project-manager v0.0.0-20221025135217-b2f1313129c4
github.com/ghodss/yaml v1.0.0
github.com/golang/protobuf v1.5.2
github.com/google/go-querystring v1.0.0
github.com/olekukonko/tablewriter v0.0.5
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.6.0
......@@ -20,7 +22,6 @@ require (
github.com/stretchr/testify v1.8.0
github.com/tidwall/pretty v1.2.1
github.com/ugorji/go/codec v1.2.7
google.golang.org/grpc v1.47.0
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.80.1
k8s.io/kubectl v0.24.7
......@@ -95,7 +96,8 @@ require (
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
google.golang.org/protobuf v1.28.0 // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
......
......@@ -13,7 +13,9 @@
package main
import "github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/cmd"
import (
"github.com/Tencent/bk-bcs/bcs-services/bcs-cli/bcs-project-manager/cmd"
)
func main() {
cmd.Execute()
......
......@@ -14,17 +14,16 @@
package pkg
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"github.com/pkg/errors"
"github.com/spf13/viper"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
"github.com/Tencent/bk-bcs/bcs-services/bcs-project-manager/proto/bcsproject"
)
// Config describe the options Client need
......@@ -37,35 +36,64 @@ type Config struct {
Operator string
}
type ProjectManagerClient struct {
cfg *Config
ctx context.Context
}
// NewClientWithConfiguration new client with config
func NewClientWithConfiguration(ctx context.Context) (bcsproject.BCSProjectClient, context.Context, error) {
return NewBcsProjectCli(ctx, &Config{
APIServer: viper.GetString("API_SERVER"),
AuthToken: viper.GetString("BCS_TOKEN"),
Operator: viper.GetString("OPERATOR"),
})
func NewClientWithConfiguration(ctx context.Context) *ProjectManagerClient {
return &ProjectManagerClient{
ctx: ctx,
cfg: &Config{
APIServer: viper.GetString("bcs.apiserver"),
AuthToken: viper.GetString("bcs.token"),
Operator: viper.GetString("bcs.operator"),
},
}
}
// NewBcsProjectCli create client for bcs-project
func NewBcsProjectCli(ctx context.Context, config *Config) (bcsproject.BCSProjectClient, context.Context, error) {
header := map[string]string{
"x-content-type": "application/grpc+proto",
"Content-Type": "application/grpc",
func (p *ProjectManagerClient) do(urls string, httpType string, query url.Values, body interface{}) ([]byte, error) {
urls = p.cfg.APIServer + urls
var req *http.Request
var err error
_, err = url.Parse(p.cfg.APIServer)
if err != nil {
return nil, fmt.Errorf("url failed %v", err)
}
if body != nil {
var bs []byte
bs, err = json.Marshal(body)
if err != nil {
return nil, errors.Wrapf(err, "marshal body failed")
}
req, err = http.NewRequestWithContext(p.ctx, httpType, urls, bytes.NewReader(bs))
} else {
req, err = http.NewRequestWithContext(p.ctx, httpType, urls, nil)
}
if len(config.AuthToken) != 0 {
header["Authorization"] = fmt.Sprintf("Bearer %s", config.AuthToken)
// 添加鉴权
if len(p.cfg.AuthToken) != 0 {
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", p.cfg.AuthToken))
}
if err != nil {
return nil, errors.Wrapf(err, "create request failed")
}
if query != nil {
req.URL.RawQuery = query.Encode()
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, errors.Wrapf(err, "http do request failed")
}
md := metadata.New(header)
var opts []grpc.DialOption
opts = append(opts, grpc.WithDefaultCallOptions(grpc.Header(&md)))
opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})))
var conn *grpc.ClientConn
conn, err := grpc.Dial(config.APIServer, opts...)
defer resp.Body.Close()
bs, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, nil, errors.Wrapf(err, "create grpc client with '%s' failed", config.APIServer)
return nil, errors.Wrapf(err, "read response body failed")
}
if conn == nil {
return nil, nil, fmt.Errorf("conn is nil")
if resp.StatusCode != http.StatusOK {
return nil, errors.Wrapf(errors.Errorf(string(bs)), "http response status not 200 but %d",
resp.StatusCode)
}
return bcsproject.NewBCSProjectClient(conn), metadata.NewOutgoingContext(ctx, md), nil
return bs, nil
}
......@@ -18,19 +18,15 @@ import (
"log"
"testing"
"github.com/Tencent/bk-bcs/bcs-services/bcs-project-manager/proto/bcsproject"
"github.com/stretchr/testify/assert"
)
func Test_GeProjectList(t *testing.T) {
client, _, err := NewBcsProjectCli(context.Background(), &Config{
APIServer: "",
AuthToken: "",
})
resp, err := NewClientWithConfiguration(context.Background()).GetProject("7da12ea6af35464a8be39961a21e95d9")
if err != nil {
log.Fatal(err)
}
rsp, err := client.ListProjects(context.Background(), &bcsproject.ListProjectsRequest{})
assert.Nil(t, err)
assert.NotNil(t, rsp)
assert.NotNil(t, resp)
}
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 pkg
import (
"encoding/json"
"fmt"
"net/http"
"github.com/Tencent/bk-bcs/bcs-services/bcs-project-manager/proto/bcsproject"
"github.com/google/go-querystring/query"
"github.com/pkg/errors"
)
const (
listProjectsUrl = "/bcsproject/v1/projects"
getProjectUrl = "/bcsproject/v1/projects/%s"
updateProjectUrl = "/bcsproject/v1/projects/%s"
)
type (
ListProjectsRequest struct {
ProjectIDs string `url:"projectIDs,omitempty"`
ProjectCode string `url:"projectCode,omitempty"`
SearchName string `url:"searchName,omitempty"`
Kind string `url:"kind,omitempty"`
Offset int64 `url:"offset,omitempty"`
Limit int64 `url:"limit,omitempty"`
All bool `url:"all,omitempty"`
}
UpdateProjectRequest struct {
BGID string `json:"BGID"`
BGName string `json:"BGName"`
BusinessID string `json:"businessID"`
CenterID string `json:"centerID"`
CenterName string `json:"centerName"`
CreateTime string `json:"createTime"`
Creator string `json:"creator"`
DeptID string `json:"deptID"`
DeptName string `json:"deptName"`
Description string `json:"description"`
IsSecret bool `json:"isSecret"`
Kind string `json:"kind"`
Managers string `json:"managers"`
Name string `json:"name"`
ProjectCode string `json:"projectCode"`
ProjectID string `json:"projectID"`
UpdateTime string `json:"updateTime"`
}
)
// ListProjects Get a list of projects based on a condition
func (p *ProjectManagerClient) ListProjects(in *ListProjectsRequest) (*bcsproject.ListProjectsResponse, error) {
v, err := query.Values(in)
if err != nil {
return nil, fmt.Errorf("slice and Array values default to encoding as multiple URL values failed: %v", err)
}
bs, err := p.do(listProjectsUrl, http.MethodGet, v, nil)
if err != nil {
return nil, fmt.Errorf("list projects failed: %v", err)
}
resp := new(bcsproject.ListProjectsResponse)
if err := json.Unmarshal(bs, resp); err != nil {
return nil, errors.Wrapf(err, "list projects unmarshal failed with response '%s'", string(bs))
}
if resp != nil && resp.Code != 0 {
return nil, fmt.Errorf("list projects response code not 0 but %d: %s", resp.Code, resp.Message)
}
return resp, nil
}
// GetProject Get project information based on project ID or CODE
func (p *ProjectManagerClient) GetProject(projectIDOrCode string) (*bcsproject.ProjectResponse, error) {
bs, err := p.do(fmt.Sprintf(getProjectUrl, projectIDOrCode), http.MethodGet, nil, nil)
if err != nil {
return nil, errors.Wrapf(err, "get project with '%s' failed", projectIDOrCode)
}
resp := new(bcsproject.ProjectResponse)
if err := json.Unmarshal(bs, resp); err != nil {
return nil, errors.Wrapf(err, "get project unmarshal failed with response '%s'", string(bs))
}
if resp != nil && resp.Code != 0 {
return nil, fmt.Errorf("get project response code not 0 but %d: %s", resp.Code, resp.Message)
}
return resp, nil
}
func (p *ProjectManagerClient) UpdateProject(in *UpdateProjectRequest) (*bcsproject.ProjectResponse, error) {
bs, err := p.do(fmt.Sprintf(updateProjectUrl, in.ProjectID), http.MethodPut, nil, in)
if err != nil {
return nil, fmt.Errorf("update project failed: %v", err)
}
resp := new(bcsproject.ProjectResponse)
if err := json.Unmarshal(bs, resp); err != nil {
return nil, errors.Wrapf(err, "update project unmarshal failed with response '%s'", string(bs))
}
if resp != nil && resp.Code != 0 {
return nil, fmt.Errorf("update project response code not 0 but %d: %s", resp.Code, resp.Message)
}
return resp, nil
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment