func Logout(login bool, args []string) error { f := mflag.NewFlagSet("logout", mflag.ContinueOnError) f.Usage = logoutUsage if err := f.Parse(args); err != nil { return err } if len(args) >= 1 { fmt.Println(ErrMsgArgument) logoutUsage() return errors.New(ErrMsgArgument) } resp, err := commToDaemon("get", "/users/logout", nil) if err != nil { fmt.Println("Error :", err) return err } if resp.StatusCode == http.StatusUnauthorized { fmt.Println("DataHub : You already logout.") } if resp.StatusCode == http.StatusOK { fmt.Println("DataHub : logout success.") } return nil }
func DpRm(needLogin bool, args []string) (err error) { f := mflag.NewFlagSet("dp rm", mflag.ContinueOnError) f.Usage = dprUseage if err = f.Parse(args); err != nil { return err } if len(args) > 0 && args[0][0] != '-' { for _, v := range args { dp := v if v[0] != '-' { resp, err := commToDaemon("DELETE", "/datapools/"+dp, nil) if err != nil { fmt.Println(err) return err } if resp.StatusCode == http.StatusOK { showResponse(resp) } else { showError(resp) } resp.Body.Close() } } } if len(args) == 0 { fmt.Println("please write the dpname which you want to delete") } return nil }
func Dp(needLogin bool, args []string) (err error) { if needLogin && !Logged { login(false) } f := mflag.NewFlagSet("dp", mflag.ContinueOnError) f.Usage = dpUsage if err = f.Parse(args); err != nil { return err } if len(args) == 0 { resp, err := commToDaemon("GET", "/datapools?size=-1", nil) if err != nil { fmt.Println(err) return err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } if resp.StatusCode == http.StatusOK { dpResp(false, body) } else { fmt.Println(resp.StatusCode, string(body)) err = errors.New(string(resp.StatusCode)) } } else { //support: dp name1 name2 name3 for _, v := range args { if len(v) > 0 && v[0] != '-' { if strings.Contains(v, "/") == true { fmt.Printf("DataHub : The name of datapool can't contain '/': \"%v\"\n", v) return } strdp := fmt.Sprintf("/datapools/%s", v) resp, err := commToDaemon("GET", strdp, nil) if err != nil { fmt.Println(err) return err } if resp.StatusCode == http.StatusOK { body, _ := ioutil.ReadAll(resp.Body) dpResp(true, body) } else { showError(resp) err = errors.New(string(resp.StatusCode)) } resp.Body.Close() } } } return err }
func DpCreate(needLogin bool, args []string) (err error) { f := mflag.NewFlagSet("dp create", mflag.ContinueOnError) d := FormatDpCreate{} f.StringVar(&d.Type, []string{"-type", "t"}, "file", "datapool type") f.StringVar(&d.Conn, []string{"-conn"}, "", "datapool connection info") if len(args) > 0 && args[0][0] != '-' { d.Name = args[0] args = args[1:] } if len(args) == 0 { d.Conn = GstrDpPath d.Type = "file" //fmt.Printf("missing argument.\nSee '%s --help'.\n", f.Name()) //return } if err = f.Parse(args); err != nil { fmt.Println("parse parameter error") return } if len(f.Args()) > 0 { fmt.Printf("invalid argument.\nSee '%s --help'.\n", f.Name()) return } dptype := strings.ToLower(d.Type) if dptype != "file" && dptype != "db" && dptype != "hadoop" && dptype != "api" && dptype != "storm" { fmt.Println("Datapool type need to be :file,db,hadoop,api,storm") return } jsonData, err := json.Marshal(d) if err != nil { return err } if needLogin && !Logged { login(false) } resp, err := commToDaemon("POST", "/datapools", jsonData) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) ShowMsgResp(body, true) return err }
func JobRm(needLogin bool, args []string) (err error) { f := mflag.NewFlagSet("datahub job rm", mflag.ContinueOnError) //fForce := f.Bool([]string{"-force", "f"}, false, "force cancel a pulling job.") fRmAll := f.Bool([]string{"-all", "a"}, false, "rm all the jobs.") path := "/job" if len(args) > 0 && len(args[0]) > 0 && args[0][0] != '-' { path += "/" + args[0] } else if len(args) == 0 { fmt.Println(ErrMsgArgument) jobUsage() return errors.New("Invalid arguments.") } //if len(args) > 0 && len(args[0]) > 0 { if err := f.Parse(args); err != nil { return err } //if *fForce { // path += "?opt=force" //} //} if (path == "/job") && (*fRmAll == false) { fmt.Println(ErrMsgArgument) jobUsage() return errors.New("Invalid arguments.") } resp, err := commToDaemon("DELETE", path, nil) if err != nil { fmt.Println(err) } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { showResponse(resp) } else { showError(resp) } //mt.Println(resp.Header) return err }
func Subs(login bool, args []string) (err error) { f := mflag.NewFlagSet("subs", mflag.ContinueOnError) f.Usage = subsUsage if err = f.Parse(args); err != nil { return err } itemDetail := false var uri string if len(args) == 0 { uri = "/subscriptions/dataitems?phase=1" err = cmdSubsRepo(itemDetail, uri, args) } else if len(args) == 1 { if false == strings.Contains(args[0], "/") { uri = "/subscriptions/dataitems?phase=1&repname=" + args[0] err = cmdSubsRepo(itemDetail, uri, args) } else { repo, item, err := GetRepoItem(args[0]) if err != nil { fmt.Println(ErrMsgArgument) subsUsage() return err } //fmt.Println(repo, item) sub, err := itemSubsOrNot(repo, item) if sub == true && err == nil { uri = "/repositories/" + args[0] itemDetail = true return Repo(login, args) //deal repo/item:tag by repo cmd } } } else { fmt.Println(ErrMsgArgument) subsUsage() return } return err }
func Pull(login bool, args []string) (err error) { var repo, item string dstruc := ds.DsPull{} f := mflag.NewFlagSet("pull", mflag.ContinueOnError) f.StringVar(&dstruc.DestName, []string{"-destname", "d"}, "", "Indicates the name that tag will be stored as ") pbAutomatic := f.Bool([]string{"-automatic", "a"}, false, "Pull the new tags of a dataitem automatically") pbCancelAutomatic := f.Bool([]string{"-cancel", "c"}, false, "Cancel the automatical pulling of a dataitem") if len(args) < 2 || (len(args) >= 2 && (args[0][0] == '-' || args[1][0] == '-')) { //fmt.Println(ErrMsgArgument) pullUsage() return } f.Usage = pullUsage if err = f.Parse(args[2:]); err != nil { fmt.Println(err) return err } u, err := url.Parse(args[0]) if err != nil { fmt.Println(err) return } dstruc.Automatic = *pbAutomatic dstruc.CancelAutomatic = *pbCancelAutomatic source := strings.Trim(u.Path, "/") if url := strings.Split(source, "/"); len(url) != 2 { fmt.Println(ErrMsgArgument) pullUsage() return } else { target := strings.Split(url[1], ":") if len(target) == 1 { target = append(target, "latest") } else if len(target[1]) == 0 { target[1] = "latest" } //uri = fmt.Sprintf("%s/%s:%s", url[0], target[0], target[1]) repo = url[0] item = target[0] dstruc.Tag = target[1] if len(dstruc.DestName) == 0 { dstruc.DestName = dstruc.Tag } } //get datapool and itemdesc if store := strings.Split(strings.Trim(args[1], "/"), "://"); len(store) == 1 { dstruc.Datapool = store[0] dstruc.ItemDesc = repo + "_" + item } else if len(store) == 2 { dstruc.Datapool = store[0] dstruc.ItemDesc = strings.Trim(store[1], "/") if len(dstruc.Datapool) == 0 { fmt.Println("Datahub : DATAPOOL://LOCATION are required!") pullUsage() return } if len(dstruc.ItemDesc) == 0 { dstruc.ItemDesc = repo + "_" + item } } else { fmt.Println("Error : DATAPOOL://LOCATION format error!") pullUsage() return } jsonData, err := json.Marshal(dstruc) if err != nil { fmt.Println("Error") return } resp, err := commToDaemon("post", "/subscriptions/"+repo+"/"+item+"/pull", jsonData) if err != nil { fmt.Println(err) os.Exit(2) } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { //body, _ := ioutil.ReadAll(resp.Body) //ShowMsgResp(body, true) showResponse(resp) } else if resp.StatusCode == http.StatusUnauthorized { if err := Login(false, nil); err == nil { return Pull(login, args) } else { fmt.Println(err) return err } } else { result := ds.Response{} respbody, _ := ioutil.ReadAll(resp.Body) //fmt.Println(string(respbody)) unmarshalerr := json.Unmarshal(respbody, &result) if unmarshalerr != nil { fmt.Println("Error : Pull error.", unmarshalerr) return unmarshalerr } if result.Code == ServerErrResultCode5009 { fmt.Println("DataHub : Failed to get subscription") } else if result.Code == ServerErrResultCode5012 { fmt.Println("DataHub : Permission denied,you have not subscribed current dataitem yet.") } else if result.Code == ServerErrResultCode5023 { fmt.Println("DataHub : Currently the data is unavaliable.") } else { //showError(resp) fmt.Println("Error : ", result.Msg) } } //showError(resp) return nil }
func Login(login bool, args []string) (err error) { f := mflag.NewFlagSet("datahub login", mflag.ContinueOnError) f.Usage = loginUsage if err := f.Parse(args); err != nil { //fmt.Println(err) return err } if len(args) == 0 { fmt.Println("Please login") loginUsage() return errors.New(ErrMsgArgument) } var prefix string if p, ok := ServerPrefix[args[0]]; ok { prefix = p } else { fmt.Println(ErrMsgArgument) loginUsage() return errors.New(ErrMsgArgument) } fmt.Printf("login as: ") reader := bufio.NewReader(os.Stdin) //loginName, _ := reader.ReadString('\n') loginName, _ := reader.ReadBytes('\n') loginName = append([]byte(prefix), bytes.TrimRight(loginName, "\r\n")...) fmt.Printf("password: "******"[%s]:[%s]\n", string(loginName), string(pass)) User.userName = string(loginName) //User.password = string(pass) User.password = fmt.Sprintf("%x", md5.Sum(pass)) User.b64 = base64.StdEncoding.EncodeToString([]byte(User.userName + ":" + User.password)) //fmt.Printf("%s\n%s:%s\n", User.b64, User.userName, User.password) //req.Header.Set("Authorization", "Basic "+os.Getenv("DAEMON_USER_AUTH_INFO")) userJson := UserForJson{Username: User.userName} jsondata, _ := json.Marshal(userJson) resp, err := commToDaemon("get", "/users/auth", jsondata) //users/auth if err != nil { fmt.Println(err) return err } defer resp.Body.Close() //fmt.Println("login return", resp.StatusCode) if resp.StatusCode == http.StatusOK { Logged = true if login { fmt.Println("DataHub : login success.") } return } else if resp.StatusCode == http.StatusForbidden { result := &ds.Result{} objloginerr := &Loginerr{} result.Data = objloginerr body, _ := ioutil.ReadAll(resp.Body) if err = json.Unmarshal(body, result); err != nil { fmt.Println("Error :", err) return err } else { retrytimes, _ := strconv.Atoi(objloginerr.Retrytimes) leftchance := 5 - retrytimes switch leftchance { case 0: fmt.Printf("%s\nno chance left.\n", result.Msg) case 1: fmt.Printf("%s\n1 chance left.\n", result.Msg) default: fmt.Printf("%s\n%v chances left.\n", result.Msg, leftchance) } fmt.Println(ErrLoginFailed) return errors.New(ErrLoginFailed) } } else { fmt.Println(ErrLoginFailed) if /*resp.StatusCode == 401 &&*/ login { body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) } return errors.New(ErrLoginFailed) } /* body, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode != 200 { //fmt.Println(resp.StatusCode, ShowMsgResp(body, false)) fmt.Println(resp.StatusCode) } if resp.StatusCode == 401 { return fmt.Errorf(string(body)) } return fmt.Errorf("ERROR %d: login failed.", resp.StatusCode) */ }
func Job(needLogin bool, args []string) (err error) { f := mflag.NewFlagSet("datahub job", mflag.ContinueOnError) fListall := f.Bool([]string{"-all", "a"}, false, "list all jobs") f.Usage = jobUsage if len(args) > 0 { if args[0][0] != '-' { path := "/job" if len(args[0]) > 0 { path += "/" + args[0] } else { if err := f.Parse(args); err != nil { return err } //if *fListall { // path += "?opt=all" //} } resp, err := commToDaemon("GET", path, nil) if err != nil { fmt.Println(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { showError(resp) } else { //body, _ := ioutil.ReadAll(resp.Body) //fmt.Println(string(body)) jobResp(resp) } //if *fForce { // path += "?opt=force" //} //} } else { path := "/job?all=1" if err := f.Parse(args); err != nil { return err } if *fListall == false { fmt.Println(ErrMsgArgument) jobUsage() return errors.New("Invalid arguments.") } resp, err := commToDaemon("GET", path, nil) if err != nil { fmt.Println(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { showError(resp) } else { //body, _ := ioutil.ReadAll(resp.Body) //fmt.Println(string(body)) jobResp(resp) } } } else { path := "/job" resp, err := commToDaemon("GET", path, nil) if err != nil { fmt.Println(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { showError(resp) } else { //body, _ := ioutil.ReadAll(resp.Body) //fmt.Println(string(body)) jobResp(resp) } } return err }
func Repo(login bool, args []string) (err error) { f := mflag.NewFlagSet("repo", mflag.ContinueOnError) f.Usage = repoUsage if err = f.Parse(args); err != nil { return err } var icmd int if len(args) > 1 { fmt.Println("DataHub : Invalid argument.") repoUsage() return } var repo, item, tag, uri string if len(args) == 0 { uri = "/repositories" icmd = Repos } else { u, err := url.Parse(args[0]) if err != nil { fmt.Println("Error :", err) return err } source := u.Path if (len(u.Path) > 0) && (u.Path[0] == '/') { source = u.Path[1:] } //fmt.Println(source) urls := strings.Split(source, "/") lenth := len(urls) if lenth == 0 { uri = "/repositories" icmd = Repos //fmt.Println(uri, icmd) } else if lenth == 1 || (lenth == 2 && len(urls[1]) == 0) { uri = "/repositories/" + urls[0] icmd = ReposReponame repo = urls[0] //fmt.Println(uri, icmd) } else if lenth == 2 || (lenth == 3 && len(urls[2]) == 0) { target := strings.Split(urls[1], ":") tarlen := len(target) if tarlen == 1 || (tarlen == 2 && len(target[1]) == 0) { uri = "/repositories/" + urls[0] + "/" + target[0] icmd = ReposReponameDataItem repo = urls[0] item = target[0] //fmt.Println(uri, icmd) } else if tarlen == 2 { uri = "/repositories/" + urls[0] + "/" + target[0] + "/" + target[1] icmd = ReposReponameDataItemTag repo = urls[0] item = target[0] tag = target[1] //fmt.Println(uri, icmd) } else { fmt.Println("Error : The parameter after repo is in wrong format!") return errors.New("The parameter after repo is in wrong format!") } } else { fmt.Println("Error : The parameter after repo is in wrong format!") return errors.New("The parameter after repo is in wrong format!") } } resp, err := commToDaemon("get", uri, nil) if err != nil { fmt.Println(err) return err } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { body, _ := ioutil.ReadAll(resp.Body) repoResp(icmd, body, repo, item, tag) } else if resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusBadRequest { if resp.StatusCode == http.StatusUnauthorized { fmt.Println("Error : Not login.") return err } //05.04.2016 The PM receive 401 while testing, but I don't know why. body, _ := ioutil.ReadAll(resp.Body) result := ds.Result{} err = json.Unmarshal(body, &result) if err != nil { fmt.Println("Error : http StatusCode:", resp.StatusCode, "Json format error!") return err } if result.Code == ServerErrResultCode1400 { if err = Login(false, nil); err == nil { err = Repo(login, args) } else { //fmt.Println(err) } } else { fmt.Printf("Error : %v\n", result.Msg) return nil } //fmt.Println(resp.StatusCode, "returned....") } else { showError(resp) } return err }
func Pub(needlogin bool, args []string) (err error) { //fmt.Println(args) //return if len(args) < 2 { //fmt.Println(ErrMsgArgument) pubUsage() return errors.New("args len error!") } pub := ds.PubPara{} //var largs []string = args var repo, item, tag, argfi, argse string f := mflag.NewFlagSet("datahub pub", mflag.ContinueOnError) //f.StringVar(&pub.Datapool, []string{"-datapool", "p"}, "", "datapool name") f.StringVar(&pub.Accesstype, []string{"-accesstype", "t"}, "private", "dataitem accesstype: private or public") f.StringVar(&pub.Comment, []string{"-comment", "m"}, "", "comments") //f.StringVar(&pub.Detail, []string{"-detail", "d"}, "", "tag detail ,for example file name") f.StringVar(&pub.SupplyStyle, []string{"-supplystyle", "s"}, "batch", "dataitem supplystyle: batch , flow or api") f.StringVar(&pub.Ch_itemname, []string{"-chinese", "ch"}, "", "dataitem's Chinese name") f.Usage = pubUsage if len(args) > 2 { if err = f.Parse(args[2:]); err != nil { fmt.Println("Error : parse parameter error.", err) return err } } //if pub.Ch_itemname == "" { // fmt.Println("DataHub: Dataitem's Chinese name cannot be empty.") // pubUsage() // return //} if len(args[0]) == 0 || len(args[1]) == 0 { fmt.Println(ErrMsgArgument) pubUsage() return errors.New("need item or tag error!") } argfi = strings.Trim(args[0], "/") //deal arg[0] sp := strings.Split(argfi, "/") if len(sp) != 2 { fmt.Println(ErrMsgArgument) pubUsage() return errors.New("invalid repo/item") } repo = sp[0] sptag := strings.Split(sp[1], ":") l := len(sptag) if l == 1 { item = sptag[0] argse = strings.Trim(args[1], "/") se := strings.Split(argse, "://") if len(se) == 2 && len(se[1]) > 0 { pub.Datapool = se[0] pub.ItemDesc = strings.Trim(se[1], "/") err = PubItem(repo, item, pub, args) } else { fmt.Println("DataHub : Please input a valid datapool and path.") err = errors.New("Error : Please input a valid datapool and path.") } } else if l == 2 { item = sptag[0] tag = sptag[1] pub.Detail = args[1] if len(args) == 2 || (len(args) == 3 && strings.Contains(args[2], "-")) { PubTag(repo, item, tag, pub, args) } else { if len(strings.Split(args[2], ":")) != 2 || strings.Split(args[2], ":")[0] == "" { fmt.Printf("DataHub : Invalid argument.\nSee '%s --help'.\n", f.Name()) return } datapool := strings.Split(args[2], ":")[0] pub.Datapool = datapool if len(strings.Split(strings.Split(args[2], ":")[1], "//")) != 2 || strings.Split(strings.Split(args[2], ":")[1], "//")[1] == "" { fmt.Printf("DataHub : Invalid argument.\nSee '%s --help'.\n", f.Name()) return } itemDesc := strings.Split(strings.Split(args[2], ":")[1], "//")[1] pub.ItemDesc = itemDesc PubTag(repo, item, tag, pub, args) } } else { fmt.Printf("DataHub : Invalid argument.\nSee '%s --help'.\n", f.Name()) return errors.New("Invalid argument.") } return err }
func DpCreate(needLogin bool, args []string) (err error) { f := mflag.NewFlagSet("datahub dp create", mflag.ContinueOnError) d := FormatDpCreate{} //f.StringVar(&d.Type, []string{"-type", "t"}, "file", "datapool type") //f.StringVar(&d.Conn, []string{"-conn", "c"}, "", "datapool connection info") f.Usage = dpcUseage //--help if err = f.Parse(args); err != nil { return err } if len(args) == 1 { if strings.Contains(args[0], "/") == true { fmt.Println("DataHub : The name of datapool can't contain '/'.") return } fmt.Print("DataHub : Are you sure to create a datapool ", " with default type 'file' and path \"/var/lib/datahub\" ?\n[Y or N]:") if GetEnsure() == true { d.Name = args[0] d.Conn = GstrDpPath d.Type = "file" } else { return } } else { if len(args) != 2 || len(args[0]) == 0 { fmt.Printf("DataHub : Invalid argument.\nSee '%s --help'.\n", f.Name()) return } if strings.Contains(args[0], "/") == true { fmt.Println("DataHub : The name of datapool can't contain '/'.") return } d.Name = args[0] sp := strings.Split(args[1], "://") if len(sp) > 1 && len(sp[1]) > 0 { d.Type = strings.ToLower(sp[0]) if sp[1][0] != '/' && d.Type == "file" { fmt.Println("DataHub : Please input absolute path after 'file://', e.g. file:///home/user/mydp") return } if d.Type == "file" { d.Conn = "/" + strings.Trim(sp[1], "/") } else if d.Type == "s3" { //d.Conn = strings.Trim(sp[1], "/") d.Conn = sp[1] } else if d.Type == "hdfs" { d.Conn = sp[1] if validateDpconn(d.Conn, d.Type) == false { return } } } else if len(sp) == 1 && len(sp[0]) != 0 { d.Type = "file" if sp[0][0] != '/' { fmt.Printf("DataHub : Please input path for '%s'.\n", args[0]) return } d.Conn = "/" + strings.Trim(sp[0], "/") } else { fmt.Printf("Error : Invalid argument.\nSee '%s --help'.\n", f.Name()) return } } var allowtype bool = false for _, v := range DataPoolTypes { if d.Type == v { allowtype = true } } if !allowtype { fmt.Println("DataHub : Datapool type need to be:", DataPoolTypes) return } jsonData, err := json.Marshal(d) if err != nil { return err } resp, err := commToDaemon("POST", "/datapools", jsonData) if err != nil { fmt.Println(err) return err } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { showResponse(resp) } else { showError(resp) } return err }
func ItemOrTagRm(needLogin bool, args []string) error { f := mflag.NewFlagSet("repo rm", mflag.ContinueOnError) f.Usage = itemortagrmUsage if err := f.Parse(args); err != nil { return err } if len(args) == 0 || len(args) > 1 { fmt.Println(ErrMsgArgument) itemortagrmUsage() return errors.New(ErrMsgArgument) } arg := args[0] if validateArgs(arg) == false { fmt.Println(ValidateErrMsgArgument) itemortagrmUsage() return errors.New(ValidateErrMsgArgument) } var repository string var dataitem string var tag string splitStr := strings.Split(arg, ":") if len(splitStr) == 1 { splitStr2 := strings.Split(splitStr[0], "/") if len(splitStr2) != 2 { fmt.Println(ValidateErrMsgArgument) itemortagrmUsage() return errors.New(ValidateErrMsgArgument) } repository = splitStr2[0] dataitem = splitStr2[1] uri := "/repositories/" + repository + "/" + dataitem resp, err := commToDaemon("DELETE", uri, nil) if err != nil { fmt.Println("Error :", err) return err } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { body, _ := ioutil.ReadAll(resp.Body) result := ds.Result{} if err := json.Unmarshal(body, &result); err != nil { fmt.Println("Error :", err) return err } ensureRmItem(result.Code, uri, result.Msg) } else if resp.StatusCode == http.StatusUnauthorized { if err = Login(false, nil); err == nil { err = ItemOrTagRm(needLogin, args) } else { fmt.Println("Error :", err) } } else { showError(resp) } return err } else if len(splitStr) == 2 { if splitStr[1] == "" { fmt.Println(ValidateErrMsgArgument) itemortagrmUsage() return errors.New(ValidateErrMsgArgument) } splitStr2 := strings.Split(splitStr[0], "/") repository = splitStr2[0] dataitem = splitStr2[1] tag = splitStr[1] uri := "/repositories/" + repository + "/" + dataitem + "/" + tag + "/judge" resp, err := commToDaemon("GET", uri, nil) if err != nil { fmt.Println("Error :", err) return err } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) result := ds.Result{} if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusBadRequest { if err := json.Unmarshal(body, &result); err != nil { fmt.Println("Error :", err) return err } ensureRmTag(resp.StatusCode, result.Code, result.Msg, repository, dataitem, tag) } else if resp.StatusCode == http.StatusUnauthorized { if err = Login(false, nil); err == nil { err = ItemOrTagRm(needLogin, args) } else { //fmt.Println(err) } } else { showError(resp) } } else { fmt.Println(ValidateErrMsgArgument) itemortagrmUsage() return errors.New(ValidateErrMsgArgument) } return nil }