// ServiceOwner returns the owner user for each given service tag. func (u *UniterAPIV1) ServiceOwner(args params.Entities) (params.StringResults, error) { result := params.StringResults{ Results: make([]params.StringResult, len(args.Entities)), } canAccess, err := u.accessService() if err != nil { return params.StringResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseServiceTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } if !canAccess(tag) { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } service, err := u.getService(tag) if err != nil { result.Results[i].Error = common.ServerError(err) continue } result.Results[i].Result = service.GetOwnerTag() } return result, nil }
func (u *UniterAPI) getService(tag string) (*state.Service, error) { t, err := names.ParseServiceTag(tag) if err != nil { return nil, err } return u.st.Service(t.Id()) }
// Merge merges in the provided leadership settings. Only leaders for // the given service may perform this operation. func (lsa *LeadershipSettingsAccessor) Merge(bulkArgs params.MergeLeadershipSettingsBulkParams) (params.ErrorResults, error) { callerUnitId := lsa.authorizer.GetAuthTag().Id() requireServiceId, err := names.UnitService(callerUnitId) if err != nil { return params.ErrorResults{}, err } results := make([]params.ErrorResult, len(bulkArgs.Params)) for i, arg := range bulkArgs.Params { result := &results[i] // TODO(fwereade): we shoudn't assume a ServiceTag: we should // use an actual auth func to determine permissions. serviceTag, err := names.ParseServiceTag(arg.ServiceTag) if err != nil { result.Error = common.ServerError(err) continue } serviceId := serviceTag.Id() if serviceId != requireServiceId { result.Error = common.ServerError(common.ErrPerm) continue } token := lsa.leaderCheckFn(serviceId, callerUnitId) err = lsa.mergeSettingsChunkFn(token, serviceId, arg.Settings) if err != nil { result.Error = common.ServerError(err) } } return params.ErrorResults{Results: results}, nil }
// parseServiceTag attempts to parse the given serviceTag, and if it // fails returns an error which is safe to return to the client -- in // both a structure and security context. func parseServiceTag(serviceTag string) (names.ServiceTag, *params.Error) { parsedTag, err := names.ParseServiceTag(serviceTag) if err != nil { // We intentionally mask the real error for security purposes. return names.ServiceTag{}, common.ServerError(common.ErrPerm) } return parsedTag, nil }
func parseServiceTag(tagStr string) (names.ServiceTag, *params.Error) { // note the concrete error type serviceTag, err := names.ParseServiceTag(tagStr) if err != nil { return serviceTag, ¶ms.Error{ Message: err.Error(), Code: params.CodeBadRequest, } } return serviceTag, nil }
func (s *serviceSuite) TestParseServiceTag(c *gc.C) { for i, t := range parseServiceTagTests { c.Logf("test %d: %s", i, t.tag) got, err := names.ParseServiceTag(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) } }
// TODO(dimitern) bug #1270795 2014-01-20 // Add a doc comment here and use u.accessService() // below in the body to check for permissions. func (u *UniterAPI) GetOwnerTag(args params.Entities) (params.StringResult, error) { var nothing params.StringResult tag, err := names.ParseServiceTag(args.Entities[0].Tag) if err != nil { return nothing, common.ErrPerm } service, err := u.getService(tag) if err != nil { return nothing, err } return params.StringResult{ Result: service.GetOwnerTag(), }, nil }
// parseServiceAndUnitTags takes in string representations of service // and unit tags and returns their corresponding tags. func parseServiceAndUnitTags( serviceTagString, unitTagString string, ) ( names.ServiceTag, names.UnitTag, error, ) { // TODO(fwereade) 2015-02-25 bug #1425506 // These permissions errors are not appropriate -- there's no permission or // security issue in play here, because our tag format is public, and the // error only triggers when the strings fail to match that format. serviceTag, err := names.ParseServiceTag(serviceTagString) if err != nil { return names.ServiceTag{}, names.UnitTag{}, common.ErrPerm } unitTag, err := names.ParseUnitTag(unitTagString) if err != nil { return names.ServiceTag{}, names.UnitTag{}, common.ErrPerm } return serviceTag, unitTag, nil }
// WatchServiceRelations returns a StringsWatcher, for each given // service, that notifies of changes to the lifecycles of relations // involving that service. func (u *UniterAPI) WatchServiceRelations(args params.Entities) (params.StringsWatchResults, error) { result := params.StringsWatchResults{ Results: make([]params.StringsWatchResult, len(args.Entities)), } canAccess, err := u.accessService() if err != nil { return params.StringsWatchResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseServiceTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { result.Results[i], err = u.watchOneServiceRelations(tag) } result.Results[i].Error = common.ServerError(err) } return result, nil }
// GetExposed returns the exposed flag value for each given service. func (f *FirewallerAPI) GetExposed(args params.Entities) (params.BoolResults, error) { result := params.BoolResults{ Results: make([]params.BoolResult, len(args.Entities)), } canAccess, err := f.accessService() if err != nil { return params.BoolResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseServiceTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } service, err := f.getService(canAccess, tag) if err == nil { result.Results[i].Result = service.IsExposed() } result.Results[i].Error = common.ServerError(err) } return result, nil }
// Read reads leadership settings for the provided service ID. Any // unit of the service may perform this operation. func (lsa *LeadershipSettingsAccessor) Read(bulkArgs params.Entities) (params.GetLeadershipSettingsBulkResults, error) { callerUnitId := lsa.authorizer.GetAuthTag().Id() requireServiceId, err := names.UnitService(callerUnitId) if err != nil { return params.GetLeadershipSettingsBulkResults{}, err } results := make([]params.GetLeadershipSettingsResult, len(bulkArgs.Entities)) for i, arg := range bulkArgs.Entities { result := &results[i] // TODO(fwereade): we shoudn't assume a ServiceTag: we should // use an actual auth func to determine permissions. serviceTag, err := names.ParseServiceTag(arg.Tag) if err != nil { result.Error = common.ServerError(err) continue } serviceId := serviceTag.Id() if serviceId != requireServiceId { result.Error = common.ServerError(common.ErrPerm) continue } settings, err := lsa.getSettingsFn(serviceId) if err != nil { result.Error = common.ServerError(err) continue } result.Settings = settings } return params.GetLeadershipSettingsBulkResults{results}, nil }
// ServicesCharmActions returns a slice of charm Actions for a slice of // services. func (a *ActionAPI) ServicesCharmActions(args params.Entities) (params.ServicesCharmActionsResults, error) { result := params.ServicesCharmActionsResults{Results: make([]params.ServiceCharmActionsResult, len(args.Entities))} for i, entity := range args.Entities { currentResult := &result.Results[i] svcTag, err := names.ParseServiceTag(entity.Tag) if err != nil { currentResult.Error = common.ServerError(common.ErrBadId) continue } currentResult.ServiceTag = svcTag.String() svc, err := a.state.Service(svcTag.Id()) if err != nil { currentResult.Error = common.ServerError(err) continue } ch, _, err := svc.Charm() if err != nil { currentResult.Error = common.ServerError(err) continue } currentResult.Actions = ch.Actions() } return result, nil }
func (u *Uniter) init(unitTag string) (err error) { tag, err := names.ParseUnitTag(unitTag) if err != nil { return err } u.unit, err = u.st.Unit(tag) if err != nil { return err } if u.unit.Life() == params.Dead { // If we started up already dead, we should not progress further. If we // become Dead immediately after starting up, we may well complete any // operations in progress before detecting it; but that race is fundamental // and inescapable, whereas this one is not. return worker.ErrTerminateAgent } if err = u.setupLocks(); err != nil { return err } u.toolsDir = tools.ToolsDir(u.dataDir, unitTag) if err := EnsureJujucSymlinks(u.toolsDir); err != nil { return err } u.baseDir = filepath.Join(u.dataDir, "agents", unitTag) u.relationsDir = filepath.Join(u.baseDir, "state", "relations") if err := os.MkdirAll(u.relationsDir, 0755); err != nil { return err } serviceTag, err := names.ParseServiceTag(u.unit.ServiceTag()) if err != nil { return err } u.service, err = u.st.Service(serviceTag) if err != nil { return err } var env *uniter.Environment env, err = u.st.Environment() if err != nil { return err } u.uuid = env.UUID() u.envName = env.Name() u.relationers = map[int]*Relationer{} u.relationHooks = make(chan hook.Info) u.charmPath = filepath.Join(u.baseDir, "charm") deployerPath := filepath.Join(u.baseDir, "state", "deployer") bundles := charm.NewBundlesDir(filepath.Join(u.baseDir, "state", "bundles")) u.deployer, err = charm.NewDeployer(u.charmPath, deployerPath, bundles) if err != nil { return fmt.Errorf("cannot create deployer: %v", err) } u.sf = NewStateFile(filepath.Join(u.baseDir, "state", "uniter")) u.rand = rand.New(rand.NewSource(time.Now().Unix())) // If we start trying to listen for juju-run commands before we have valid // relation state, surprising things will come to pass. if err := u.restoreRelations(); err != nil { return err } runListenerSocketPath := filepath.Join(u.baseDir, RunListenerFile) logger.Debugf("starting juju-run listener on unix:%s", runListenerSocketPath) u.runListener, err = NewRunListener(u, runListenerSocketPath) if err != nil { return err } // The socket needs to have permissions 777 in order for other users to use it. return os.Chmod(runListenerSocketPath, 0777) }