github.com/verrazzano/verrazzano@v1.7.0/tools/oam-converter/pkg/resources/authorizationpolicy/authoizationpolicy.go (about) 1 // Copyright (c) 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package authorizationpolicy 5 6 import ( 7 "fmt" 8 vzapi "github.com/verrazzano/verrazzano/application-operator/apis/oam/v1alpha1" 9 "github.com/verrazzano/verrazzano/application-operator/constants" 10 consts "github.com/verrazzano/verrazzano/tools/oam-converter/pkg/constants" 11 "istio.io/api/security/v1beta1" 12 v1beta12 "istio.io/api/type/v1beta1" 13 clisecurity "istio.io/client-go/pkg/apis/security/v1beta1" 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "strings" 16 ) 17 18 // creates Authorization Policy 19 func CreateAuthorizationPolicies(trait *vzapi.IngressTrait, rule vzapi.IngressRule, namePrefix string, hosts []string) (*clisecurity.AuthorizationPolicy, error) { 20 21 // If any path needs an AuthorizationPolicy then add one for every path 22 var addAuthPolicy bool 23 for _, path := range rule.Paths { 24 if path.Policy != nil { 25 addAuthPolicy = true 26 } 27 } 28 for _, path := range rule.Paths { 29 if addAuthPolicy { 30 requireFrom := true 31 32 // Add a policy rule if one is missing 33 if path.Policy == nil { 34 path.Policy = &vzapi.AuthorizationPolicy{ 35 Rules: []*vzapi.AuthorizationRule{{}}, 36 } 37 // No from field required, this is just a path being added 38 requireFrom = false 39 } 40 41 pathSuffix := strings.Replace(path.Path, "/", "", -1) 42 policyName := namePrefix 43 if pathSuffix != "" { 44 policyName = fmt.Sprintf("%s-%s", policyName, pathSuffix) 45 } 46 47 authzPolicy := &clisecurity.AuthorizationPolicy{ 48 TypeMeta: metav1.TypeMeta{ 49 Kind: "AuthorizationPolicy", 50 APIVersion: consts.AuthorizationAPIVersion, 51 }, 52 ObjectMeta: metav1.ObjectMeta{ 53 Name: policyName, 54 Namespace: constants.IstioSystemNamespace, 55 Labels: map[string]string{constants.LabelIngressTraitNsn: getIngressTraitNsn(trait.Namespace, trait.Name)}, 56 }, 57 } 58 return mutateAuthorizationPolicy(authzPolicy, path.Policy, path.Path, hosts, requireFrom) 59 } 60 } 61 return nil, nil 62 } 63 64 // mutateAuthorizationPolicy changes the destination rule based upon a trait's configuration 65 func mutateAuthorizationPolicy(authzPolicy *clisecurity.AuthorizationPolicy, vzPolicy *vzapi.AuthorizationPolicy, path string, hosts []string, requireFrom bool) (*clisecurity.AuthorizationPolicy, error) { 66 policyRules := make([]*v1beta1.Rule, len(vzPolicy.Rules)) 67 var err error 68 for i, authzRule := range vzPolicy.Rules { 69 policyRules[i], err = createAuthorizationPolicyRule(authzRule, path, hosts, requireFrom) 70 if err != nil { 71 print(err) 72 return nil, err 73 } 74 } 75 76 authzPolicy.Spec = v1beta1.AuthorizationPolicy{ 77 Selector: &v1beta12.WorkloadSelector{ 78 MatchLabels: map[string]string{"istio": "ingressgateway"}, 79 }, 80 Rules: policyRules, 81 } 82 83 return authzPolicy, nil 84 } 85 86 // createAuthorizationPolicyRule uses the provided information to create an istio authorization policy rule 87 func createAuthorizationPolicyRule(rule *vzapi.AuthorizationRule, path string, hosts []string, requireFrom bool) (*v1beta1.Rule, error) { 88 authzRule := v1beta1.Rule{} 89 90 if requireFrom && rule.From == nil { 91 return nil, fmt.Errorf("Authorization Policy requires 'From' clause") 92 } 93 if rule.From != nil { 94 authzRule.From = []*v1beta1.Rule_From{ 95 {Source: &v1beta1.Source{ 96 RequestPrincipals: rule.From.RequestPrincipals}, 97 }, 98 } 99 } 100 101 if len(path) > 0 { 102 authzRule.To = []*v1beta1.Rule_To{{ 103 Operation: &v1beta1.Operation{ 104 Hosts: hosts, 105 Paths: []string{path}, 106 }, 107 }} 108 } 109 110 if rule.When != nil { 111 conditions := []*v1beta1.Condition{} 112 for _, vzCondition := range rule.When { 113 condition := &v1beta1.Condition{ 114 Key: vzCondition.Key, 115 Values: vzCondition.Values, 116 } 117 conditions = append(conditions, condition) 118 } 119 authzRule.When = conditions 120 } 121 122 return &authzRule, nil 123 } 124 125 // Get Ingress Trait Namespace and name appended with "-" 126 func getIngressTraitNsn(namespace string, name string) string { 127 return fmt.Sprintf("%s-%s", namespace, name) 128 }