Exemple #1
0
func (cmd *Upload) request_file(filename string) (err error) {

	// アップロードするファイルへのReaderを作成
	file, err := os.OpenFile(filename, os.O_RDONLY, 0600)
	if err != nil {
		return err
	}

	// アップロード先のURIを準備
	uri, err := buildStorageUrl(cmd.config.EndPointUrl, cmd.destContainer, filename)
	if err != nil {
		return err
	}

	// PUTリクエストを作成
	req, err := http.NewRequest("PUT", uri.String(), file)
	if err != nil {
		return err
	}

	contentType := cmd.detectContentType(filename)
	req.Header.Set("Content-type", contentType)
	req.Header.Set("X-Auth-Token", cmd.config.Token)

	// リクエストを実行
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}

	switch {
	case resp.StatusCode == 404:
		return errors.New("Container was not found.")

	case resp.StatusCode >= 400:
		msg := fmt.Sprintf("Return %d status code from the server with message. [%s].",
			resp.StatusCode,
			extractErrorMessage(resp.Body),
		)
		return errors.New(msg)
	}

	log := lib.GetLogInstance()
	log.Infof("%s (content-type: %s) was uploaded.", filename, contentType)

	return nil
}
Exemple #2
0
func (cmd *Download) DownloadObjects(srcpath string, destpath string) error {
	log := lib.GetLogInstance()

	// 対象の情報を取得
	s := NewCommand("stat", cmd.config, cmd.stdStream, cmd.errStream).(*Stat)
	item, err := s.Stat(srcpath)
	if err != nil {
		return err
	}

	_, isContainer := item.(*Container)

	if isContainer {
		// オブジェクトの一覧を取得
		l := NewCommand("list", cmd.config, cmd.stdStream, cmd.errStream).(*List)
		list, err := l.List(srcpath)
		if err != nil {
			return err
		}

		for i := 0; i < len(list); i++ {
			cmd.DownloadObjects(srcpath+"/"+list[i], destpath)
		}

	} else {

		log.Debugf("Downloading %s => %s", srcpath, destpath)

		u, err := buildStorageUrl(cmd.config.EndPointUrl, srcpath)
		if err != nil {
			return err
		}

		err = cmd.request(u, destpath)
		if err != nil {
			log.Infof("%s download error.", srcpath)
			return err
		}
		log.Infof("%s download complete.", srcpath)
	}

	return nil
}
Exemple #3
0
func (cmd *Upload) request_dir(dirname string) (err error) {

	// アップロード先のURIを準備
	uri, err := buildStorageUrl(cmd.config.EndPointUrl, cmd.destContainer, dirname)
	if err != nil {
		return err
	}

	// PUTリクエストを作成
	req, err := http.NewRequest("PUT", uri.String(), nil)
	if err != nil {
		return err
	}

	req.Header.Set("Content-type", "application/directory")
	req.Header.Set("X-Auth-Token", cmd.config.Token)

	// リクエストを実行
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}

	switch {
	case resp.StatusCode == 404:
		return errors.New("Container was not found.")

	case resp.StatusCode >= 400:
		msg := fmt.Sprintf("Return %d status code from the server with message. [%s].",
			resp.StatusCode,
			extractErrorMessage(resp.Body),
		)
		return errors.New(msg)
	}

	log := lib.GetLogInstance()
	log.Infof("%s directory was created.", dirname)

	return nil
}
Exemple #4
0
// 引数で渡された文字列を解決して、オブジェクトストレージのURIを返す
func buildStorageUrl(endpointUrl string, paths ...string) (url *url.URL, err error) {
	log := lib.GetLogInstance()

	// オブジェクトストレージのURIを構築する
	rawurl := endpointUrl

	// EndPointUrl の末尾のスラッシュを削除
	if strings.HasSuffix(rawurl, "/") {
		rawurl = rawurl[0 : len(rawurl)-1]
	}

	// パスを連結する先頭のスラッシュを補完
	for i := 0; i < len(paths); i++ {
		paths[i] = strings.Trim(paths[i], "/")
	}

	rawurl += "/" + strings.Join(paths, "/")

	log.Debug(rawurl)

	return url.Parse(rawurl)
}
Exemple #5
0
// トークンの有効期限のチェックを行う
// 有効期限内の場合は何もしない
// 有効期限切れの場合は再取得を行う
func (cmd *Auth) CheckTokenIsExpired(c *lib.Config) error {
	log := lib.GetLogInstance()

	// configでユーザ名などが空の場合は先に認証(authコマンド)を実行してくださいと返す
	if c.ApiUsername == "" || c.ApiPassword == "" || c.TenantId == "" {
		err := errors.New("ApiUsername, Apipassword and TenantID was not found in a config file. You should execute an auth command. (See \"conoha-ojs auth\").")
		return err
	}

	// 以下をすべて満たす場合はキャッシュ済みのトークンを使うため、処理をスキップする
	// * トークンが取得済みである(空文字でない)
	// * エンドポイントURLが取得できている(空文字でない)
	// * トークンの有効期限内である
	doUpdate := false

	if c.Token == "" || c.EndPointUrl == "" {
		doUpdate = true
	}

	now := time.Now().UTC()
	te, err := time.Parse(time.RFC1123, c.TokenExpires)

	if err != nil || now.After(te) {
		doUpdate = true
	}

	if !doUpdate {
		log.Debug("Using the cached token.")
		return nil
	}

	// 認証URLの指定がない場合はデフォルトを使用
	if cmd.authUrl == "" {
		cmd.authUrl = DEFAULT_AUTH_URL
	}

	return cmd.request(c, c.ApiUsername, c.ApiPassword, c.TenantId)
}
Exemple #6
0
func (cmd *Delete) Delete(path string) error {
	log := lib.GetLogInstance()

	// 対象の情報を取得
	s := NewCommand("stat", cmd.config, cmd.stdStream, cmd.errStream).(*Stat)
	item, err := s.Stat(path)
	if err != nil {
		return err
	}

	_, isContainer := item.(*Container)

	if isContainer {
		// 配下のオブジェクト一覧を取得
		l := NewCommand("list", cmd.config, cmd.stdStream, cmd.errStream).(*List)
		list, err := l.List(path)
		if err != nil {
			return err
		}

		for i := 0; i < len(list); i++ {
			cmd.Delete(path + "/" + list[i])
		}
	}

	u, err := buildStorageUrl(cmd.config.EndPointUrl, path)
	if err != nil {
		return err
	}

	err = cmd.request(u)
	if err != nil {
		return err
	}
	log.Infof("%s was deleted.", path)

	return nil
}
Exemple #7
0
// 引数のhttp.Requestに、メタデータ、ReadACL, WriteACLのヘッダ情報を追加する
func (cmd *Post) addHeaders(req *http.Request, item Item) {

	log := lib.GetLogInstance()
	_, isContainer := item.(*Container)

	// メタデータをセット
	for name, value := range cmd.metadatas {
		var header = "X-"

		// valueが空の場合はメタデータの削除
		if value == "" {
			header += "Remove-"
		}

		// コンテナの場合とオブジェクトの場合でヘッダ名が違う
		if isContainer {
			header += "Container-Meta-"
		} else {
			header += "Object-Meta-"
		}

		header += name
		req.Header.Add(header, value)

		log.Debugf("Set meta data: %s=%s", header, value)
	}

	// Read-ACLとWrite-ACL
	if isContainer && cmd.readAcl != "_no_assign_" {
		req.Header.Add("X-Container-Read", cmd.readAcl)
		log.Debugf("Set Read ACL: %s", cmd.readAcl)
	}

	if isContainer && cmd.writeAcl != "_no_assign_" {
		req.Header.Add("X-Container-Write", cmd.writeAcl)
		log.Debugf("Set Write ACL: %s", cmd.readAcl)
	}
}
Exemple #8
0
func run() (exitCode int, err error) {
	// log
	log := lib.GetLogInstance()

	// 実行するコマンド
	var cmd command.Commander

	// 出力先
	stdStream := os.Stdout
	errStream := os.Stderr

	// 設定を読み込む
	config := lib.NewConfig()

	// コマンドを実行
	if len(os.Args) <= 1 {
		// コマンドが未指定の場合は使用法を表示
		cmd = command.NewCommand("nocommand", config, stdStream, errStream)
		return cmd.Run()
	}

	command_name := os.Args[1]

	log.Debugf("Command: \"%v\"", command_name)

	if command_name == "auth" {
		// 認証情報を更新(コマンドライン引数から認証情報を設定する)
		auth := command.NewCommand("auth", config, stdStream, errStream)
		exitCode, err = auth.Run()
		if err != nil {
			return exitCode, err
		}

	} else if command_name == "deauth" {
		// 認証情報を削除
		deauth := command.NewCommand("deauth", config, stdStream, errStream)
		exitCode, err = deauth.Run()
		if err != nil {
			return exitCode, err
		}

	} else if command_name == "version" {
		// バージョン表示
		v := command.NewCommand("version", config, stdStream, errStream)
		exitCode, err = v.Run()
		if err != nil {
			return exitCode, err
		}

	} else {
		// 認証情報を更新
		auth := command.NewCommand("auth", config, stdStream, errStream).(*command.Auth)
		if err = auth.CheckTokenIsExpired(config); err != nil {
			return 1, err
		}

		// コマンドを実行
		cmd := command.NewCommand(command_name, config, stdStream, errStream)

		code, err := cmd.Run()
		if err != nil {
			return code, err
		}
	}

	return command.ExitCodeOK, nil
}