@@ -64,6 +64,10 @@ func (f RoutePolicySourceFlags) validateSourceFlags() error {
6464
6565// resolveSource resolves source flags to a raw source string and a human-readable
6666// scope description. Returns (source, scopeDisplay, warnings, error).
67+ //
68+ // Resolution cascades org -> space -> app: each level refines the GUID that the
69+ // next level resolves against, and the most specific flag provided becomes the
70+ // scope. The result is always of the form cf:<scope>:<guid>.
6771func resolveSource (f RoutePolicySourceFlags , actor Actor , config command.Config ) (string , string , v7action.Warnings , error ) {
6872 var allWarnings v7action.Warnings
6973
@@ -77,29 +81,38 @@ func resolveSource(f RoutePolicySourceFlags, actor Actor, config command.Config)
7781 return "cf:any" , "scope: any, source: any authenticated app" , allWarnings , nil
7882 }
7983
80- // --source-app (with optional --source-space / --source-org for cross-space/org lookup)
81- if f .SourceApp != "" {
82- spaceGUID := config .TargetedSpace ().GUID
83- spaceName := config .TargetedSpace ().Name
84- orgName := config .TargetedOrganization ().Name
84+ scope := ""
85+ var sourceGUID string
8586
86- if f .SourceSpace != "" {
87- resolvedOrgGUID , resolvedOrgName , orgWarnings , err := resolveOrgGUID (f , actor , config )
88- allWarnings = append (allWarnings , orgWarnings ... )
89- if err != nil {
90- return "" , "" , allWarnings , err
91- }
92- orgName = resolvedOrgName
87+ // Org level: default to the targeted org; --source-org overrides it and, when it
88+ // is the most specific flag provided, becomes the scope.
89+ orgGUID := config .TargetedOrganization ().GUID
90+ orgName := config .TargetedOrganization ().Name
91+ if f .SourceOrg != "" {
92+ org , warnings , err := actor .GetOrganizationByName (f .SourceOrg )
93+ allWarnings = append (allWarnings , warnings ... )
94+ if err != nil {
95+ return "" , "" , allWarnings , err
96+ }
97+ orgGUID , orgName = org .GUID , f .SourceOrg
98+ scope , sourceGUID = "org" , orgGUID
99+ }
93100
94- resolvedSpaceGUID , spaceWarnings , err := resolveSpaceGUID (f .SourceSpace , resolvedOrgGUID , actor )
95- allWarnings = append (allWarnings , spaceWarnings ... )
96- if err != nil {
97- return "" , "" , allWarnings , err
98- }
99- spaceGUID = resolvedSpaceGUID
100- spaceName = f .SourceSpace
101+ // Space level: resolved within orgGUID (targeted or --source-org).
102+ spaceGUID := config .TargetedSpace ().GUID
103+ spaceName := config .TargetedSpace ().Name
104+ if f .SourceSpace != "" {
105+ space , warnings , err := actor .GetSpaceByNameAndOrganization (f .SourceSpace , orgGUID )
106+ allWarnings = append (allWarnings , warnings ... )
107+ if err != nil {
108+ return "" , "" , allWarnings , err
101109 }
110+ spaceGUID , spaceName = space .GUID , f .SourceSpace
111+ scope , sourceGUID = "space" , spaceGUID
112+ }
102113
114+ // App level: resolved within spaceGUID (targeted, --source-space, or both).
115+ if f .SourceApp != "" {
103116 app , warnings , err := actor .GetApplicationByNameAndSpace (f .SourceApp , spaceGUID )
104117 allWarnings = append (allWarnings , warnings ... )
105118 if err != nil {
@@ -113,75 +126,33 @@ func resolveSource(f RoutePolicySourceFlags, actor Actor, config command.Config)
113126 }
114127 return "" , "" , allWarnings , err
115128 }
129+ scope , sourceGUID = "app" , app .GUID
130+ }
131+
132+ if scope == "" {
133+ return "" , "" , allWarnings , fmt .Errorf ("no source specified" )
134+ }
116135
117- scopeDisplay := fmt .Sprintf ("scope: app, source: %s" , f .SourceApp )
136+ // Human-readable scope description; annotate cross-space/cross-org modifiers when present.
137+ var scopeDisplay string
138+ switch scope {
139+ case "app" :
140+ scopeDisplay = fmt .Sprintf ("scope: app, source: %s" , f .SourceApp )
118141 if f .SourceSpace != "" {
119142 scopeDisplay += fmt .Sprintf (" (space: %s" , spaceName )
120143 if f .SourceOrg != "" {
121144 scopeDisplay += fmt .Sprintf (", org: %s" , orgName )
122145 }
123146 scopeDisplay += ")"
124147 }
125-
126- return fmt .Sprintf ("cf:app:%s" , app .GUID ), scopeDisplay , allWarnings , nil
127- }
128-
129- // --source-space (primary: space-level policy)
130- if f .SourceSpace != "" {
131- orgGUID , orgName , orgWarnings , err := resolveOrgGUID (f , actor , config )
132- allWarnings = append (allWarnings , orgWarnings ... )
133- if err != nil {
134- return "" , "" , allWarnings , err
135- }
136-
137- spaceGUID , spaceWarnings , err := resolveSpaceGUID (f .SourceSpace , orgGUID , actor )
138- allWarnings = append (allWarnings , spaceWarnings ... )
139- if err != nil {
140- return "" , "" , allWarnings , err
141- }
142-
143- scopeDisplay := fmt .Sprintf ("scope: space, source: %s" , f .SourceSpace )
148+ case "space" :
149+ scopeDisplay = fmt .Sprintf ("scope: space, source: %s" , f .SourceSpace )
144150 if f .SourceOrg != "" {
145151 scopeDisplay += fmt .Sprintf (" (org: %s)" , orgName )
146152 }
147-
148- return fmt .Sprintf ("cf:space:%s" , spaceGUID ), scopeDisplay , allWarnings , nil
149- }
150-
151- // --source-org (primary: org-level policy)
152- if f .SourceOrg != "" {
153- org , warnings , err := actor .GetOrganizationByName (f .SourceOrg )
154- allWarnings = append (allWarnings , warnings ... )
155- if err != nil {
156- return "" , "" , allWarnings , err
157- }
158-
159- return fmt .Sprintf ("cf:org:%s" , org .GUID ),
160- fmt .Sprintf ("scope: org, source: %s" , f .SourceOrg ),
161- allWarnings , nil
162- }
163-
164- return "" , "" , allWarnings , fmt .Errorf ("no source specified" )
165- }
166-
167- // resolveOrgGUID returns the GUID and name of the org identified by --source-org,
168- // falling back to the targeted org if --source-org is not set.
169- func resolveOrgGUID (f RoutePolicySourceFlags , actor Actor , config command.Config ) (string , string , v7action.Warnings , error ) {
170- if f .SourceOrg == "" {
171- return config .TargetedOrganization ().GUID , config .TargetedOrganization ().Name , nil , nil
153+ default : // "org"
154+ scopeDisplay = fmt .Sprintf ("scope: org, source: %s" , f .SourceOrg )
172155 }
173- org , warnings , err := actor .GetOrganizationByName (f .SourceOrg )
174- if err != nil {
175- return "" , "" , v7action .Warnings (warnings ), err
176- }
177- return org .GUID , f .SourceOrg , v7action .Warnings (warnings ), nil
178- }
179156
180- // resolveSpaceGUID returns the GUID of the named space within the given org.
181- func resolveSpaceGUID (spaceName , orgGUID string , actor Actor ) (string , v7action.Warnings , error ) {
182- space , warnings , err := actor .GetSpaceByNameAndOrganization (spaceName , orgGUID )
183- if err != nil {
184- return "" , v7action .Warnings (warnings ), err
185- }
186- return space .GUID , v7action .Warnings (warnings ), nil
157+ return fmt .Sprintf ("cf:%s:%s" , scope , sourceGUID ), scopeDisplay , allWarnings , nil
187158}
0 commit comments