github.com/akzi/consul@v1.4.5/acl/policy.go (about) 1 package acl 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 8 "github.com/hashicorp/consul/sentinel" 9 "github.com/hashicorp/hcl" 10 "github.com/hashicorp/hcl/hcl/ast" 11 hclprinter "github.com/hashicorp/hcl/hcl/printer" 12 "golang.org/x/crypto/blake2b" 13 ) 14 15 type SyntaxVersion int 16 17 const ( 18 SyntaxCurrent SyntaxVersion = iota 19 SyntaxLegacy 20 ) 21 22 const ( 23 PolicyDeny = "deny" 24 PolicyRead = "read" 25 PolicyWrite = "write" 26 PolicyList = "list" 27 ) 28 29 // Policy is used to represent the policy specified by 30 // an ACL configuration. 31 type Policy struct { 32 ID string `hcl:"id"` 33 Revision uint64 `hcl:"revision"` 34 ACL string `hcl:"acl,expand"` 35 Agents []*AgentPolicy `hcl:"agent,expand"` 36 AgentPrefixes []*AgentPolicy `hcl:"agent_prefix,expand"` 37 Keys []*KeyPolicy `hcl:"key,expand"` 38 KeyPrefixes []*KeyPolicy `hcl:"key_prefix,expand"` 39 Nodes []*NodePolicy `hcl:"node,expand"` 40 NodePrefixes []*NodePolicy `hcl:"node_prefix,expand"` 41 Services []*ServicePolicy `hcl:"service,expand"` 42 ServicePrefixes []*ServicePolicy `hcl:"service_prefix,expand"` 43 Sessions []*SessionPolicy `hcl:"session,expand"` 44 SessionPrefixes []*SessionPolicy `hcl:"session_prefix,expand"` 45 Events []*EventPolicy `hcl:"event,expand"` 46 EventPrefixes []*EventPolicy `hcl:"event_prefix,expand"` 47 PreparedQueries []*PreparedQueryPolicy `hcl:"query,expand"` 48 PreparedQueryPrefixes []*PreparedQueryPolicy `hcl:"query_prefix,expand"` 49 Keyring string `hcl:"keyring"` 50 Operator string `hcl:"operator"` 51 } 52 53 // Sentinel defines a snippet of Sentinel code that can be attached to a policy. 54 type Sentinel struct { 55 Code string 56 EnforcementLevel string 57 } 58 59 // AgentPolicy represents a policy for working with agent endpoints on nodes 60 // with specific name prefixes. 61 type AgentPolicy struct { 62 Node string `hcl:",key"` 63 Policy string 64 } 65 66 func (a *AgentPolicy) GoString() string { 67 return fmt.Sprintf("%#v", *a) 68 } 69 70 // KeyPolicy represents a policy for a key 71 type KeyPolicy struct { 72 Prefix string `hcl:",key"` 73 Policy string 74 Sentinel Sentinel 75 } 76 77 func (k *KeyPolicy) GoString() string { 78 return fmt.Sprintf("%#v", *k) 79 } 80 81 // NodePolicy represents a policy for a node 82 type NodePolicy struct { 83 Name string `hcl:",key"` 84 Policy string 85 Sentinel Sentinel 86 } 87 88 func (n *NodePolicy) GoString() string { 89 return fmt.Sprintf("%#v", *n) 90 } 91 92 // ServicePolicy represents a policy for a service 93 type ServicePolicy struct { 94 Name string `hcl:",key"` 95 Policy string 96 Sentinel Sentinel 97 98 // Intentions is the policy for intentions where this service is the 99 // destination. This may be empty, in which case the Policy determines 100 // the intentions policy. 101 Intentions string 102 } 103 104 func (s *ServicePolicy) GoString() string { 105 return fmt.Sprintf("%#v", *s) 106 } 107 108 // SessionPolicy represents a policy for making sessions tied to specific node 109 // name prefixes. 110 type SessionPolicy struct { 111 Node string `hcl:",key"` 112 Policy string 113 } 114 115 func (s *SessionPolicy) GoString() string { 116 return fmt.Sprintf("%#v", *s) 117 } 118 119 // EventPolicy represents a user event policy. 120 type EventPolicy struct { 121 Event string `hcl:",key"` 122 Policy string 123 } 124 125 func (e *EventPolicy) GoString() string { 126 return fmt.Sprintf("%#v", *e) 127 } 128 129 // PreparedQueryPolicy represents a prepared query policy. 130 type PreparedQueryPolicy struct { 131 Prefix string `hcl:",key"` 132 Policy string 133 } 134 135 func (p *PreparedQueryPolicy) GoString() string { 136 return fmt.Sprintf("%#v", *p) 137 } 138 139 // isPolicyValid makes sure the given string matches one of the valid policies. 140 func isPolicyValid(policy string) bool { 141 switch policy { 142 case PolicyDeny: 143 return true 144 case PolicyRead: 145 return true 146 case PolicyWrite: 147 return true 148 default: 149 return false 150 } 151 } 152 153 // isSentinelValid makes sure the given sentinel block is valid, and will skip 154 // out if the evaluator is nil. 155 func isSentinelValid(sentinel sentinel.Evaluator, basicPolicy string, sp Sentinel) error { 156 // Sentinel not enabled at all, or for this policy. 157 if sentinel == nil { 158 return nil 159 } 160 if sp.Code == "" { 161 return nil 162 } 163 164 // We only allow sentinel code on write policies at this time. 165 if basicPolicy != PolicyWrite { 166 return fmt.Errorf("code is only allowed for write policies") 167 } 168 169 // Validate the sentinel parts. 170 switch sp.EnforcementLevel { 171 case "", "soft-mandatory", "hard-mandatory": 172 // OK 173 default: 174 return fmt.Errorf("unsupported enforcement level %q", sp.EnforcementLevel) 175 } 176 return sentinel.Compile(sp.Code) 177 } 178 179 func parseCurrent(rules string, sentinel sentinel.Evaluator) (*Policy, error) { 180 p := &Policy{} 181 182 if err := hcl.Decode(p, rules); err != nil { 183 return nil, fmt.Errorf("Failed to parse ACL rules: %v", err) 184 } 185 186 // Validate the acl policy 187 if p.ACL != "" && !isPolicyValid(p.ACL) { 188 return nil, fmt.Errorf("Invalid acl policy: %#v", p.ACL) 189 } 190 191 // Validate the agent policy 192 for _, ap := range p.Agents { 193 if !isPolicyValid(ap.Policy) { 194 return nil, fmt.Errorf("Invalid agent policy: %#v", ap) 195 } 196 } 197 for _, ap := range p.AgentPrefixes { 198 if !isPolicyValid(ap.Policy) { 199 return nil, fmt.Errorf("Invalid agent_prefix policy: %#v", ap) 200 } 201 } 202 203 // Validate the key policy 204 for _, kp := range p.Keys { 205 if kp.Policy != PolicyList && !isPolicyValid(kp.Policy) { 206 return nil, fmt.Errorf("Invalid key policy: %#v", kp) 207 } 208 if err := isSentinelValid(sentinel, kp.Policy, kp.Sentinel); err != nil { 209 return nil, fmt.Errorf("Invalid key Sentinel policy: %#v, got error:%v", kp, err) 210 } 211 } 212 for _, kp := range p.KeyPrefixes { 213 if kp.Policy != PolicyList && !isPolicyValid(kp.Policy) { 214 return nil, fmt.Errorf("Invalid key_prefix policy: %#v", kp) 215 } 216 if err := isSentinelValid(sentinel, kp.Policy, kp.Sentinel); err != nil { 217 return nil, fmt.Errorf("Invalid key_prefix Sentinel policy: %#v, got error:%v", kp, err) 218 } 219 } 220 221 // Validate the node policies 222 for _, np := range p.Nodes { 223 if !isPolicyValid(np.Policy) { 224 return nil, fmt.Errorf("Invalid node policy: %#v", np) 225 } 226 if err := isSentinelValid(sentinel, np.Policy, np.Sentinel); err != nil { 227 return nil, fmt.Errorf("Invalid node Sentinel policy: %#v, got error:%v", np, err) 228 } 229 } 230 for _, np := range p.NodePrefixes { 231 if !isPolicyValid(np.Policy) { 232 return nil, fmt.Errorf("Invalid node_prefix policy: %#v", np) 233 } 234 if err := isSentinelValid(sentinel, np.Policy, np.Sentinel); err != nil { 235 return nil, fmt.Errorf("Invalid node_prefix Sentinel policy: %#v, got error:%v", np, err) 236 } 237 } 238 239 // Validate the service policies 240 for _, sp := range p.Services { 241 if !isPolicyValid(sp.Policy) { 242 return nil, fmt.Errorf("Invalid service policy: %#v", sp) 243 } 244 if sp.Intentions != "" && !isPolicyValid(sp.Intentions) { 245 return nil, fmt.Errorf("Invalid service intentions policy: %#v", sp) 246 } 247 if err := isSentinelValid(sentinel, sp.Policy, sp.Sentinel); err != nil { 248 return nil, fmt.Errorf("Invalid service Sentinel policy: %#v, got error:%v", sp, err) 249 } 250 } 251 for _, sp := range p.ServicePrefixes { 252 if !isPolicyValid(sp.Policy) { 253 return nil, fmt.Errorf("Invalid service_prefix policy: %#v", sp) 254 } 255 if sp.Intentions != "" && !isPolicyValid(sp.Intentions) { 256 return nil, fmt.Errorf("Invalid service_prefix intentions policy: %#v", sp) 257 } 258 if err := isSentinelValid(sentinel, sp.Policy, sp.Sentinel); err != nil { 259 return nil, fmt.Errorf("Invalid service_prefix Sentinel policy: %#v, got error:%v", sp, err) 260 } 261 } 262 263 // Validate the session policies 264 for _, sp := range p.Sessions { 265 if !isPolicyValid(sp.Policy) { 266 return nil, fmt.Errorf("Invalid session policy: %#v", sp) 267 } 268 } 269 for _, sp := range p.SessionPrefixes { 270 if !isPolicyValid(sp.Policy) { 271 return nil, fmt.Errorf("Invalid session_prefix policy: %#v", sp) 272 } 273 } 274 275 // Validate the user event policies 276 for _, ep := range p.Events { 277 if !isPolicyValid(ep.Policy) { 278 return nil, fmt.Errorf("Invalid event policy: %#v", ep) 279 } 280 } 281 for _, ep := range p.EventPrefixes { 282 if !isPolicyValid(ep.Policy) { 283 return nil, fmt.Errorf("Invalid event_prefix policy: %#v", ep) 284 } 285 } 286 287 // Validate the prepared query policies 288 for _, pq := range p.PreparedQueries { 289 if !isPolicyValid(pq.Policy) { 290 return nil, fmt.Errorf("Invalid query policy: %#v", pq) 291 } 292 } 293 for _, pq := range p.PreparedQueryPrefixes { 294 if !isPolicyValid(pq.Policy) { 295 return nil, fmt.Errorf("Invalid query_prefix policy: %#v", pq) 296 } 297 } 298 299 // Validate the keyring policy - this one is allowed to be empty 300 if p.Keyring != "" && !isPolicyValid(p.Keyring) { 301 return nil, fmt.Errorf("Invalid keyring policy: %#v", p.Keyring) 302 } 303 304 // Validate the operator policy - this one is allowed to be empty 305 if p.Operator != "" && !isPolicyValid(p.Operator) { 306 return nil, fmt.Errorf("Invalid operator policy: %#v", p.Operator) 307 } 308 309 return p, nil 310 } 311 312 func parseLegacy(rules string, sentinel sentinel.Evaluator) (*Policy, error) { 313 p := &Policy{} 314 315 type LegacyPolicy struct { 316 Agents []*AgentPolicy `hcl:"agent,expand"` 317 Keys []*KeyPolicy `hcl:"key,expand"` 318 Nodes []*NodePolicy `hcl:"node,expand"` 319 Services []*ServicePolicy `hcl:"service,expand"` 320 Sessions []*SessionPolicy `hcl:"session,expand"` 321 Events []*EventPolicy `hcl:"event,expand"` 322 PreparedQueries []*PreparedQueryPolicy `hcl:"query,expand"` 323 Keyring string `hcl:"keyring"` 324 Operator string `hcl:"operator"` 325 } 326 327 lp := &LegacyPolicy{} 328 329 if err := hcl.Decode(lp, rules); err != nil { 330 return nil, fmt.Errorf("Failed to parse ACL rules: %v", err) 331 } 332 333 // Validate the agent policy 334 for _, ap := range lp.Agents { 335 if !isPolicyValid(ap.Policy) { 336 return nil, fmt.Errorf("Invalid agent policy: %#v", ap) 337 } 338 339 p.AgentPrefixes = append(p.AgentPrefixes, ap) 340 } 341 342 // Validate the key policy 343 for _, kp := range lp.Keys { 344 if kp.Policy != PolicyList && !isPolicyValid(kp.Policy) { 345 return nil, fmt.Errorf("Invalid key policy: %#v", kp) 346 } 347 if err := isSentinelValid(sentinel, kp.Policy, kp.Sentinel); err != nil { 348 return nil, fmt.Errorf("Invalid key Sentinel policy: %#v, got error:%v", kp, err) 349 } 350 351 p.KeyPrefixes = append(p.KeyPrefixes, kp) 352 } 353 354 // Validate the node policies 355 for _, np := range lp.Nodes { 356 if !isPolicyValid(np.Policy) { 357 return nil, fmt.Errorf("Invalid node policy: %#v", np) 358 } 359 if err := isSentinelValid(sentinel, np.Policy, np.Sentinel); err != nil { 360 return nil, fmt.Errorf("Invalid node Sentinel policy: %#v, got error:%v", np, err) 361 } 362 363 p.NodePrefixes = append(p.NodePrefixes, np) 364 } 365 366 // Validate the service policies 367 for _, sp := range lp.Services { 368 if !isPolicyValid(sp.Policy) { 369 return nil, fmt.Errorf("Invalid service policy: %#v", sp) 370 } 371 if sp.Intentions != "" && !isPolicyValid(sp.Intentions) { 372 return nil, fmt.Errorf("Invalid service intentions policy: %#v", sp) 373 } 374 if err := isSentinelValid(sentinel, sp.Policy, sp.Sentinel); err != nil { 375 return nil, fmt.Errorf("Invalid service Sentinel policy: %#v, got error:%v", sp, err) 376 } 377 378 p.ServicePrefixes = append(p.ServicePrefixes, sp) 379 } 380 381 // Validate the session policies 382 for _, sp := range lp.Sessions { 383 if !isPolicyValid(sp.Policy) { 384 return nil, fmt.Errorf("Invalid session policy: %#v", sp) 385 } 386 387 p.SessionPrefixes = append(p.SessionPrefixes, sp) 388 } 389 390 // Validate the user event policies 391 for _, ep := range lp.Events { 392 if !isPolicyValid(ep.Policy) { 393 return nil, fmt.Errorf("Invalid event policy: %#v", ep) 394 } 395 396 p.EventPrefixes = append(p.EventPrefixes, ep) 397 } 398 399 // Validate the prepared query policies 400 for _, pq := range lp.PreparedQueries { 401 if !isPolicyValid(pq.Policy) { 402 return nil, fmt.Errorf("Invalid query policy: %#v", pq) 403 } 404 405 p.PreparedQueryPrefixes = append(p.PreparedQueryPrefixes, pq) 406 } 407 408 // Validate the keyring policy - this one is allowed to be empty 409 if lp.Keyring != "" && !isPolicyValid(lp.Keyring) { 410 return nil, fmt.Errorf("Invalid keyring policy: %#v", lp.Keyring) 411 } else { 412 p.Keyring = lp.Keyring 413 } 414 415 // Validate the operator policy - this one is allowed to be empty 416 if lp.Operator != "" && !isPolicyValid(lp.Operator) { 417 return nil, fmt.Errorf("Invalid operator policy: %#v", lp.Operator) 418 } else { 419 p.Operator = lp.Operator 420 } 421 422 return p, nil 423 } 424 425 // NewPolicyFromSource is used to parse the specified ACL rules into an 426 // intermediary set of policies, before being compiled into 427 // the ACL 428 func NewPolicyFromSource(id string, revision uint64, rules string, syntax SyntaxVersion, sentinel sentinel.Evaluator) (*Policy, error) { 429 if rules == "" { 430 // Hot path for empty source 431 return &Policy{ID: id, Revision: revision}, nil 432 } 433 434 var policy *Policy 435 var err error 436 switch syntax { 437 case SyntaxLegacy: 438 policy, err = parseLegacy(rules, sentinel) 439 case SyntaxCurrent: 440 policy, err = parseCurrent(rules, sentinel) 441 default: 442 return nil, fmt.Errorf("Invalid rules version: %d", syntax) 443 } 444 445 if err == nil { 446 policy.ID = id 447 policy.Revision = revision 448 } 449 return policy, err 450 } 451 452 func (policy *Policy) ConvertToLegacy() *Policy { 453 converted := &Policy{ 454 ID: policy.ID, 455 Revision: policy.Revision, 456 ACL: policy.ACL, 457 Keyring: policy.Keyring, 458 Operator: policy.Operator, 459 } 460 461 converted.Agents = append(converted.Agents, policy.Agents...) 462 converted.Agents = append(converted.Agents, policy.AgentPrefixes...) 463 converted.Keys = append(converted.Keys, policy.Keys...) 464 converted.Keys = append(converted.Keys, policy.KeyPrefixes...) 465 converted.Nodes = append(converted.Nodes, policy.Nodes...) 466 converted.Nodes = append(converted.Nodes, policy.NodePrefixes...) 467 converted.Services = append(converted.Services, policy.Services...) 468 converted.Services = append(converted.Services, policy.ServicePrefixes...) 469 converted.Sessions = append(converted.Sessions, policy.Sessions...) 470 converted.Sessions = append(converted.Sessions, policy.SessionPrefixes...) 471 converted.Events = append(converted.Events, policy.Events...) 472 converted.Events = append(converted.Events, policy.EventPrefixes...) 473 converted.PreparedQueries = append(converted.PreparedQueries, policy.PreparedQueries...) 474 converted.PreparedQueries = append(converted.PreparedQueries, policy.PreparedQueryPrefixes...) 475 return converted 476 } 477 478 func (policy *Policy) ConvertFromLegacy() *Policy { 479 return &Policy{ 480 ID: policy.ID, 481 Revision: policy.Revision, 482 AgentPrefixes: policy.Agents, 483 KeyPrefixes: policy.Keys, 484 NodePrefixes: policy.Nodes, 485 ServicePrefixes: policy.Services, 486 SessionPrefixes: policy.Sessions, 487 EventPrefixes: policy.Events, 488 PreparedQueryPrefixes: policy.PreparedQueries, 489 Keyring: policy.Keyring, 490 Operator: policy.Operator, 491 } 492 } 493 494 // takesPrecedenceOver returns true when permission a 495 // should take precedence over permission b 496 func takesPrecedenceOver(a, b string) bool { 497 if a == PolicyDeny { 498 return true 499 } else if b == PolicyDeny { 500 return false 501 } 502 503 if a == PolicyWrite { 504 return true 505 } else if b == PolicyWrite { 506 return false 507 } 508 509 if a == PolicyList { 510 return true 511 } else if b == PolicyList { 512 return false 513 } 514 515 if a == PolicyRead { 516 return true 517 } else if b == PolicyRead { 518 return false 519 } 520 521 return false 522 } 523 524 func multiPolicyID(policies []*Policy) []byte { 525 cacheKeyHash, err := blake2b.New256(nil) 526 if err != nil { 527 panic(err) 528 } 529 for _, policy := range policies { 530 cacheKeyHash.Write([]byte(policy.ID)) 531 binary.Write(cacheKeyHash, binary.BigEndian, policy.Revision) 532 } 533 return cacheKeyHash.Sum(nil) 534 } 535 536 // MergePolicies merges multiple ACL policies into one policy 537 // This function will not set either the ID or the Scope fields 538 // of the resulting policy as its up to the caller to determine 539 // what the merged value is. 540 func MergePolicies(policies []*Policy) *Policy { 541 // maps are used here so that we can lookup each policy by 542 // the segment that the rule applies to during the policy 543 // merge. Otherwise we could do a linear search through a slice 544 // and replace it inline 545 aclPolicy := "" 546 agentPolicies := make(map[string]*AgentPolicy) 547 agentPrefixPolicies := make(map[string]*AgentPolicy) 548 eventPolicies := make(map[string]*EventPolicy) 549 eventPrefixPolicies := make(map[string]*EventPolicy) 550 keyringPolicy := "" 551 keyPolicies := make(map[string]*KeyPolicy) 552 keyPrefixPolicies := make(map[string]*KeyPolicy) 553 nodePolicies := make(map[string]*NodePolicy) 554 nodePrefixPolicies := make(map[string]*NodePolicy) 555 operatorPolicy := "" 556 preparedQueryPolicies := make(map[string]*PreparedQueryPolicy) 557 preparedQueryPrefixPolicies := make(map[string]*PreparedQueryPolicy) 558 servicePolicies := make(map[string]*ServicePolicy) 559 servicePrefixPolicies := make(map[string]*ServicePolicy) 560 sessionPolicies := make(map[string]*SessionPolicy) 561 sessionPrefixPolicies := make(map[string]*SessionPolicy) 562 563 // Parse all the individual rule sets 564 for _, policy := range policies { 565 if takesPrecedenceOver(policy.ACL, aclPolicy) { 566 aclPolicy = policy.ACL 567 } 568 569 for _, ap := range policy.Agents { 570 update := true 571 if permission, found := agentPolicies[ap.Node]; found { 572 update = takesPrecedenceOver(ap.Policy, permission.Policy) 573 } 574 575 if update { 576 577 agentPolicies[ap.Node] = ap 578 } 579 } 580 581 for _, ap := range policy.AgentPrefixes { 582 update := true 583 if permission, found := agentPrefixPolicies[ap.Node]; found { 584 update = takesPrecedenceOver(ap.Policy, permission.Policy) 585 } 586 587 if update { 588 agentPrefixPolicies[ap.Node] = ap 589 } 590 } 591 592 for _, ep := range policy.Events { 593 update := true 594 if permission, found := eventPolicies[ep.Event]; found { 595 update = takesPrecedenceOver(ep.Policy, permission.Policy) 596 } 597 598 if update { 599 eventPolicies[ep.Event] = ep 600 } 601 } 602 603 for _, ep := range policy.EventPrefixes { 604 update := true 605 if permission, found := eventPrefixPolicies[ep.Event]; found { 606 update = takesPrecedenceOver(ep.Policy, permission.Policy) 607 } 608 609 if update { 610 eventPrefixPolicies[ep.Event] = ep 611 } 612 } 613 614 if takesPrecedenceOver(policy.Keyring, keyringPolicy) { 615 keyringPolicy = policy.Keyring 616 } 617 618 for _, kp := range policy.Keys { 619 update := true 620 if permission, found := keyPolicies[kp.Prefix]; found { 621 update = takesPrecedenceOver(kp.Policy, permission.Policy) 622 } 623 624 if update { 625 keyPolicies[kp.Prefix] = kp 626 } 627 } 628 629 for _, kp := range policy.KeyPrefixes { 630 update := true 631 if permission, found := keyPrefixPolicies[kp.Prefix]; found { 632 update = takesPrecedenceOver(kp.Policy, permission.Policy) 633 } 634 635 if update { 636 keyPrefixPolicies[kp.Prefix] = kp 637 } 638 } 639 640 for _, np := range policy.Nodes { 641 update := true 642 if permission, found := nodePolicies[np.Name]; found { 643 update = takesPrecedenceOver(np.Policy, permission.Policy) 644 } 645 646 if update { 647 nodePolicies[np.Name] = np 648 } 649 } 650 651 for _, np := range policy.NodePrefixes { 652 update := true 653 if permission, found := nodePrefixPolicies[np.Name]; found { 654 update = takesPrecedenceOver(np.Policy, permission.Policy) 655 } 656 657 if update { 658 nodePrefixPolicies[np.Name] = np 659 } 660 } 661 662 if takesPrecedenceOver(policy.Operator, operatorPolicy) { 663 operatorPolicy = policy.Operator 664 } 665 666 for _, qp := range policy.PreparedQueries { 667 update := true 668 if permission, found := preparedQueryPolicies[qp.Prefix]; found { 669 update = takesPrecedenceOver(qp.Policy, permission.Policy) 670 } 671 672 if update { 673 preparedQueryPolicies[qp.Prefix] = qp 674 } 675 } 676 677 for _, qp := range policy.PreparedQueryPrefixes { 678 update := true 679 if permission, found := preparedQueryPrefixPolicies[qp.Prefix]; found { 680 update = takesPrecedenceOver(qp.Policy, permission.Policy) 681 } 682 683 if update { 684 preparedQueryPrefixPolicies[qp.Prefix] = qp 685 } 686 } 687 688 for _, sp := range policy.Services { 689 existing, found := servicePolicies[sp.Name] 690 691 if !found { 692 servicePolicies[sp.Name] = sp 693 continue 694 } 695 696 if takesPrecedenceOver(sp.Policy, existing.Policy) { 697 existing.Policy = sp.Policy 698 existing.Sentinel = sp.Sentinel 699 } 700 701 if takesPrecedenceOver(sp.Intentions, existing.Intentions) { 702 existing.Intentions = sp.Intentions 703 } 704 } 705 706 for _, sp := range policy.ServicePrefixes { 707 existing, found := servicePrefixPolicies[sp.Name] 708 709 if !found { 710 servicePrefixPolicies[sp.Name] = sp 711 continue 712 } 713 714 if takesPrecedenceOver(sp.Policy, existing.Policy) { 715 existing.Policy = sp.Policy 716 existing.Sentinel = sp.Sentinel 717 } 718 719 if takesPrecedenceOver(sp.Intentions, existing.Intentions) { 720 existing.Intentions = sp.Intentions 721 } 722 } 723 724 for _, sp := range policy.Sessions { 725 update := true 726 if permission, found := sessionPolicies[sp.Node]; found { 727 update = takesPrecedenceOver(sp.Policy, permission.Policy) 728 } 729 730 if update { 731 sessionPolicies[sp.Node] = sp 732 } 733 } 734 735 for _, sp := range policy.SessionPrefixes { 736 update := true 737 if permission, found := sessionPrefixPolicies[sp.Node]; found { 738 update = takesPrecedenceOver(sp.Policy, permission.Policy) 739 } 740 741 if update { 742 sessionPrefixPolicies[sp.Node] = sp 743 } 744 } 745 } 746 747 merged := &Policy{ACL: aclPolicy, Keyring: keyringPolicy, Operator: operatorPolicy} 748 749 // All the for loop appends are ugly but Go doesn't have a way to get 750 // a slice of all values within a map so this is necessary 751 752 for _, policy := range agentPolicies { 753 merged.Agents = append(merged.Agents, policy) 754 } 755 756 for _, policy := range agentPrefixPolicies { 757 merged.AgentPrefixes = append(merged.AgentPrefixes, policy) 758 } 759 760 for _, policy := range eventPolicies { 761 merged.Events = append(merged.Events, policy) 762 } 763 764 for _, policy := range eventPrefixPolicies { 765 merged.EventPrefixes = append(merged.EventPrefixes, policy) 766 } 767 768 for _, policy := range keyPolicies { 769 merged.Keys = append(merged.Keys, policy) 770 } 771 772 for _, policy := range keyPrefixPolicies { 773 merged.KeyPrefixes = append(merged.KeyPrefixes, policy) 774 } 775 776 for _, policy := range nodePolicies { 777 merged.Nodes = append(merged.Nodes, policy) 778 } 779 780 for _, policy := range nodePrefixPolicies { 781 merged.NodePrefixes = append(merged.NodePrefixes, policy) 782 } 783 784 for _, policy := range preparedQueryPolicies { 785 merged.PreparedQueries = append(merged.PreparedQueries, policy) 786 } 787 788 for _, policy := range preparedQueryPrefixPolicies { 789 merged.PreparedQueryPrefixes = append(merged.PreparedQueryPrefixes, policy) 790 } 791 792 for _, policy := range servicePolicies { 793 merged.Services = append(merged.Services, policy) 794 } 795 796 for _, policy := range servicePrefixPolicies { 797 merged.ServicePrefixes = append(merged.ServicePrefixes, policy) 798 } 799 800 for _, policy := range sessionPolicies { 801 merged.Sessions = append(merged.Sessions, policy) 802 } 803 804 for _, policy := range sessionPrefixPolicies { 805 merged.SessionPrefixes = append(merged.SessionPrefixes, policy) 806 } 807 808 merged.ID = fmt.Sprintf("%x", multiPolicyID(policies)) 809 810 return merged 811 } 812 813 func TranslateLegacyRules(policyBytes []byte) ([]byte, error) { 814 parsed, err := hcl.ParseBytes(policyBytes) 815 if err != nil { 816 return nil, fmt.Errorf("Failed to parse rules: %v", err) 817 } 818 819 rewritten := ast.Walk(parsed, func(node ast.Node) (ast.Node, bool) { 820 switch n := node.(type) { 821 case *ast.ObjectKey: 822 switch n.Token.Text { 823 case "agent": 824 n.Token.Text = "agent_prefix" 825 case "key": 826 n.Token.Text = "key_prefix" 827 case "node": 828 n.Token.Text = "node_prefix" 829 case "query": 830 n.Token.Text = "query_prefix" 831 case "service": 832 n.Token.Text = "service_prefix" 833 case "session": 834 n.Token.Text = "session_prefix" 835 case "event": 836 n.Token.Text = "event_prefix" 837 } 838 } 839 840 return node, true 841 }) 842 843 buffer := new(bytes.Buffer) 844 845 if err := hclprinter.Fprint(buffer, rewritten); err != nil { 846 return nil, fmt.Errorf("Failed to output new rules: %v", err) 847 } 848 849 return buffer.Bytes(), nil 850 }