• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Golang names.ParseUserTag函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Golang中github.com/juju/names.ParseUserTag函数的典型用法代码示例。如果您正苦于以下问题:Golang ParseUserTag函数的具体用法?Golang ParseUserTag怎么用?Golang ParseUserTag使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了ParseUserTag函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。

示例1: AddUser

// AddUser creates a new local user in the juju server.
func (c *Client) AddUser(username, displayName, password string) (names.UserTag, error) {
	if !names.IsValidUser(username) {
		return names.UserTag{}, fmt.Errorf("invalid user name %q", username)
	}
	userArgs := params.AddUsers{
		Users: []params.AddUser{{Username: username, DisplayName: displayName, Password: password}},
	}
	var results params.AddUserResults
	err := c.facade.FacadeCall("AddUser", userArgs, &results)
	if err != nil {
		return names.UserTag{}, errors.Trace(err)
	}
	if count := len(results.Results); count != 1 {
		logger.Errorf("expected 1 result, got %#v", results)
		return names.UserTag{}, errors.Errorf("expected 1 result, got %d", count)
	}
	result := results.Results[0]
	if result.Error != nil {
		return names.UserTag{}, errors.Trace(result.Error)
	}
	tag, err := names.ParseUserTag(result.Tag)
	if err != nil {
		return names.UserTag{}, errors.Trace(err)
	}
	logger.Infof("created user %s", result.Tag)
	return tag, nil
}
开发者ID:imoapps,项目名称:juju,代码行数:28,代码来源:client.go


示例2: ListModels

// ListModels returns the models that the specified user
// has access to in the current server.  Only that controller owner
// can list models for any user (at this stage).  Other users
// can only ask about their own models.
func (c *Client) ListModels(user string) ([]base.UserModel, error) {
	var models params.UserModelList
	if !names.IsValidUser(user) {
		return nil, errors.Errorf("invalid user name %q", user)
	}
	entity := params.Entity{names.NewUserTag(user).String()}
	err := c.facade.FacadeCall("ListModels", entity, &models)
	if err != nil {
		return nil, errors.Trace(err)
	}
	result := make([]base.UserModel, len(models.UserModels))
	for i, model := range models.UserModels {
		owner, err := names.ParseUserTag(model.OwnerTag)
		if err != nil {
			return nil, errors.Annotatef(err, "OwnerTag %q at position %d", model.OwnerTag, i)
		}
		result[i] = base.UserModel{
			Name:           model.Name,
			UUID:           model.UUID,
			Owner:          owner.Canonical(),
			LastConnection: model.LastConnection,
		}
	}
	return result, nil
}
开发者ID:exekias,项目名称:juju,代码行数:29,代码来源:modelmanager.go


示例3: UserInfo

// UserInfo returns information on a user.
func (api *UserManagerAPI) UserInfo(args params.Entities) (UserInfoResults, error) {
	results := UserInfoResults{
		Results: make([]UserInfoResult, len(args.Entities)),
	}

	for i, userArg := range args.Entities {
		tag, err := names.ParseUserTag(userArg.Tag)
		if err != nil {
			results.Results[0].Error = common.ServerError(err)
			continue
		}
		user, err := api.state.User(tag)
		var result UserInfoResult
		if err != nil {
			if errors.IsNotFound(err) {
				result.Error = common.ServerError(common.ErrPerm)
			} else {
				result.Error = common.ServerError(err)
			}
		} else {
			info := UserInfo{
				Username:       tag.Name(),
				DisplayName:    user.DisplayName(),
				CreatedBy:      user.CreatedBy(),
				DateCreated:    user.DateCreated(),
				LastConnection: user.LastLogin(),
			}
			result.Result = &info
		}
		results.Results[i] = result
	}

	return results, nil
}
开发者ID:zhouqt,项目名称:juju,代码行数:35,代码来源:usermanager.go


示例4: ListEnvironments

// ListEnvironments returns the environments that the specified user
// has access to in the current server.  Only that state server owner
// can list environments for any user (at this stage).  Other users
// can only ask about their own environments.
func (c *Client) ListEnvironments(user string) ([]base.UserEnvironment, error) {
	var environments params.UserEnvironmentList
	if !names.IsValidUser(user) {
		return nil, errors.Errorf("invalid user name %q", user)
	}
	entity := params.Entity{names.NewUserTag(user).String()}
	err := c.facade.FacadeCall("ListEnvironments", entity, &environments)
	if err != nil {
		return nil, errors.Trace(err)
	}
	result := make([]base.UserEnvironment, len(environments.UserEnvironments))
	for i, env := range environments.UserEnvironments {
		owner, err := names.ParseUserTag(env.OwnerTag)
		if err != nil {
			return nil, errors.Annotatef(err, "OwnerTag %q at position %d", env.OwnerTag, i)
		}
		result[i] = base.UserEnvironment{
			Name:           env.Name,
			UUID:           env.UUID,
			Owner:          owner.Username(),
			LastConnection: env.LastConnection,
		}
	}
	return result, nil
}
开发者ID:claudiu-coblis,项目名称:juju,代码行数:29,代码来源:environmentmanager.go


示例5: ListEnvironments

// ListEnvironments returns the environments that the specified user
// has access to in the current server.  Only that state server owner
// can list environments for any user (at this stage).  Other users
// can only ask about their own environments.
func (em *EnvironmentManagerAPI) ListEnvironments(user params.Entity) (params.EnvironmentList, error) {
	result := params.EnvironmentList{}

	stateServerEnv, err := em.state.StateServerEnvironment()
	if err != nil {
		return result, errors.Trace(err)
	}
	adminUser := stateServerEnv.Owner()

	userTag, err := names.ParseUserTag(user.Tag)
	if err != nil {
		return result, errors.Trace(err)
	}

	err = em.authCheck(userTag, adminUser)
	if err != nil {
		return result, errors.Trace(err)
	}

	environments, err := em.state.EnvironmentsForUser(userTag)
	if err != nil {
		return result, errors.Trace(err)
	}

	for _, env := range environments {
		result.Environments = append(result.Environments, params.Environment{
			Name:     env.Name(),
			UUID:     env.UUID(),
			OwnerTag: env.Owner().String(),
		})
		logger.Debugf("list env: %s, %s, %s", env.Name(), env.UUID(), env.Owner())
	}

	return result, nil
}
开发者ID:Pankov404,项目名称:juju,代码行数:39,代码来源:environmentmanager.go


示例6: EnvironmentStatus

// EnvironmentStatus returns a status summary for each environment tag passed in.
func (c *Client) EnvironmentStatus(tags ...names.EnvironTag) ([]base.EnvironmentStatus, error) {
	result := params.EnvironmentStatusResults{}
	envs := make([]params.Entity, len(tags))
	for i, tag := range tags {
		envs[i] = params.Entity{Tag: tag.String()}
	}
	req := params.Entities{
		Entities: envs,
	}
	if err := c.facade.FacadeCall("EnvironmentStatus", req, &result); err != nil {
		return nil, err
	}

	results := make([]base.EnvironmentStatus, len(result.Results))
	for i, r := range result.Results {
		env, err := names.ParseEnvironTag(r.EnvironTag)
		if err != nil {
			return nil, errors.Annotatef(err, "EnvironTag %q at position %d", r.EnvironTag, i)
		}
		owner, err := names.ParseUserTag(r.OwnerTag)
		if err != nil {
			return nil, errors.Annotatef(err, "OwnerTag %q at position %d", r.OwnerTag, i)
		}

		results[i] = base.EnvironmentStatus{
			UUID:               env.Id(),
			Life:               r.Life,
			Owner:              owner.Canonical(),
			HostedMachineCount: r.HostedMachineCount,
			ServiceCount:       r.ServiceCount,
		}

	}
	return results, nil
}
开发者ID:imoapps,项目名称:juju,代码行数:36,代码来源:controller.go


示例7: authenticate

// authenticate parses HTTP basic authentication and authorizes the
// request by looking up the provided tag and password against state.
func (h *httpHandler) authenticate(r *http.Request) error {
	parts := strings.Fields(r.Header.Get("Authorization"))
	if len(parts) != 2 || parts[0] != "Basic" {
		// Invalid header format or no header provided.
		return fmt.Errorf("invalid request format")
	}
	// Challenge is a base64-encoded "tag:pass" string.
	// See RFC 2617, Section 2.
	challenge, err := base64.StdEncoding.DecodeString(parts[1])
	if err != nil {
		return fmt.Errorf("invalid request format")
	}
	tagPass := strings.SplitN(string(challenge), ":", 2)
	if len(tagPass) != 2 {
		return fmt.Errorf("invalid request format")
	}
	// Only allow users, not agents.
	if _, err := names.ParseUserTag(tagPass[0]); err != nil {
		return common.ErrBadCreds
	}
	// Ensure the credentials are correct.
	_, err = checkCreds(h.state, params.Creds{
		AuthTag:  tagPass[0],
		Password: tagPass[1],
	})
	return err
}
开发者ID:klyachin,项目名称:juju,代码行数:29,代码来源:httphandler.go


示例8: ModifyModelAccess

// ModifyModelAccess changes the model access granted to users.
func (m *ModelManagerAPI) ModifyModelAccess(args params.ModifyModelAccessRequest) (result params.ErrorResults, err error) {
	result = params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.Changes)),
	}
	if len(args.Changes) == 0 {
		return result, nil
	}

	for i, arg := range args.Changes {
		modelAccess, err := FromModelAccessParam(arg.Access)
		if err != nil {
			err = errors.Annotate(err, "could not modify model access")
			result.Results[i].Error = common.ServerError(err)
			continue
		}

		targetUserTag, err := names.ParseUserTag(arg.UserTag)
		if err != nil {
			result.Results[i].Error = common.ServerError(errors.Annotate(err, "could not modify model access"))
			continue
		}
		modelTag, err := names.ParseModelTag(arg.ModelTag)
		if err != nil {
			result.Results[i].Error = common.ServerError(errors.Annotate(err, "could not modify model access"))
			continue
		}

		result.Results[i].Error = common.ServerError(
			ChangeModelAccess(m.state, modelTag, m.apiUser, targetUserTag, arg.Action, modelAccess, m.isAdmin))
	}
	return result, nil
}
开发者ID:makyo,项目名称:juju,代码行数:33,代码来源:modelmanager.go


示例9: getUser

func (api *UserManagerAPI) getUser(tag string) (*state.User, error) {
	userTag, err := names.ParseUserTag(tag)
	if err != nil {
		return nil, errors.Trace(err)
	}
	user, err := api.state.User(userTag)
	if err != nil {
		return nil, errors.Wrap(err, common.ErrPerm)
	}
	return user, nil
}
开发者ID:AlexisBruemmer,项目名称:juju,代码行数:11,代码来源:usermanager.go


示例10: TestParseUserTag

func (s *userSuite) TestParseUserTag(c *gc.C) {
	for i, t := range parseUserTagTests {
		c.Logf("test %d: %s", i, t.tag)
		got, err := names.ParseUserTag(t.tag)
		if err != nil || t.err != nil {
			c.Check(err, gc.DeepEquals, t.err)
			continue
		}
		c.Check(got, gc.FitsTypeOf, t.expected)
		c.Check(got, gc.Equals, t.expected)
	}
}
开发者ID:howbazaar,项目名称:names,代码行数:12,代码来源:user_test.go


示例11: TargetInfo

// TargetInfo implements ModelMigration.
func (mig *modelMigration) TargetInfo() (*migration.TargetInfo, error) {
	authTag, err := names.ParseUserTag(mig.doc.TargetAuthTag)
	if err != nil {
		return nil, errors.Trace(err)
	}
	return &migration.TargetInfo{
		ControllerTag: names.NewModelTag(mig.doc.TargetController),
		Addrs:         mig.doc.TargetAddrs,
		CACert:        mig.doc.TargetCACert,
		AuthTag:       authTag,
		Password:      mig.doc.TargetPassword,
	}, nil
}
开发者ID:makyo,项目名称:juju,代码行数:14,代码来源:modelmigration.go


示例12: ownerTag

func (s *Service) ownerTag() (names.UserTag, error) {
	var invalidTag names.UserTag
	var result params.StringResult
	args := params.Entities{
		Entities: []params.Entity{{Tag: s.tag.String()}},
	}
	err := s.st.facade.FacadeCall("GetOwnerTag", args, &result)
	if err != nil {
		return invalidTag, err
	}
	if result.Error != nil {
		return invalidTag, result.Error
	}
	return names.ParseUserTag(result.Result)
}
开发者ID:felicianotech,项目名称:juju,代码行数:15,代码来源:service.go


示例13: AddUser

// AddUser creates a new local user in the controller, sharing with that user any specified models.
func (c *Client) AddUser(
	username, displayName, password, access string, modelUUIDs ...string,
) (_ names.UserTag, secretKey []byte, _ error) {
	if !names.IsValidUser(username) {
		return names.UserTag{}, nil, fmt.Errorf("invalid user name %q", username)
	}
	modelTags := make([]string, len(modelUUIDs))
	for i, uuid := range modelUUIDs {
		modelTags[i] = names.NewModelTag(uuid).String()
	}

	var accessPermission params.ModelAccessPermission
	var err error
	if len(modelTags) > 0 {
		accessPermission, err = modelmanager.ParseModelAccess(access)
		if err != nil {
			return names.UserTag{}, nil, errors.Trace(err)
		}
	}

	userArgs := params.AddUsers{
		Users: []params.AddUser{{
			Username:        username,
			DisplayName:     displayName,
			Password:        password,
			SharedModelTags: modelTags,
			ModelAccess:     accessPermission}},
	}
	var results params.AddUserResults
	err = c.facade.FacadeCall("AddUser", userArgs, &results)
	if err != nil {
		return names.UserTag{}, nil, errors.Trace(err)
	}
	if count := len(results.Results); count != 1 {
		logger.Errorf("expected 1 result, got %#v", results)
		return names.UserTag{}, nil, errors.Errorf("expected 1 result, got %d", count)
	}
	result := results.Results[0]
	if result.Error != nil {
		return names.UserTag{}, nil, errors.Trace(result.Error)
	}
	tag, err := names.ParseUserTag(result.Tag)
	if err != nil {
		return names.UserTag{}, nil, errors.Trace(err)
	}
	return tag, result.SecretKey, nil
}
开发者ID:AlexisBruemmer,项目名称:juju,代码行数:48,代码来源:client.go


示例14: initiateOneModelMigration

func (c *ControllerAPI) initiateOneModelMigration(spec params.ModelMigrationSpec) (string, error) {
	modelTag, err := names.ParseModelTag(spec.ModelTag)
	if err != nil {
		return "", errors.Annotate(err, "model tag")
	}

	// Ensure the model exists.
	if _, err := c.state.GetModel(modelTag); err != nil {
		return "", errors.Annotate(err, "unable to read model")
	}

	// Get State for model.
	hostedState, err := c.state.ForModel(modelTag)
	if err != nil {
		return "", errors.Trace(err)
	}
	defer hostedState.Close()

	// Start the migration.
	targetInfo := spec.TargetInfo

	controllerTag, err := names.ParseModelTag(targetInfo.ControllerTag)
	if err != nil {
		return "", errors.Annotate(err, "controller tag")
	}
	authTag, err := names.ParseUserTag(targetInfo.AuthTag)
	if err != nil {
		return "", errors.Annotate(err, "auth tag")
	}

	args := state.ModelMigrationSpec{
		InitiatedBy: c.apiUser,
		TargetInfo: migration.TargetInfo{
			ControllerTag: controllerTag,
			Addrs:         targetInfo.Addrs,
			CACert:        targetInfo.CACert,
			AuthTag:       authTag,
			Password:      targetInfo.Password,
		},
	}
	mig, err := hostedState.CreateModelMigration(args)
	if err != nil {
		return "", errors.Trace(err)
	}
	return mig.Id(), nil
}
开发者ID:AlexisBruemmer,项目名称:juju,代码行数:46,代码来源:controller.go


示例15: apiModelInfoToModelInfoMap

func (c *showModelCommand) apiModelInfoToModelInfoMap(modelInfo []params.ModelInfo) (map[string]ModelInfo, error) {
	output := make(map[string]ModelInfo)
	for _, info := range modelInfo {
		tag, err := names.ParseUserTag(info.OwnerTag)
		if err != nil {
			return nil, errors.Trace(err)
		}
		output[info.Name] = ModelInfo{
			UUID:           info.UUID,
			ControllerUUID: info.ControllerUUID,
			Owner:          tag.Id(),
			ProviderType:   info.ProviderType,
			Users:          apiUsersToUserInfoMap(info.Users),
		}
	}
	return output, nil
}
开发者ID:AlexisBruemmer,项目名称:juju,代码行数:17,代码来源:show.go


示例16: loop

func (w *migrationMasterWatcher) loop() error {
	w.newResult = func() interface{} { return new(params.ModelMigrationTargetInfo) }
	w.call = makeWatcherAPICaller(w.caller, "MigrationMasterWatcher", w.id)
	w.commonWatcher.init()
	go w.commonLoop()

	for {
		var data interface{}
		var ok bool

		select {
		case data, ok = <-w.in:
			if !ok {
				// The tomb is already killed with the correct error
				// at this point, so just return.
				return nil
			}
		case <-w.tomb.Dying():
			return nil
		}

		info := data.(*params.ModelMigrationTargetInfo)
		controllerTag, err := names.ParseModelTag(info.ControllerTag)
		if err != nil {
			return errors.Annotatef(err, "unable to parse %q", info.ControllerTag)
		}
		authTag, err := names.ParseUserTag(info.AuthTag)
		if err != nil {
			return errors.Annotatef(err, "unable to parse %q", info.AuthTag)
		}
		outInfo := migration.TargetInfo{
			ControllerTag: controllerTag,
			Addrs:         info.Addrs,
			CACert:        info.CACert,
			AuthTag:       authTag,
			Password:      info.Password,
		}
		select {
		case w.out <- outInfo:
		case <-w.tomb.Dying():
			return nil
		}
	}
}
开发者ID:AlexisBruemmer,项目名称:juju,代码行数:44,代码来源:watcher.go


示例17: ModifyModelAccess

// ModifyModelAccess changes the model access granted to users.
func (em *ModelManagerAPI) ModifyModelAccess(args params.ModifyModelAccessRequest) (result params.ErrorResults, err error) {
	// API user must be a controller admin.
	createdBy, _ := em.authorizer.GetAuthTag().(names.UserTag)
	isAdmin, err := em.state.IsControllerAdministrator(createdBy)
	if err != nil {
		return result, errors.Trace(err)
	}
	if !isAdmin {
		return result, errors.New("only controller admins can grant or revoke model access")
	}

	result = params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.Changes)),
	}
	if len(args.Changes) == 0 {
		return result, nil
	}

	for i, arg := range args.Changes {
		modelAccess, err := FromModelAccessParam(arg.Access)
		if err != nil {
			err = errors.Annotate(err, "could not modify model access")
			result.Results[i].Error = common.ServerError(err)
			continue
		}

		userTagString := arg.UserTag
		user, err := names.ParseUserTag(userTagString)
		if err != nil {
			result.Results[i].Error = common.ServerError(errors.Annotate(err, "could not modify model access"))
			continue
		}
		modelTagString := arg.ModelTag
		model, err := names.ParseModelTag(modelTagString)
		if err != nil {
			result.Results[i].Error = common.ServerError(errors.Annotate(err, "could not modify model access"))
			continue
		}

		result.Results[i].Error = common.ServerError(
			ChangeModelAccess(em.state, model, createdBy, user, arg.Action, modelAccess))
	}
	return result, nil
}
开发者ID:AlexisBruemmer,项目名称:juju,代码行数:45,代码来源:modelmanager.go


示例18: serviceOwnerTag

func (s *Service) serviceOwnerTag() (names.UserTag, error) {
	var invalidTag names.UserTag
	var results params.StringResults
	args := params.Entities{
		Entities: []params.Entity{{Tag: s.tag.String()}},
	}
	err := s.st.facade.FacadeCall("ServiceOwner", args, &results)
	if err != nil {
		return invalidTag, err
	}
	if len(results.Results) != 1 {
		return invalidTag, fmt.Errorf("expected 1 result, got %d", len(results.Results))
	}
	result := results.Results[0]
	if result.Error != nil {
		return invalidTag, result.Error
	}
	return names.ParseUserTag(result.Result)
}
开发者ID:pmatulis,项目名称:juju,代码行数:19,代码来源:service.go


示例19: CreateEnvironment

// CreateEnvironment creates a new environment using the account and
// environment config specified in the args.
func (em *EnvironmentManagerAPI) CreateEnvironment(args params.EnvironmentCreateArgs) (params.Environment, error) {
	result := params.Environment{}
	// Get the state server environment first. We need it both for the state
	// server owner and the ability to get the config.
	stateServerEnv, err := em.state.StateServerEnvironment()
	if err != nil {
		return result, errors.Trace(err)
	}
	adminUser := stateServerEnv.Owner()

	ownerTag, err := names.ParseUserTag(args.OwnerTag)
	if err != nil {
		return result, errors.Trace(err)
	}

	// Any user is able to create themselves an environment (until real fine
	// grain permissions are available), and admins (the creator of the state
	// server environment) are able to create environments for other people.
	err = em.authCheck(ownerTag, adminUser)
	if err != nil {
		return result, errors.Trace(err)
	}

	newConfig, err := em.newEnvironmentConfig(args, stateServerEnv)
	if err != nil {
		return result, errors.Trace(err)
	}
	// NOTE: check the agent-version of the config, and if it is > the current
	// version, it is not supported, also check existing tools, and if we don't
	// have tools for that version, also die.
	env, st, err := em.state.NewEnvironment(newConfig, ownerTag)
	if err != nil {
		return result, errors.Annotate(err, "failed to create new environment")
	}
	defer st.Close()

	result.Name = env.Name()
	result.UUID = env.UUID()
	result.OwnerTag = env.Owner().String()

	return result, nil
}
开发者ID:Pankov404,项目名称:juju,代码行数:44,代码来源:environmentmanager.go


示例20: GetMigrationStatus

// GetMigrationStatus implements Client.
func (c *client) GetMigrationStatus() (MigrationStatus, error) {
	var empty MigrationStatus
	var status params.FullMigrationStatus
	err := c.caller.FacadeCall("GetMigrationStatus", nil, &status)
	if err != nil {
		return empty, errors.Trace(err)
	}

	modelTag, err := names.ParseModelTag(status.Spec.ModelTag)
	if err != nil {
		return empty, errors.Annotatef(err, "parsing model tag")
	}

	phase, ok := migration.ParsePhase(status.Phase)
	if !ok {
		return empty, errors.New("unable to parse phase")
	}

	target := status.Spec.TargetInfo
	controllerTag, err := names.ParseModelTag(target.ControllerTag)
	if err != nil {
		return empty, errors.Annotatef(err, "parsing controller tag")
	}

	authTag, err := names.ParseUserTag(target.AuthTag)
	if err != nil {
		return empty, errors.Annotatef(err, "unable to parse auth tag")
	}

	return MigrationStatus{
		ModelUUID: modelTag.Id(),
		Attempt:   status.Attempt,
		Phase:     phase,
		TargetInfo: migration.TargetInfo{
			ControllerTag: controllerTag,
			Addrs:         target.Addrs,
			CACert:        target.CACert,
			AuthTag:       authTag,
			Password:      target.Password,
		},
	}, nil
}
开发者ID:makyo,项目名称:juju,代码行数:43,代码来源:client.go



注:本文中的github.com/juju/names.ParseUserTag函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang names.ParseVolumeTag函数代码示例发布时间:2022-05-23
下一篇:
Golang names.ParseUnitTag函数代码示例发布时间:2022-05-23
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap