@@ -233,6 +233,60 @@ type PolicyRule struct {
233233 Scopes []string `json:"scopes,omitempty"`
234234}
235235
236+ func matches (allowed , requested []string , emptyAllowedIsAll bool ) bool {
237+ for _ , requested := range requested {
238+ if ! matchesSingle (allowed , requested , emptyAllowedIsAll ) {
239+ return false
240+ }
241+ }
242+ return true
243+ }
244+
245+ func matchesSingle (allowed []string , requested string , emptyAllowedIsAll bool ) bool {
246+ if len (requested ) == 0 {
247+ return true
248+ }
249+ if emptyAllowedIsAll && len (allowed ) == 0 {
250+ return true
251+ }
252+ for _ , allow := range allowed {
253+ if allow == "*" || requested == allow {
254+ return true
255+ }
256+ if strings .HasSuffix (allow , "*" ) && strings .HasPrefix (requested , allow [:len (allow )- 1 ]) {
257+ return true
258+ }
259+ }
260+
261+ return false
262+ }
263+
264+ func (p PolicyRule ) Grants (currentNamespace string , requested PolicyRule ) bool {
265+ if len (p .NonResourceURLs ) > 0 && len (p .Resources ) == 0 {
266+ return len (p .Scopes ) == 0 &&
267+ len (requested .Scopes ) == 0 &&
268+ matches (p .NonResourceURLs , requested .NonResourceURLs , false )
269+ }
270+
271+ if len (p .NonResourceURLs ) > 0 {
272+ return false
273+ }
274+
275+ for _ , ns := range p .ResolveNamespaces (currentNamespace ) {
276+ for _ , requestedNamespace := range requested .ResolveNamespaces (currentNamespace ) {
277+ if ns == requestedNamespace &&
278+ matches (p .Verbs , requested .Verbs , false ) &&
279+ matches (p .APIGroups , requested .APIGroups , false ) &&
280+ matches (p .Resources , requested .Resources , false ) &&
281+ matches (p .ResourceNames , requested .ResourceNames , true ) {
282+ return true
283+ }
284+ }
285+ }
286+
287+ return false
288+ }
289+
236290func (p PolicyRule ) IsAccountScoped () bool {
237291 for _ , scope := range p .Scopes {
238292 if scope == "" {
@@ -289,13 +343,38 @@ func (p PolicyRule) Namespaces() (result []string) {
289343 return
290344}
291345
346+ func GroupByServiceName (perms []Permissions ) map [string ]Permissions {
347+ byServiceName := map [string ]Permissions {}
348+
349+ for _ , perm := range perms {
350+ existing := byServiceName [perm .ServiceName ]
351+ existing .ServiceName = perm .ServiceName
352+ existing .Rules = append (existing .Rules , perm .Rules ... )
353+ byServiceName [perm .ServiceName ] = existing
354+ }
355+
356+ return byServiceName
357+ }
358+
292359type Permissions struct {
293360 ServiceName string `json:"serviceName,omitempty"`
294361 Rules []PolicyRule `json:"rules,omitempty"`
295362 // Deprecated, use Rules with the 'scopes: ["cluster"]' field
296363 ZZ_ClusterRules []PolicyRule `json:"clusterRules,omitempty"`
297364}
298365
366+ func (in Permissions ) Grants (currentNamespace string , forService string , requested PolicyRule ) bool {
367+ if in .ServiceName != forService {
368+ return false
369+ }
370+ for _ , granted := range in .GetRules () {
371+ if granted .Grants (currentNamespace , requested ) {
372+ return true
373+ }
374+ }
375+ return false
376+ }
377+
299378func (in Permissions ) GetRules () []PolicyRule {
300379 result := in .Rules
301380 for _ , rule := range in .ZZ_ClusterRules {
@@ -321,13 +400,27 @@ func (in *Permissions) Get() Permissions {
321400 return * in
322401}
323402
324- func FindPermission (serviceName string , perms []Permissions ) Permissions {
403+ func Grants (grantedPermissions Permissions , currentNamespace string , requestedPermissions Permissions ) (missing Permissions , granted bool ) {
404+ missing .ServiceName = requestedPermissions .ServiceName
405+
406+ for _ , requested := range requestedPermissions .Rules {
407+ if grantedPermissions .Grants (currentNamespace , requestedPermissions .ServiceName , requested ) {
408+ continue
409+ }
410+ missing .Rules = append (missing .Rules , requested )
411+ }
412+
413+ return missing , len (missing .Rules ) == 0
414+ }
415+
416+ func FindPermission (serviceName string , perms []Permissions ) (result Permissions ) {
417+ result .ServiceName = serviceName
325418 for _ , perm := range perms {
326- if serviceName == perm . ServiceName {
327- return perm
419+ if perm . ServiceName == serviceName {
420+ result . Rules = append ( result . Rules , perm . GetRules () ... )
328421 }
329422 }
330- return Permissions {}
423+ return
331424}
332425
333426type Files map [string ]File
@@ -418,24 +511,33 @@ type Router struct {
418511 Routes Routes `json:"routes,omitempty"`
419512}
420513
514+ func (in Acorn ) GetOriginalImage () string {
515+ originalImage := in .Image
516+ if in .Build != nil && in .Build .OriginalImage != "" {
517+ originalImage = in .Build .OriginalImage
518+ }
519+ return originalImage
520+ }
521+
421522type Acorn struct {
422- Labels ScopedLabels `json:"labels,omitempty"`
423- Annotations ScopedLabels `json:"annotations,omitempty"`
424- Image string `json:"image,omitempty"`
425- Build * AcornBuild `json:"build,omitempty"`
426- Profiles []string `json:"profiles,omitempty"`
427- DeployArgs GenericMap `json:"deployArgs,omitempty"`
428- Publish PortBindings `json:"publish,omitempty"`
429- PublishMode PublishMode `json:"publishMode,omitempty"`
430- Environment NameValues `json:"environment,omitempty"`
431- Secrets SecretBindings `json:"secrets,omitempty"`
432- Volumes VolumeBindings `json:"volumes,omitempty"`
433- Links ServiceBindings `json:"links,omitempty"`
434- AutoUpgrade * bool `json:"autoUpgrade,omitempty"`
435- NotifyUpgrade * bool `json:"notifyUpgrade,omitempty"`
436- AutoUpgradeInterval string `json:"autoUpgradeInterval,omitempty"`
437- Memory MemoryMap `json:"memory,omitempty"`
438- ComputeClasses ComputeClassMap `json:"computeClasses,omitempty"`
523+ Labels ScopedLabels `json:"labels,omitempty"`
524+ Annotations ScopedLabels `json:"annotations,omitempty"`
525+ Image string `json:"image,omitempty"`
526+ Build * AcornBuild `json:"build,omitempty"`
527+ Profiles []string `json:"profiles,omitempty"`
528+ DeployArgs GenericMap `json:"deployArgs,omitempty"`
529+ Publish PortBindings `json:"publish,omitempty"`
530+ PublishMode PublishMode `json:"publishMode,omitempty"`
531+ Environment NameValues `json:"environment,omitempty"`
532+ Secrets SecretBindings `json:"secrets,omitempty"`
533+ Volumes VolumeBindings `json:"volumes,omitempty"`
534+ Links ServiceBindings `json:"links,omitempty"`
535+ AutoUpgrade * bool `json:"autoUpgrade,omitempty"`
536+ NotifyUpgrade * bool `json:"notifyUpgrade,omitempty"`
537+ AutoUpgradeInterval string `json:"autoUpgradeInterval,omitempty"`
538+ Memory MemoryMap `json:"memory,omitempty"`
539+ ComputeClasses ComputeClassMap `json:"computeClasses,omitempty"`
540+ Permissions map [string ]Permissions `json:"permissions,omitempty"`
439541}
440542
441543type Secret struct {
@@ -474,31 +576,40 @@ type GeneratedService struct {
474576}
475577
476578type Service struct {
477- Labels ScopedLabels `json:"labels,omitempty"`
478- Annotations ScopedLabels `json:"annotations,omitempty"`
479- Default bool `json:"default,omitempty"`
480- External string `json:"external,omitempty"`
481- Alias string `json:"alias,omitempty"`
482- Address string `json:"address,omitempty"`
483- Ports Ports `json:"ports,omitempty"`
484- Container string `json:"container,omitempty"`
485- Data GenericMap `json:"data,omitempty"`
486- Generated * GeneratedService `json:"generated,omitempty"`
487- Image string `json:"image,omitempty"`
488- Build * AcornBuild `json:"build,omitempty"`
489- ServiceArgs GenericMap `json:"serviceArgs,omitempty"`
490- Environment NameValues `json:"environment,omitempty"`
491- Secrets SecretBindings `json:"secrets,omitempty"`
492- Links ServiceBindings `json:"links,omitempty"`
493- AutoUpgrade * bool `json:"autoUpgrade,omitempty"`
494- NotifyUpgrade * bool `json:"notifyUpgrade,omitempty"`
495- AutoUpgradeInterval string `json:"autoUpgradeInterval,omitempty"`
496- Memory MemoryMap `json:"memory,omitempty"`
497- }
498-
499- func (s Service ) GetJob () string {
500- if s .Generated == nil {
579+ Labels ScopedLabels `json:"labels,omitempty"`
580+ Annotations ScopedLabels `json:"annotations,omitempty"`
581+ Default bool `json:"default,omitempty"`
582+ External string `json:"external,omitempty"`
583+ Alias string `json:"alias,omitempty"`
584+ Address string `json:"address,omitempty"`
585+ Ports Ports `json:"ports,omitempty"`
586+ Container string `json:"container,omitempty"`
587+ Data GenericMap `json:"data,omitempty"`
588+ Generated * GeneratedService `json:"generated,omitempty"`
589+ Image string `json:"image,omitempty"`
590+ Build * AcornBuild `json:"build,omitempty"`
591+ ServiceArgs GenericMap `json:"serviceArgs,omitempty"`
592+ Environment NameValues `json:"environment,omitempty"`
593+ Secrets SecretBindings `json:"secrets,omitempty"`
594+ Links ServiceBindings `json:"links,omitempty"`
595+ AutoUpgrade * bool `json:"autoUpgrade,omitempty"`
596+ NotifyUpgrade * bool `json:"notifyUpgrade,omitempty"`
597+ AutoUpgradeInterval string `json:"autoUpgradeInterval,omitempty"`
598+ Memory MemoryMap `json:"memory,omitempty"`
599+ Permissions map [string ]Permissions `json:"permissions,omitempty"`
600+ }
601+
602+ func (in Service ) GetOriginalImage () string {
603+ originalImage := in .Image
604+ if in .Build != nil && in .Build .OriginalImage != "" {
605+ originalImage = in .Build .OriginalImage
606+ }
607+ return originalImage
608+ }
609+
610+ func (in Service ) GetJob () string {
611+ if in .Generated == nil {
501612 return ""
502613 }
503- return s .Generated .Job
614+ return in .Generated .Job
504615}
0 commit comments