// matchUnit attempts to match a state.Unit to one of // a set of patterns, taking into account subordinate // relationships. func (m unitMatcher) matchUnit(u *state.Unit) bool { if m.matchesAny() { return true } // Keep the unit if: // (a) its name matches a pattern, or // (b) it's a principal and one of its subordinates matches, or // (c) it's a subordinate and its principal matches. // // Note: do *not* include a second subordinate if the principal is // only matched on account of a first subordinate matching. if m.matchString(u.Name()) { return true } if u.IsPrincipal() { for _, s := range u.SubordinateNames() { if m.matchString(s) { return true } } return false } principal, valid := u.PrincipalName() if !valid { panic("PrincipalName failed for subordinate unit") } return m.matchString(principal) }
// GetPrincipal returns the result of calling PrincipalName() and // converting it to a tag, on each given unit. func (u *UniterAPIV3) GetPrincipal(args params.Entities) (params.StringBoolResults, error) { result := params.StringBoolResults{ Results: make([]params.StringBoolResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.StringBoolResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { principal, ok := unit.PrincipalName() if principal != "" { result.Results[i].Result = names.NewUnitTag(principal).String() } result.Results[i].Ok = ok } } result.Results[i].Error = common.ServerError(err) } return result, nil }