From a97b4c39f3e361a3bf3543f2f902b70d595c206c Mon Sep 17 00:00:00 2001 From: Yangmin Zhu Date: Fri, 9 Aug 2019 07:09:17 -0700 Subject: [PATCH] authz-v2: clean out-dated authorization implementation (#16119) --- .../processor/metadata/collections.gen.go | 8 - .../config/processor/metadata/metadata.gen.go | 21 +- .../config/processor/metadata/metadata.yaml | 18 +- galley/pkg/metadata/kube/types.go | 15 - galley/pkg/metadata/types.gen.go | 6 - galley/testdata/validation/dataset.gen.go | 65 -- ...-v1alpha1-AuthorizationPolicy-invalid.yaml | 12 - ...ac-v1alpha1-AuthorizationPolicy-valid.yaml | 13 - galley/tools/gen-meta/metadata.yaml | 9 - istioctl/cmd/auth.go | 72 +- istioctl/cmd/auth_test.go | 21 - .../cmd/testdata/auth/authz-policy.golden | 31 - ...olicies-multiple-namespaces-v2.golden.yaml | 50 -- .../rbac-policies-multiple-namespaces.yaml | 45 -- ...ple-rules-multiple-services-v2.golden.yaml | 65 -- ...cies-multiple-rules-multiple-services.yaml | 11 - ...bac-policies-multiple-rules-v2.golden.yaml | 50 -- .../rbac-policies-multiple-rules.yaml | 12 - ...-policies-multiple-services-v2.golden.yaml | 40 - .../rbac-policies-multiple-services.yaml | 9 - ...rbac-policies-services-only-v2.golden.yaml | 53 -- .../testdata/rbac-policies-services-only.yaml | 49 -- ...cies-with-methods-and-paths-v2.golden.yaml | 27 - .../rbac-policies-with-methods-and-paths.yaml | 10 - istioctl/pkg/auth/upgrade.go | 352 --------- istioctl/pkg/auth/upgrade_test.go | 132 ---- pilot/pkg/config/kube/crd/types.go | 113 --- pilot/pkg/model/authorization.go | 74 +- pilot/pkg/model/authorization_test.go | 79 -- pilot/pkg/model/config.go | 26 - pilot/pkg/model/config_test.go | 34 - .../v1alpha3/fakes/fake_istio_config_store.go | 61 -- pilot/pkg/security/authz/policy/helper.go | 26 - pilot/pkg/security/authz/policy/v2/v2.go | 67 +- pilot/pkg/security/authz/policy/v2/v2_test.go | 84 --- pilot/test/mock/config.go | 10 - pkg/config/validation.go | 14 - pkg/config/validation_test.go | 161 ---- .../rbac/authorizationPolicy/basic/input.yaml | 17 - .../rbac/authorizationPolicy/basic/mcp.yaml | 50 -- .../rbac/authorizationPolicy/basic/test.yaml | 2 - .../rbac/testdata/v2-policy-basic.yaml.tmpl | 133 ---- .../testdata/v2-policy-extended.yaml.tmpl | 73 -- .../rbac/testdata/v2-policy-group.yaml.tmpl | 81 -- .../rbac/testdata/v2-policy-grpc.yaml.tmpl | 59 -- tests/integration/security/rbac/v2_test.go | 705 ------------------ 46 files changed, 12 insertions(+), 3053 deletions(-) delete mode 100644 galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-invalid.yaml delete mode 100644 galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-valid.yaml delete mode 100644 istioctl/cmd/testdata/auth/authz-policy.golden delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces-v2.golden.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services-v2.golden.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-v2.golden.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-rules.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-services-v2.golden.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-multiple-services.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-services-only-v2.golden.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-services-only.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths-v2.golden.yaml delete mode 100644 istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths.yaml delete mode 100644 istioctl/pkg/auth/upgrade.go delete mode 100644 istioctl/pkg/auth/upgrade_test.go delete mode 100644 tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/input.yaml delete mode 100644 tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/mcp.yaml delete mode 100644 tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/test.yaml delete mode 100644 tests/integration/security/rbac/testdata/v2-policy-basic.yaml.tmpl delete mode 100644 tests/integration/security/rbac/testdata/v2-policy-extended.yaml.tmpl delete mode 100644 tests/integration/security/rbac/testdata/v2-policy-group.yaml.tmpl delete mode 100644 tests/integration/security/rbac/testdata/v2-policy-grpc.yaml.tmpl delete mode 100644 tests/integration/security/rbac/v2_test.go diff --git a/galley/pkg/config/processor/metadata/collections.gen.go b/galley/pkg/config/processor/metadata/collections.gen.go index 453cf97b885e..9114f278b84b 100755 --- a/galley/pkg/config/processor/metadata/collections.gen.go +++ b/galley/pkg/config/processor/metadata/collections.gen.go @@ -162,9 +162,6 @@ var ( // IstioPolicyV1Beta1Rules is the name of collection istio/policy/v1beta1/rules IstioPolicyV1Beta1Rules = collection.NewName("istio/policy/v1beta1/rules") - // IstioRbacV1Alpha1Authorizationpolicies is the name of collection istio/rbac/v1alpha1/authorizationpolicies - IstioRbacV1Alpha1Authorizationpolicies = collection.NewName("istio/rbac/v1alpha1/authorizationpolicies") - // IstioRbacV1Alpha1Clusterrbacconfigs is the name of collection istio/rbac/v1alpha1/clusterrbacconfigs IstioRbacV1Alpha1Clusterrbacconfigs = collection.NewName("istio/rbac/v1alpha1/clusterrbacconfigs") @@ -342,9 +339,6 @@ var ( // K8SNetworkingIstioIoV1Alpha3Virtualservices is the name of collection k8s/networking.istio.io/v1alpha3/virtualservices K8SNetworkingIstioIoV1Alpha3Virtualservices = collection.NewName("k8s/networking.istio.io/v1alpha3/virtualservices") - // K8SRbacIstioIoV1Alpha1Authorizationpolicies is the name of collection k8s/rbac.istio.io/v1alpha1/authorizationpolicies - K8SRbacIstioIoV1Alpha1Authorizationpolicies = collection.NewName("k8s/rbac.istio.io/v1alpha1/authorizationpolicies") - // K8SRbacIstioIoV1Alpha1Clusterrbacconfigs is the name of collection k8s/rbac.istio.io/v1alpha1/clusterrbacconfigs K8SRbacIstioIoV1Alpha1Clusterrbacconfigs = collection.NewName("k8s/rbac.istio.io/v1alpha1/clusterrbacconfigs") @@ -412,7 +406,6 @@ func CollectionNames() []collection.Name { IstioPolicyV1Beta1Handlers, IstioPolicyV1Beta1Instances, IstioPolicyV1Beta1Rules, - IstioRbacV1Alpha1Authorizationpolicies, IstioRbacV1Alpha1Clusterrbacconfigs, IstioRbacV1Alpha1Rbacconfigs, IstioRbacV1Alpha1Servicerolebindings, @@ -472,7 +465,6 @@ func CollectionNames() []collection.Name { K8SNetworkingIstioIoV1Alpha3Serviceentries, K8SNetworkingIstioIoV1Alpha3Sidecars, K8SNetworkingIstioIoV1Alpha3Virtualservices, - K8SRbacIstioIoV1Alpha1Authorizationpolicies, K8SRbacIstioIoV1Alpha1Clusterrbacconfigs, K8SRbacIstioIoV1Alpha1Policy, K8SRbacIstioIoV1Alpha1Rbacconfigs, diff --git a/galley/pkg/config/processor/metadata/metadata.gen.go b/galley/pkg/config/processor/metadata/metadata.gen.go index 8d67830b5574..415824d8e304 100644 --- a/galley/pkg/config/processor/metadata/metadata.gen.go +++ b/galley/pkg/config/processor/metadata/metadata.gen.go @@ -13,6 +13,7 @@ import ( "strings" "time" ) + type asset struct { bytes []byte info os.FileInfo @@ -146,10 +147,6 @@ collections: proto: "istio.policy.v1beta1.Rule" protoPackage: "istio.io/api/policy/v1beta1" - - name: "istio/rbac/v1alpha1/authorizationpolicies" - proto: "istio.rbac.v1alpha1.AuthorizationPolicy" - protoPackage: "istio.io/api/rbac/v1alpha1" - - name: "istio/rbac/v1alpha1/clusterrbacconfigs" proto: "istio.rbac.v1alpha1.RbacConfig" protoPackage: "istio.io/api/rbac/v1alpha1" @@ -264,10 +261,6 @@ collections: proto: "istio.policy.v1beta1.Handler" protoPackage: "istio.io/api/policy/v1beta1" - - name: "k8s/rbac.istio.io/v1alpha1/authorizationpolicies" - proto: "istio.rbac.v1alpha1.AuthorizationPolicy" - protoPackage: "istio.io/api/rbac/v1alpha1" - - name: "k8s/rbac.istio.io/v1alpha1/clusterrbacconfigs" proto: "istio.rbac.v1alpha1.RbacConfig" protoPackage: "istio.io/api/rbac/v1alpha1" @@ -558,7 +551,6 @@ snapshots: - "istio/policy/v1beta1/handlers" - "istio/policy/v1beta1/instances" - "istio/policy/v1beta1/rules" - - "istio/rbac/v1alpha1/authorizationpolicies" - "istio/rbac/v1alpha1/clusterrbacconfigs" - "istio/rbac/v1alpha1/rbacconfigs" - "istio/rbac/v1alpha1/servicerolebindings" @@ -722,13 +714,7 @@ sources: plural: "servicerolebindings" group: "rbac.istio.io" version: "v1alpha1" - - - collection: "k8s/rbac.istio.io/v1alpha1/authorizationpolicies" - kind: "AuthorizationPolicy" - plural: "authorizationpolicies" - group: "rbac.istio.io" - version: "v1alpha1" - + - collection: "k8s/rbac.istio.io/v1alpha1/rbacconfigs" kind: "RbacConfig" plural: "rbacconfigs" @@ -1021,7 +1007,6 @@ transforms: "k8s/networking.istio.io/v1alpha3/serviceentries": "istio/networking/v1alpha3/serviceentries" "k8s/networking.istio.io/v1alpha3/sidecars": "istio/networking/v1alpha3/sidecars" "k8s/networking.istio.io/v1alpha3/virtualservices": "istio/networking/v1alpha3/virtualservices" - "k8s/rbac.istio.io/v1alpha1/authorizationpolicies": "istio/rbac/v1alpha1/authorizationpolicies" "k8s/rbac.istio.io/v1alpha1/policy": "istio/rbac/v1alpha1/servicerolebindings" "k8s/rbac.istio.io/v1alpha1/rbacconfigs": "istio/rbac/v1alpha1/rbacconfigs" "k8s/rbac.istio.io/v1alpha1/clusterrbacconfigs": "istio/rbac/v1alpha1/clusterrbacconfigs" @@ -1173,6 +1158,7 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } + var _bintree = &bintree{nil, map[string]*bintree{ "metadata.yaml": &bintree{metadataYaml, map[string]*bintree{}}, }} @@ -1223,4 +1209,3 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } - diff --git a/galley/pkg/config/processor/metadata/metadata.yaml b/galley/pkg/config/processor/metadata/metadata.yaml index c8f7f0ee717e..b77215969d23 100644 --- a/galley/pkg/config/processor/metadata/metadata.yaml +++ b/galley/pkg/config/processor/metadata/metadata.yaml @@ -100,10 +100,6 @@ collections: proto: "istio.policy.v1beta1.Rule" protoPackage: "istio.io/api/policy/v1beta1" - - name: "istio/rbac/v1alpha1/authorizationpolicies" - proto: "istio.rbac.v1alpha1.AuthorizationPolicy" - protoPackage: "istio.io/api/rbac/v1alpha1" - - name: "istio/rbac/v1alpha1/clusterrbacconfigs" proto: "istio.rbac.v1alpha1.RbacConfig" protoPackage: "istio.io/api/rbac/v1alpha1" @@ -218,10 +214,6 @@ collections: proto: "istio.policy.v1beta1.Handler" protoPackage: "istio.io/api/policy/v1beta1" - - name: "k8s/rbac.istio.io/v1alpha1/authorizationpolicies" - proto: "istio.rbac.v1alpha1.AuthorizationPolicy" - protoPackage: "istio.io/api/rbac/v1alpha1" - - name: "k8s/rbac.istio.io/v1alpha1/clusterrbacconfigs" proto: "istio.rbac.v1alpha1.RbacConfig" protoPackage: "istio.io/api/rbac/v1alpha1" @@ -512,7 +504,6 @@ snapshots: - "istio/policy/v1beta1/handlers" - "istio/policy/v1beta1/instances" - "istio/policy/v1beta1/rules" - - "istio/rbac/v1alpha1/authorizationpolicies" - "istio/rbac/v1alpha1/clusterrbacconfigs" - "istio/rbac/v1alpha1/rbacconfigs" - "istio/rbac/v1alpha1/servicerolebindings" @@ -676,13 +667,7 @@ sources: plural: "servicerolebindings" group: "rbac.istio.io" version: "v1alpha1" - - - collection: "k8s/rbac.istio.io/v1alpha1/authorizationpolicies" - kind: "AuthorizationPolicy" - plural: "authorizationpolicies" - group: "rbac.istio.io" - version: "v1alpha1" - + - collection: "k8s/rbac.istio.io/v1alpha1/rbacconfigs" kind: "RbacConfig" plural: "rbacconfigs" @@ -975,7 +960,6 @@ transforms: "k8s/networking.istio.io/v1alpha3/serviceentries": "istio/networking/v1alpha3/serviceentries" "k8s/networking.istio.io/v1alpha3/sidecars": "istio/networking/v1alpha3/sidecars" "k8s/networking.istio.io/v1alpha3/virtualservices": "istio/networking/v1alpha3/virtualservices" - "k8s/rbac.istio.io/v1alpha1/authorizationpolicies": "istio/rbac/v1alpha1/authorizationpolicies" "k8s/rbac.istio.io/v1alpha1/policy": "istio/rbac/v1alpha1/servicerolebindings" "k8s/rbac.istio.io/v1alpha1/rbacconfigs": "istio/rbac/v1alpha1/rbacconfigs" "k8s/rbac.istio.io/v1alpha1/clusterrbacconfigs": "istio/rbac/v1alpha1/clusterrbacconfigs" diff --git a/galley/pkg/metadata/kube/types.go b/galley/pkg/metadata/kube/types.go index 26c17e648ccf..ce6dc873982f 100644 --- a/galley/pkg/metadata/kube/types.go +++ b/galley/pkg/metadata/kube/types.go @@ -819,21 +819,6 @@ func init() { versions = append(versions, "v1alpha1") - b.Add(schema.ResourceSpec{ - Kind: "AuthorizationPolicy", - ListKind: "AuthorizationPolicyList", - Singular: "authorizationpolicy", - Plural: "authorizationpolicies", - Versions: versions, - Group: "rbac.istio.io", - Target: metadata.Types.Get("istio/rbac/v1alpha1/authorizationpolicies"), - Converter: converter.Get("identity"), - }) - - versions = make([]string, 0) - - versions = append(versions, "v1alpha1") - b.Add(schema.ResourceSpec{ Kind: "ClusterRbacConfig", ListKind: "ClusterRbacConfigList", diff --git a/galley/pkg/metadata/types.gen.go b/galley/pkg/metadata/types.gen.go index d2ebf0263480..0ae060222d0a 100755 --- a/galley/pkg/metadata/types.gen.go +++ b/galley/pkg/metadata/types.gen.go @@ -190,9 +190,6 @@ var ( // istio/policy/v1beta1/rules metadata IstioPolicyV1beta1Rules resource.Info - // istio/rbac/v1alpha1/authorizationpolicies metadata - IstioRbacV1alpha1Authorizationpolicies resource.Info - // istio/rbac/v1alpha1/clusterrbacconfigs metadata IstioRbacV1alpha1Clusterrbacconfigs resource.Info @@ -377,9 +374,6 @@ func init() { IstioPolicyV1beta1Rules = b.Register( "istio/policy/v1beta1/rules", "type.googleapis.com/istio.policy.v1beta1.Rule") - IstioRbacV1alpha1Authorizationpolicies = b.Register( - "istio/rbac/v1alpha1/authorizationpolicies", - "type.googleapis.com/istio.rbac.v1alpha1.AuthorizationPolicy") IstioRbacV1alpha1Clusterrbacconfigs = b.Register( "istio/rbac/v1alpha1/clusterrbacconfigs", "type.googleapis.com/istio.rbac.v1alpha1.RbacConfig") diff --git a/galley/testdata/validation/dataset.gen.go b/galley/testdata/validation/dataset.gen.go index 5fa0722640a3..48b9b1056880 100644 --- a/galley/testdata/validation/dataset.gen.go +++ b/galley/testdata/validation/dataset.gen.go @@ -36,8 +36,6 @@ // dataset/networking-v1alpha3-Sidecar-valid.yaml // dataset/networking-v1alpha3-VirtualService-invalid.yaml // dataset/networking-v1alpha3-VirtualService-valid.yaml -// dataset/rbac-v1alpha1-AuthorizationPolicy-invalid.yaml -// dataset/rbac-v1alpha1-AuthorizationPolicy-valid.yaml // dataset/rbac-v1alpha1-ClusterRbacConfig-invalid.yaml // dataset/rbac-v1alpha1-ClusterRbacConfig-valid.yaml // dataset/rbac-v1alpha1-RBacConfig-invalid.yaml @@ -1267,65 +1265,6 @@ func datasetNetworkingV1alpha3VirtualserviceValidYaml() (*asset, error) { return a, nil } -var _datasetRbacV1alpha1AuthorizationpolicyInvalidYaml = []byte(`apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer -spec: - allow: - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings -`) - -func datasetRbacV1alpha1AuthorizationpolicyInvalidYamlBytes() ([]byte, error) { - return _datasetRbacV1alpha1AuthorizationpolicyInvalidYaml, nil -} - -func datasetRbacV1alpha1AuthorizationpolicyInvalidYaml() (*asset, error) { - bytes, err := datasetRbacV1alpha1AuthorizationpolicyInvalidYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "dataset/rbac-v1alpha1-AuthorizationPolicy-invalid.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _datasetRbacV1alpha1AuthorizationpolicyValidYaml = []byte(`apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer -spec: - allow: - - role: service-viewer - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings -`) - -func datasetRbacV1alpha1AuthorizationpolicyValidYamlBytes() ([]byte, error) { - return _datasetRbacV1alpha1AuthorizationpolicyValidYaml, nil -} - -func datasetRbacV1alpha1AuthorizationpolicyValidYaml() (*asset, error) { - bytes, err := datasetRbacV1alpha1AuthorizationpolicyValidYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "dataset/rbac-v1alpha1-AuthorizationPolicy-valid.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _datasetRbacV1alpha1ClusterrbacconfigInvalidYaml = []byte(`apiVersion: "rbac.istio.io/v1alpha1" kind: ClusterRbacConfig metadata: @@ -1617,8 +1556,6 @@ var _bindata = map[string]func() (*asset, error){ "dataset/networking-v1alpha3-Sidecar-valid.yaml": datasetNetworkingV1alpha3SidecarValidYaml, "dataset/networking-v1alpha3-VirtualService-invalid.yaml": datasetNetworkingV1alpha3VirtualserviceInvalidYaml, "dataset/networking-v1alpha3-VirtualService-valid.yaml": datasetNetworkingV1alpha3VirtualserviceValidYaml, - "dataset/rbac-v1alpha1-AuthorizationPolicy-invalid.yaml": datasetRbacV1alpha1AuthorizationpolicyInvalidYaml, - "dataset/rbac-v1alpha1-AuthorizationPolicy-valid.yaml": datasetRbacV1alpha1AuthorizationpolicyValidYaml, "dataset/rbac-v1alpha1-ClusterRbacConfig-invalid.yaml": datasetRbacV1alpha1ClusterrbacconfigInvalidYaml, "dataset/rbac-v1alpha1-ClusterRbacConfig-valid.yaml": datasetRbacV1alpha1ClusterrbacconfigValidYaml, "dataset/rbac-v1alpha1-RBacConfig-invalid.yaml": datasetRbacV1alpha1RbacconfigInvalidYaml, @@ -1707,8 +1644,6 @@ var _bintree = &bintree{nil, map[string]*bintree{ "networking-v1alpha3-Sidecar-valid.yaml": &bintree{datasetNetworkingV1alpha3SidecarValidYaml, map[string]*bintree{}}, "networking-v1alpha3-VirtualService-invalid.yaml": &bintree{datasetNetworkingV1alpha3VirtualserviceInvalidYaml, map[string]*bintree{}}, "networking-v1alpha3-VirtualService-valid.yaml": &bintree{datasetNetworkingV1alpha3VirtualserviceValidYaml, map[string]*bintree{}}, - "rbac-v1alpha1-AuthorizationPolicy-invalid.yaml": &bintree{datasetRbacV1alpha1AuthorizationpolicyInvalidYaml, map[string]*bintree{}}, - "rbac-v1alpha1-AuthorizationPolicy-valid.yaml": &bintree{datasetRbacV1alpha1AuthorizationpolicyValidYaml, map[string]*bintree{}}, "rbac-v1alpha1-ClusterRbacConfig-invalid.yaml": &bintree{datasetRbacV1alpha1ClusterrbacconfigInvalidYaml, map[string]*bintree{}}, "rbac-v1alpha1-ClusterRbacConfig-valid.yaml": &bintree{datasetRbacV1alpha1ClusterrbacconfigValidYaml, map[string]*bintree{}}, "rbac-v1alpha1-RBacConfig-invalid.yaml": &bintree{datasetRbacV1alpha1RbacconfigInvalidYaml, map[string]*bintree{}}, diff --git a/galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-invalid.yaml b/galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-invalid.yaml deleted file mode 100644 index 6ffca76df05d..000000000000 --- a/galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-invalid.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer -spec: - allow: - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings diff --git a/galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-valid.yaml b/galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-valid.yaml deleted file mode 100644 index 0181ff28259f..000000000000 --- a/galley/testdata/validation/dataset/rbac-v1alpha1-AuthorizationPolicy-valid.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer -spec: - allow: - - role: service-viewer - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings diff --git a/galley/tools/gen-meta/metadata.yaml b/galley/tools/gen-meta/metadata.yaml index 55893c6a5a9c..105e3c3f47c1 100644 --- a/galley/tools/gen-meta/metadata.yaml +++ b/galley/tools/gen-meta/metadata.yaml @@ -206,15 +206,6 @@ resources: proto: "istio.rbac.v1alpha1.ServiceRoleBinding" collection: "istio/rbac/v1alpha1/servicerolebindings" - - kind: "AuthorizationPolicy" - singular: "authorizationpolicy" - plural: "authorizationpolicies" - group: "rbac.istio.io" - versions: - - "v1alpha1" - proto: "istio.rbac.v1alpha1.AuthorizationPolicy" - collection: "istio/rbac/v1alpha1/authorizationpolicies" - - kind: "RbacConfig" listKind: "RbacConfigList" singular: "rbacconfig" diff --git a/istioctl/cmd/auth.go b/istioctl/cmd/auth.go index ec0b7d208d7f..e29f8be637b3 100644 --- a/istioctl/cmd/auth.go +++ b/istioctl/cmd/auth.go @@ -19,24 +19,21 @@ import ( "io/ioutil" "os" - "istio.io/istio/pilot/pkg/model" - "github.com/spf13/cobra" - k8s "k8s.io/client-go/kubernetes" + + "istio.io/pkg/log" "istio.io/istio/istioctl/pkg/auth" "istio.io/istio/istioctl/pkg/kubernetes" "istio.io/istio/istioctl/pkg/util/configdump" "istio.io/istio/istioctl/pkg/util/handlers" - "istio.io/istio/pkg/kube" - "istio.io/pkg/log" + "istio.io/istio/pilot/pkg/model" ) var ( printAll bool configDumpFile string policyFiles []string - serviceFiles []string checkCmd = &cobra.Command{ Use: "check [.]", @@ -92,39 +89,7 @@ THIS COMMAND IS STILL UNDER ACTIVE DEVELOPMENT AND NOT READY FOR PRODUCTION USE. }, } - upgradeCmd = &cobra.Command{ - Hidden: true, - Use: "upgrade", - Short: "Upgrade Istio Authorization Policy from version v1 to v2", - Long: `Upgrade converts Istio authorization policy from version v1 to v2. It requires access to Kubernetes -service definition in order to translate the service name specified in the ServiceRole to the corresponding -workload labels in the AuthorizationPolicy. The service definition could be provided either from the current -Kubernetes cluster or from a yaml file specified from command line. - -THIS COMMAND IS STILL UNDER ACTIVE DEVELOPMENT AND NOT READY FOR PRODUCTION USE. -`, - Example: ` # Upgrade the Istio authorization policy with service definition from the current k8s cluster: - istioctl experimental auth upgrade -f istio-authz-v1-policy-1.yaml,istio-authz-v1-policy-2.yaml - - # Upgrade the Istio authorization policy with service definition from 2 yaml files specified in the command line: - istioctl experimental auth upgrade -f istio-authz-v1-policy.yaml --service svc-a.yaml,svc-b.yaml`, - RunE: func(cmd *cobra.Command, args []string) error { - upgrader, err := newUpgrader(policyFiles, serviceFiles) - if err != nil { - return err - } - err = upgrader.UpgradeCRDs() - if err != nil { - return err - } - writer := cmd.OutOrStdout() - _, err = writer.Write([]byte(upgrader.ConvertedPolicies.String())) - if err != nil { - return fmt.Errorf("failed writing config with error %v", err) - } - return nil - }, - } + // TODO(phillip): Add the upgrade command for the new authorization v1beta1 policy. validatorCmd = &cobra.Command{ Use: "validate ", @@ -203,29 +168,6 @@ func getConfigDumpFromPod(podName, podNamespace string) (*configdump.Wrapper, er return envoyConfig, nil } -func newUpgrader(v1PolicyFiles []string, serviceFiles []string) (*auth.Upgrader, error) { - if len(v1PolicyFiles) == 0 { - return nil, fmt.Errorf("no input file provided") - } - - var k8sClient *k8s.Clientset - var err error - if len(serviceFiles) == 0 { - k8sClient, err = kube.CreateClientset("", "") - if err != nil { - return nil, fmt.Errorf("failed to connect to Kubernetes with error %v", err) - } - } - - upgrader := &auth.Upgrader{ - K8sClient: k8sClient, - ServiceFiles: serviceFiles, - NamespaceToServiceToWorkloadLabels: map[string]auth.ServiceToWorkloadLabels{}, - V1PolicyFiles: v1PolicyFiles, - } - return upgrader, nil -} - func newValidator(policyFiles []string) (*auth.Validator, error) { if len(policyFiles) == 0 { return nil, fmt.Errorf("no input file provided") @@ -245,7 +187,6 @@ func Auth() *cobra.Command { Short: "Inspect and interact with authentication and authorization policies in the mesh", Long: `Commands to inspect and interact with the authentication (TLS, JWT) and authorization (RBAC) policies in the mesh check - check the TLS/JWT/RBAC settings based on the Envoy config - upgrade - upgrade the authorization policy from version v1 to v2 validate - check for potential incorrect usage in authorization policy files. `, Example: ` # Check the TLS/JWT/RBAC settings for pod httpbin-88ddbcfdd-nt5jb: @@ -253,7 +194,6 @@ func Auth() *cobra.Command { } cmd.AddCommand(checkCmd) - cmd.AddCommand(upgradeCmd) cmd.AddCommand(validatorCmd) return cmd } @@ -263,10 +203,6 @@ func init() { "Show additional information (e.g. SNI and ALPN)") checkCmd.PersistentFlags().StringVarP(&configDumpFile, "file", "f", "", "Check the TLS/JWT/RBAC setting from the config dump file") - upgradeCmd.PersistentFlags().StringSliceVarP(&policyFiles, "file", "f", []string{}, - "Authorization policy file") - upgradeCmd.PersistentFlags().StringSliceVarP(&serviceFiles, "service", "s", []string{}, - "Kubernetes Service resource that provides the mapping relationship between service name and pod labels") validatorCmd.PersistentFlags().StringSliceVarP(&policyFiles, "file", "f", []string{}, "Authorization policy file") } diff --git a/istioctl/cmd/auth_test.go b/istioctl/cmd/auth_test.go index 69b53dd5356a..500839c25a34 100644 --- a/istioctl/cmd/auth_test.go +++ b/istioctl/cmd/auth_test.go @@ -69,27 +69,6 @@ func TestAuthCheck(t *testing.T) { } } -func TestAuthUpgrade(t *testing.T) { - testCases := []struct { - name string - in string - services []string - golden string - }{ - { - name: "v1 policies", - in: "testdata/auth/authz-policy.yaml", - services: []string{"testdata/auth/svc-other.yaml", "testdata/auth/svc-bookinfo.yaml"}, - golden: "testdata/auth/authz-policy.golden", - }, - } - - for _, c := range testCases { - command := fmt.Sprintf("experimental auth upgrade -f %s --service %s", c.in, strings.Join(c.services, ",")) - runCommandAndCheckGoldenFile(c.name, command, c.golden, t) - } -} - func TestAuthValidator(t *testing.T) { testCases := []struct { name string diff --git a/istioctl/cmd/testdata/auth/authz-policy.golden b/istioctl/cmd/testdata/auth/authz-policy.golden deleted file mode 100644 index be9836458f55..000000000000 --- a/istioctl/cmd/testdata/auth/authz-policy.golden +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-productpage-viewer - namespace: default -spec: - allow: - - role: productpage-viewer - subjects: - - properties: - source.namespace: istio-system - - groups: - - bar - names: - - foo - workloadSelector: - labels: - app: productpage ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: productpage-viewer - namespace: default -spec: - rules: - - constraints: - - key: destination.labels[version] - values: - - v3 ---- diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces-v2.golden.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces-v2.golden.yaml deleted file mode 100644 index b62883431f8f..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces-v2.golden.yaml +++ /dev/null @@ -1,50 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer - namespace: foo -spec: - allow: - - role: service-viewer - subjects: - - names: - - foo - workloadSelector: - labels: - app: productpage ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer - namespace: bar -spec: - allow: - - role: service-viewer - subjects: - - names: - - bar - workloadSelector: - labels: - app: ratings ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer - namespace: foo -spec: - rules: - - methods: - - GET ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer - namespace: bar -spec: - rules: - - methods: - - POST ---- diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces.yaml deleted file mode 100644 index 2f9cb8f70d1e..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-namespaces.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: service-viewer - namespace: foo -spec: - rules: - - services: ["productpage.svc.cluster.local"] - methods: ["GET"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: service-viewer - namespace: bar -spec: - rules: - - services: ["ratings.svc.cluster.local"] - methods: ["POST"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRoleBinding -# This comment will be removed in the converted version of this file. -metadata: - name: bind-service-viewer - namespace: foo -spec: - subjects: - - user: "foo" - roleRef: - kind: ServiceRole - name: "service-viewer" ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRoleBinding -# This comment will be removed in the converted version of this file. -metadata: - name: bind-service-viewer - namespace: bar -spec: - subjects: - - user: "bar" - roleRef: - kind: ServiceRole - name: "service-viewer" \ No newline at end of file diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services-v2.golden.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services-v2.golden.yaml deleted file mode 100644 index b80c021e819a..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services-v2.golden.yaml +++ /dev/null @@ -1,65 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer-0-0 - namespace: default -spec: - allow: - - role: service-viewer-0 - subjects: - - names: - - foo - workloadSelector: - labels: - app: productpage ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer-0-1 - namespace: default -spec: - allow: - - role: service-viewer-0 - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer-1 - namespace: default -spec: - allow: - - role: service-viewer-1 - subjects: - - names: - - foo - workloadSelector: - labels: - app: reviews ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer-0 - namespace: default -spec: - rules: - - methods: - - GET ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer-1 - namespace: default -spec: - rules: - - methods: - - POST ---- diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services.yaml deleted file mode 100644 index a5cd384d9cbd..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-multiple-services.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - services: ["productpage.svc.cluster.local", "ratings.svc.cluster.local"] - methods: ["GET"] - - services: ["reviews.svc.cluster.local"] - methods: ["POST"] diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-v2.golden.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-v2.golden.yaml deleted file mode 100644 index bc5ebd97ae3a..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules-v2.golden.yaml +++ /dev/null @@ -1,50 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer-0 - namespace: default -spec: - allow: - - role: service-viewer-0 - subjects: - - names: - - foo - workloadSelector: - labels: - app: productpage ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer-1 - namespace: default -spec: - allow: - - role: service-viewer-1 - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer-0 - namespace: default -spec: - rules: - - methods: - - GET ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer-1 - namespace: default -spec: - rules: - - methods: - - POST ---- diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules.yaml deleted file mode 100644 index 2b8a8b67531d..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-rules.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Since there are two rules, this ServiceRole will be converting into two ServiceRoles, one with a rule. -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - services: ["productpage.svc.cluster.local"] - methods: ["GET"] - - services: ["ratings.svc.cluster.local"] - methods: ["POST"] diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-services-v2.golden.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-services-v2.golden.yaml deleted file mode 100644 index ba7e0abba6c4..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-services-v2.golden.yaml +++ /dev/null @@ -1,40 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer-0 - namespace: default -spec: - allow: - - role: service-viewer - subjects: - - names: - - foo - workloadSelector: - labels: - app: productpage ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer-1 - namespace: default -spec: - allow: - - role: service-viewer - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - methods: - - '*' ---- diff --git a/istioctl/pkg/auth/testdata/rbac-policies-multiple-services.yaml b/istioctl/pkg/auth/testdata/rbac-policies-multiple-services.yaml deleted file mode 100644 index 099493b67f04..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-multiple-services.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - services: ["productpage.svc.cluster.local", "ratings.svc.cluster.local"] - diff --git a/istioctl/pkg/auth/testdata/rbac-policies-services-only-v2.golden.yaml b/istioctl/pkg/auth/testdata/rbac-policies-services-only-v2.golden.yaml deleted file mode 100644 index d0d098d579ff..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-services-only-v2.golden.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer - namespace: default -spec: - allow: - - role: service-viewer - subjects: - - properties: - source.namespace: istio-system - - groups: - - bar - names: - - foo - workloadSelector: - labels: - app: productpage ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-all-services - namespace: default -spec: - allow: - - role: all-services - subjects: - - names: - - foo ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - constraints: - - key: destination.labels[version] - values: - - v3 ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: all-services - namespace: default -spec: - rules: - - methods: - - '*' ---- diff --git a/istioctl/pkg/auth/testdata/rbac-policies-services-only.yaml b/istioctl/pkg/auth/testdata/rbac-policies-services-only.yaml deleted file mode 100644 index 4fe6d0a051fe..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-services-only.yaml +++ /dev/null @@ -1,49 +0,0 @@ -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - services: ["productpage.svc.cluster.local"] - constraints: - - key: "destination.labels[version]" - values: ["v3"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: all-services - namespace: default -spec: - rules: - - services: ["*"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRoleBinding -# This comment will be removed in the converted version of this file. -metadata: - name: bind-service-viewer - namespace: default -spec: - subjects: - - properties: - source.namespace: "istio-system" - - user: "foo" - group: "bar" - roleRef: - kind: ServiceRole - name: "service-viewer" ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRoleBinding -# This comment will be removed in the converted version of this file. -metadata: - name: bind-all-services - namespace: default -spec: - subjects: - - user: "foo" - roleRef: - kind: ServiceRole - name: "all-services" diff --git a/istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths-v2.golden.yaml b/istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths-v2.golden.yaml deleted file mode 100644 index a970d2e8bcae..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths-v2.golden.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: rbac.istio.io/v1alpha1 -kind: AuthorizationPolicy -metadata: - name: bind-service-viewer - namespace: default -spec: - allow: - - role: service-viewer - subjects: - - names: - - foo - workloadSelector: - labels: - app: ratings ---- -apiVersion: rbac.istio.io/v1alpha1 -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - methods: - - GET - paths: - - /prod/* ---- diff --git a/istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths.yaml b/istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths.yaml deleted file mode 100644 index 236ede71c397..000000000000 --- a/istioctl/pkg/auth/testdata/rbac-policies-with-methods-and-paths.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: service-viewer - namespace: default -spec: - rules: - - services: ["ratings.svc.cluster.local"] - methods: ["GET"] - paths: ["/prod/*"] diff --git a/istioctl/pkg/auth/upgrade.go b/istioctl/pkg/auth/upgrade.go deleted file mode 100644 index ebfb1504a117..000000000000 --- a/istioctl/pkg/auth/upgrade.go +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright 2019 Istio Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package auth - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "strconv" - "strings" - - v1 "k8s.io/api/core/v1" - kubeyaml "k8s.io/apimachinery/pkg/util/yaml" - - "github.com/ghodss/yaml" - - "istio.io/istio/pilot/pkg/config/kube/crd" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - - "istio.io/istio/pilot/pkg/model" - - rbacproto "istio.io/api/rbac/v1alpha1" -) - -// WorkloadLabels is the workload labels, for example, app: productpage. -type WorkloadLabels map[string]string - -// ServiceToWorkloadLabels maps the short service name to the workload labels that it's pointing to. -// This service is defined in same namespace as the ServiceRole that's using it. -type ServiceToWorkloadLabels map[string]WorkloadLabels - -type Upgrader struct { - K8sClient *kubernetes.Clientset - ServiceFiles []string - // NamespaceToServiceToWorkloadLabels maps the namespace to service name to the workload labels - // that the service in this namespace pointing to. - NamespaceToServiceToWorkloadLabels map[string]ServiceToWorkloadLabels - V1PolicyFiles []string - serviceRoles []model.Config - serviceRoleBindings []model.Config - ConvertedPolicies strings.Builder -} - -const ( - creationTimestampNilField = "creationTimestamp: null" -) - -var ( - configDescriptor = model.ConfigDescriptor{ - model.ServiceRole, - model.ServiceRoleBinding, - model.AuthorizationPolicy, - } -) - -// UpgradeCRDs is the main function that converts RBAC v1 to v2 for local policy files. -func (ug *Upgrader) UpgradeCRDs() error { - err := ug.createRoleAndBindingLists(ug.V1PolicyFiles) - if err != nil { - return err - } - // Need to perform the conversion on ServiceRoleBinding first, since ServiceRoles will be modified. - // This prevents creating unnecessary deep copies of ServiceRoles. - for _, serviceRoleBinding := range ug.serviceRoleBindings { - err := ug.createAuthorizationPolicyFromRoleBinding(serviceRoleBinding) - if err != nil { - return err - } - } - for _, serviceRole := range ug.serviceRoles { - err := ug.upgradeServiceRole(serviceRole) - if err != nil { - return err - } - } - return nil -} - -// parseConfigToString parses data from `config` to string. -func parseConfigToString(config model.Config) (string, error) { - schema, exists := configDescriptor.GetByType(config.Type) - if !exists { - return "", fmt.Errorf("unknown kind %q for %v", crd.ResourceName(config.Type), config.Name) - } - obj, err := crd.ConvertConfig(schema, config) - if err != nil { - return "", fmt.Errorf("could not decode %v: %v", config.Name, err) - } - configInBytes, err := yaml.Marshal(obj) - if err != nil { - return "", fmt.Errorf("could not unmarshal %v: %v", config.Name, err) - } - configLines := strings.Split(string(configInBytes), "\n") - var configInString strings.Builder - for i, configLine := range configLines { - if i == len(configLines)-1 && configLine == "" { - configInString.WriteString("---\n") - } else if !strings.Contains(configLine, creationTimestampNilField) { - configInString.WriteString(fmt.Sprintf("%s\n", configLine)) - } - } - return configInString.String(), nil -} - -// createRoleAndBindingLists creates lists of model.Configs to store ServiceRole and ServiceRoleBinding policies. -func (ug *Upgrader) createRoleAndBindingLists(fileNames []string) error { - for _, fileName := range fileNames { - rbacFileBuf, err := ioutil.ReadFile(fileName) - if err != nil { - return fmt.Errorf("failed to read file %s", fileName) - } - configsFromFile, _, err := crd.ParseInputs(string(rbacFileBuf)) - if err != nil { - return err - } - for _, config := range configsFromFile { - if config.Type == model.ServiceRole.Type { - ug.serviceRoles = append(ug.serviceRoles, config) - } else if config.Type == model.ServiceRoleBinding.Type { - ug.serviceRoleBindings = append(ug.serviceRoleBindings, config) - } - } - } - return nil -} - -// upgradeServiceRole writes N new ServiceRoles if there are N rules in serviceRolePolicy. -// Before writing, it also removes the services field in each rule and add methods = ["*"] if necessary. -func (ug *Upgrader) upgradeServiceRole(serviceRolePolicy model.Config) error { - serviceRoleSpec := serviceRolePolicy.Spec.(*rbacproto.ServiceRole) - for i, rule := range serviceRoleSpec.Rules { - // newServiceRole is an individual ServiceRole broken from serviceRolePolicy because it has multiple - // rules. - newServiceRole := rbacproto.ServiceRole{} - newServiceRole.Rules = []*rbacproto.AccessRule{rule} - if rule.Methods == nil && rule.Paths == nil && rule.Constraints == nil { - // If `services` is the only field, we need to create `methods = ["*"]` - newServiceRole.Rules[0].Methods = []string{"*"} - } - newServiceRole.Rules[0].Services = nil - serviceRoleConfig := model.Config{ - ConfigMeta: serviceRolePolicy.ConfigMeta, - Spec: &newServiceRole, - } - serviceRoleConfig.Name = getNewRoleName(serviceRoleConfig.Name, len(serviceRoleSpec.Rules), i) - convertedRole, err := parseConfigToString(serviceRoleConfig) - if err != nil { - return err - } - ug.ConvertedPolicies.WriteString(convertedRole) - } - return nil -} - -// createAuthorizationPolicyFromRoleBinding creates AuthorizationPolicy from the given ServiceRoleBinding. -// In particular: -// * For each service in the referred ServiceRole from the ServiceRoleBinding, create an AuthorizationPolicy -// * If field `user` exists, change it to use `names` -// * If field `group` exists, change it to use `groups` -// * Change `roleRef` to use `role` -// * Create a list of binding with one element (serviceRoleBinding) and use workload selector. -func (ug *Upgrader) createAuthorizationPolicyFromRoleBinding(serviceRoleBinding model.Config) error { - bindingSpec := serviceRoleBinding.Spec.(*rbacproto.ServiceRoleBinding) - if bindingSpec.RoleRef == nil { - return fmt.Errorf("serviceRoleBinding %q does not have `roleRef` field", serviceRoleBinding.Name) - } - oldRoleName := bindingSpec.RoleRef.Name - refRole := ug.getServiceRole(bindingSpec.RoleRef.Name, serviceRoleBinding.Namespace) - if refRole == nil { - return fmt.Errorf("cannot find ServiceRole %q from ServiceRoleBinding %q", bindingSpec.RoleRef.Name, serviceRoleBinding.Name) - } - refRoleSpec := refRole.Spec.(*rbacproto.ServiceRole) - for i, rule := range refRoleSpec.Rules { - newRoleName := getNewRoleName(oldRoleName, len(refRoleSpec.Rules), i) - for j, serviceName := range rule.Services { - newAuthzPolicyName := getNewAuthzPolicyName(serviceRoleBinding.Name, len(refRoleSpec.Rules), i, len(rule.Services), j) - authzPolicy, err := ug.constructAuthorizationPolicy(serviceRoleBinding, serviceName, newRoleName, newAuthzPolicyName) - if err != nil { - return err - } - convertedAuthzPolicy, err := parseConfigToString(authzPolicy) - if err != nil { - return err - } - ug.ConvertedPolicies.WriteString(convertedAuthzPolicy) - } - } - return nil -} - -func (ug *Upgrader) constructAuthorizationPolicy(serviceRoleBinding model.Config, serviceName, newRoleName, newAuthzPolicyName string) (model.Config, error) { - bindingSpec := serviceRoleBinding.Spec.(*rbacproto.ServiceRoleBinding) - for _, subject := range bindingSpec.Subjects { - if subject.User != "" { - subject.Names = []string{subject.User} - subject.User = "" - } - if subject.Group != "" { - subject.Groups = []string{subject.Group} - subject.Group = "" - } - bindingSpec.RoleRef = nil - bindingSpec.Role = newRoleName - } - authzPolicy := rbacproto.AuthorizationPolicy{} - authzPolicy.Allow = []*rbacproto.ServiceRoleBinding{bindingSpec} - workloadLabels, err := ug.getAndAddServiceToWorkloadLabelMapping(serviceName, serviceRoleBinding.Namespace) - if err != nil { - return model.Config{}, err - } - if len(workloadLabels) > 0 { - authzPolicy.WorkloadSelector = &rbacproto.WorkloadSelector{Labels: workloadLabels} - } - authzPolicyConfig := model.Config{ - ConfigMeta: model.ConfigMeta{ - Type: model.AuthorizationPolicy.Type, - Group: serviceRoleBinding.Group, // model.AuthorizationPolicy.Group is "rbac", but we need "rbac.istio.io". - Version: model.AuthorizationPolicy.Version, - Name: newAuthzPolicyName, - Namespace: serviceRoleBinding.Namespace, - }, - Spec: &authzPolicy, - } - return authzPolicyConfig, nil -} - -// getAndAddServiceToWorkloadLabelMapping get the workload labels given the fullServiceName and namespace. It may -// update the NamespaceToServiceToWorkloadLabels map along the way if the data is not yet there. -func (ug *Upgrader) getAndAddServiceToWorkloadLabelMapping(fullServiceName, namespace string) (WorkloadLabels, error) { - // TODO: Handle suffix and prefix for services. - if fullServiceName == "*" { - return nil, nil - } - if strings.Contains(fullServiceName, "*") { - return nil, fmt.Errorf("wildcard * as prefix or suffix is not supported yet") - } - serviceName := strings.Split(fullServiceName, ".")[0] - - if _, found := ug.NamespaceToServiceToWorkloadLabels[namespace][serviceName]; !found { - // If NamespaceToServiceToWorkloadLabels does not have serviceName key yet, try fetching from Kubernetes apiserver. - err := ug.addServiceToWorkloadLabelMapping(namespace, serviceName) - if err != nil { - return nil, err - } - } - return ug.NamespaceToServiceToWorkloadLabels[namespace][serviceName], nil -} - -// getServiceRole return the ServiceRole (from the input file) in the provided namespace given the role name. -func (ug *Upgrader) getServiceRole(roleName, namespace string) *model.Config { - for _, serviceRole := range ug.serviceRoles { - if serviceRole.Name == roleName && serviceRole.Namespace == namespace { - return &serviceRole - } - } - return nil -} - -// addServiceToWorkloadLabelMapping maps the namespace and service name to workload labels that its rules originally -// applies to. -func (ug *Upgrader) addServiceToWorkloadLabelMapping(namespace, serviceName string) error { - if _, found := ug.NamespaceToServiceToWorkloadLabels[namespace][serviceName]; found { - return nil - } - - // TODO: cache the Service. - var service *v1.Service - if len(ug.ServiceFiles) != 0 { - svc := v1.Service{} - for _, filename := range ug.ServiceFiles { - fileBuf, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - reader := bytes.NewReader(fileBuf) - yamlDecoder := kubeyaml.NewYAMLOrJSONDecoder(reader, 512*1024) - for { - err = yamlDecoder.Decode(&svc) - if err == io.EOF { - break - } - if err != nil { - return fmt.Errorf("failed to parse k8s Service file: %s", err) - } - if svc.Name == serviceName && svc.Namespace == namespace { - service = &svc - break - } - } - } - } else { - var err error - service, err = ug.K8sClient.CoreV1().Services(namespace).Get(serviceName, metav1.GetOptions{}) - if err != nil { - return err - } - } - if service == nil { - return fmt.Errorf("no service found in namespace %s", namespace) - } - if service.Spec.Selector == nil { - return fmt.Errorf("failed because service %q does not have selector", serviceName) - } - // Maps need to be initialized (from lowest level outwards) before we can write to them. - if _, found := ug.NamespaceToServiceToWorkloadLabels[namespace][serviceName]; !found { - if _, found := ug.NamespaceToServiceToWorkloadLabels[namespace]; !found { - ug.NamespaceToServiceToWorkloadLabels[namespace] = make(ServiceToWorkloadLabels) - } - ug.NamespaceToServiceToWorkloadLabels[namespace][serviceName] = make(WorkloadLabels) - } - ug.NamespaceToServiceToWorkloadLabels[namespace][serviceName] = service.Spec.Selector - return nil -} - -// getNewRoleName returns a new name for the ServiceRole. If a ServiceRole has more than one rules, -// the new name will be oldName-ruleIndex -func getNewRoleName(oldRoleName string, lenRules, ruleIdx int) string { - newRoleName := oldRoleName - if lenRules > 1 { - newRoleName = fmt.Sprintf("%s-%s", newRoleName, strconv.Itoa(ruleIdx)) - } - return newRoleName -} - -// getNewAuthzPolicyName returns a new name for the AuthorizationPolicy from ServiceRoleBinding. -// The new name follow the format oldBindingName-lenRules-lenServices. -// If lenRules or lenServices is 0, they won't appear in the new name. -func getNewAuthzPolicyName(oldBindingName string, lenRules, ruleIdx, lenServices, svcIdx int) string { - newAuthzPolicyName := oldBindingName - if lenRules > 1 { - newAuthzPolicyName = fmt.Sprintf("%s-%s", newAuthzPolicyName, strconv.Itoa(ruleIdx)) - } - if lenServices > 1 { - newAuthzPolicyName = fmt.Sprintf("%s-%s", newAuthzPolicyName, strconv.Itoa(svcIdx)) - } - return newAuthzPolicyName -} diff --git a/istioctl/pkg/auth/upgrade_test.go b/istioctl/pkg/auth/upgrade_test.go deleted file mode 100644 index 00d729ea2712..000000000000 --- a/istioctl/pkg/auth/upgrade_test.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2019 Istio Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package auth - -import ( - "io/ioutil" - "reflect" - "testing" -) - -const ( - testFailedWithError = "test failed with error %v" - testFailedExpectedGot = "test [%s] failed.\nExpected\n%s\nGot\n%s" -) - -var ( - appProductPage = map[string]string{ - "app": "productpage", - } - appRatings = map[string]string{ - "app": "ratings", - } - appReviews = map[string]string{ - "app": "reviews", - } - - productPageMapping = map[string]WorkloadLabels{ - "productpage": appProductPage, - } - ratingsMapping = map[string]WorkloadLabels{ - "ratings": appRatings, - } -) - -type testCases struct { - testName string - input []string - workloadLabelMapping map[string]ServiceToWorkloadLabels - expected string -} - -func TestUpgradeLocalFile(t *testing.T) { - cases := []testCases{ - { - testName: "ServiceRole with only services", - input: []string{"./testdata/rbac-policies-services-only.yaml"}, - workloadLabelMapping: map[string]ServiceToWorkloadLabels{ - "default": productPageMapping, - }, - expected: "./testdata/rbac-policies-services-only-v2.golden.yaml", - }, - { - testName: "ServiceRole with methods and paths", - input: []string{"./testdata/rbac-policies-with-methods-and-paths.yaml", "./testdata/binding-ns-default-user-foo.yaml"}, - workloadLabelMapping: map[string]ServiceToWorkloadLabels{ - "default": ratingsMapping, - }, - expected: "./testdata/rbac-policies-with-methods-and-paths-v2.golden.yaml", - }, - { - testName: "Same ServiceRole name in multiple namespaces", - input: []string{"./testdata/rbac-policies-multiple-namespaces.yaml"}, - workloadLabelMapping: map[string]ServiceToWorkloadLabels{ - "foo": productPageMapping, - "bar": ratingsMapping, - }, - expected: "./testdata/rbac-policies-multiple-namespaces-v2.golden.yaml", - }, - { - input: []string{"./testdata/rbac-policies-multiple-rules.yaml", "./testdata/binding-ns-default-user-foo.yaml"}, - workloadLabelMapping: map[string]ServiceToWorkloadLabels{ - "default": { - "productpage": appProductPage, - "ratings": appRatings, - }, - }, - expected: "./testdata/rbac-policies-multiple-rules-v2.golden.yaml", - }, - { - input: []string{"./testdata/rbac-policies-multiple-services.yaml", "./testdata/binding-ns-default-user-foo.yaml"}, - workloadLabelMapping: map[string]ServiceToWorkloadLabels{ - "default": { - "productpage": appProductPage, - "ratings": appRatings, - }, - }, - expected: "./testdata/rbac-policies-multiple-services-v2.golden.yaml", - }, - { - input: []string{"./testdata/rbac-policies-multiple-rules-multiple-services.yaml", "./testdata/binding-ns-default-user-foo.yaml"}, - workloadLabelMapping: map[string]ServiceToWorkloadLabels{ - "default": { - "productpage": appProductPage, - "ratings": appRatings, - "reviews": appReviews, - }, - }, - expected: "./testdata/rbac-policies-multiple-rules-multiple-services-v2.golden.yaml", - }, - } - - for _, tc := range cases { - upgrader := Upgrader{ - V1PolicyFiles: tc.input, - NamespaceToServiceToWorkloadLabels: tc.workloadLabelMapping, - } - err := upgrader.UpgradeCRDs() - if err != nil { - t.Errorf(testFailedWithError, err) - } - gotContent := upgrader.ConvertedPolicies.String() - expectedContent, err := ioutil.ReadFile(tc.expected) - if err != nil { - t.Errorf(testFailedWithError, err) - } - if !reflect.DeepEqual(string(expectedContent), gotContent) { - t.Errorf(testFailedExpectedGot, tc.testName, string(expectedContent), gotContent) - } - } -} diff --git a/pilot/pkg/config/kube/crd/types.go b/pilot/pkg/config/kube/crd/types.go index 20cbb9d3d66d..aaace51d5760 100644 --- a/pilot/pkg/config/kube/crd/types.go +++ b/pilot/pkg/config/kube/crd/types.go @@ -185,16 +185,6 @@ var KnownTypes = map[string]SchemaType{ }, Collection: &ServiceRoleBindingList{}, }, - model.AuthorizationPolicy.Type: { - Schema: model.AuthorizationPolicy, - Object: &AuthorizationPolicy{ - TypeMeta: meta_v1.TypeMeta{ - Kind: "AuthorizationPolicy", - APIVersion: APIVersion(&model.AuthorizationPolicy), - }, - }, - Collection: &AuthorizationPolicyList{}, - }, model.RbacConfig.Type: { Schema: model.RbacConfig, Object: &RbacConfig{ @@ -1762,109 +1752,6 @@ func (in *ServiceRoleBindingList) DeepCopyObject() runtime.Object { return nil } -// AuthorizationPolicy is the generic Kubernetes API Object wrapper -type AuthorizationPolicy struct { - meta_v1.TypeMeta `json:",inline"` - meta_v1.ObjectMeta `json:"metadata"` - Spec map[string]interface{} `json:"spec"` -} - -// GetSpec from a wrapper -func (in *AuthorizationPolicy) GetSpec() map[string]interface{} { - return in.Spec -} - -// SetSpec for a wrapper -func (in *AuthorizationPolicy) SetSpec(spec map[string]interface{}) { - in.Spec = spec -} - -// GetObjectMeta from a wrapper -func (in *AuthorizationPolicy) GetObjectMeta() meta_v1.ObjectMeta { - return in.ObjectMeta -} - -// SetObjectMeta for a wrapper -func (in *AuthorizationPolicy) SetObjectMeta(metadata meta_v1.ObjectMeta) { - in.ObjectMeta = metadata -} - -// AuthorizationPolicyList is the generic Kubernetes API list wrapper -type AuthorizationPolicyList struct { - meta_v1.TypeMeta `json:",inline"` - meta_v1.ListMeta `json:"metadata"` - Items []AuthorizationPolicy `json:"items"` -} - -// GetItems from a wrapper -func (in *AuthorizationPolicyList) GetItems() []IstioObject { - out := make([]IstioObject, len(in.Items)) - for i := range in.Items { - out[i] = &in.Items[i] - } - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthorizationPolicy) DeepCopyInto(out *AuthorizationPolicy) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationPolicy. -func (in *AuthorizationPolicy) DeepCopy() *AuthorizationPolicy { - if in == nil { - return nil - } - out := new(AuthorizationPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *AuthorizationPolicy) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthorizationPolicyList) DeepCopyInto(out *AuthorizationPolicyList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]AuthorizationPolicy, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationPolicyList. -func (in *AuthorizationPolicyList) DeepCopy() *AuthorizationPolicyList { - if in == nil { - return nil - } - out := new(AuthorizationPolicyList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *AuthorizationPolicyList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - - return nil -} - // RbacConfig is the generic Kubernetes API Object wrapper type RbacConfig struct { meta_v1.TypeMeta `json:",inline"` diff --git a/pilot/pkg/model/authorization.go b/pilot/pkg/model/authorization.go index cbc910c9cfc5..4010ca86e695 100644 --- a/pilot/pkg/model/authorization.go +++ b/pilot/pkg/model/authorization.go @@ -15,8 +15,6 @@ package model import ( - "fmt" - rbacproto "istio.io/api/rbac/v1alpha1" istiolog "istio.io/pkg/log" ) @@ -36,17 +34,13 @@ type RolesAndBindings struct { // AuthorizationPolicyConfig stores the AuthorizationPolicy and its name. type AuthorizationPolicyConfig struct { - Name string - Policy *rbacproto.AuthorizationPolicy + Name string } // AuthorizationConfigV2 stores a list of AuthorizationPolicyConfig and ServiceRole in a given namespace. type AuthorizationConfigV2 struct { // A list of AuthorizationPolicyConfig. AuthzPolicies []*AuthorizationPolicyConfig - - // Maps from name to ServiceRole. - NameToServiceRoles map[string]*rbacproto.ServiceRole } // AuthorizationPolicies stores all authorization policies (i.e. ServiceRole, ServiceRoleBinding and @@ -85,14 +79,6 @@ func (policy *AuthorizationPolicies) addServiceRole(role *Config) { if policy.NamespaceToAuthorizationConfigV2 == nil { policy.NamespaceToAuthorizationConfigV2 = map[string]*AuthorizationConfigV2{} } - if policy.NamespaceToAuthorizationConfigV2[role.Namespace] == nil { - policy.NamespaceToAuthorizationConfigV2[role.Namespace] = &AuthorizationConfigV2{ - AuthzPolicies: []*AuthorizationPolicyConfig{}, - NameToServiceRoles: map[string]*rbacproto.ServiceRole{}, - } - } - authzV2 := policy.NamespaceToAuthorizationConfigV2[role.Namespace] - authzV2.NameToServiceRoles[role.Name] = role.Spec.(*rbacproto.ServiceRole) } func (policy *AuthorizationPolicies) addServiceRoleBinding(binding *Config) { @@ -122,30 +108,7 @@ func (policy *AuthorizationPolicies) addServiceRoleBinding(binding *Config) { rolesAndBindings.RoleNameToBindings[name], binding.Spec.(*rbacproto.ServiceRoleBinding)) } -func (policy *AuthorizationPolicies) addAuthorizationPolicy(authzPolicy *Config) { - if authzPolicy == nil || authzPolicy.Spec.(*rbacproto.AuthorizationPolicy) == nil { - return - } - - // Initialize AuthzPolicies for authz v2. - if policy.NamespaceToAuthorizationConfigV2 == nil { - policy.NamespaceToAuthorizationConfigV2 = map[string]*AuthorizationConfigV2{} - } - if policy.NamespaceToAuthorizationConfigV2[authzPolicy.Namespace] == nil { - policy.NamespaceToAuthorizationConfigV2[authzPolicy.Namespace] = &AuthorizationConfigV2{ - AuthzPolicies: []*AuthorizationPolicyConfig{}, - NameToServiceRoles: map[string]*rbacproto.ServiceRole{}, - } - } - authzV2 := policy.NamespaceToAuthorizationConfigV2[authzPolicy.Namespace] - authzV2.AuthzPolicies = append(authzV2.AuthzPolicies, &AuthorizationPolicyConfig{ - Name: authzPolicy.Name, - Policy: authzPolicy.Spec.(*rbacproto.AuthorizationPolicy), - }) -} - -// AddConfig adds a config of type ServiceRole, ServiceRoleBinding or AuthorizationPolicy to -// AuthorizationPolicies. +// AddConfig adds a config of type ServiceRole, ServiceRoleBinding to AuthorizationPolicies. func (policy *AuthorizationPolicies) AddConfig(cfgs ...*Config) { for _, cfg := range cfgs { if cfg == nil { @@ -156,8 +119,6 @@ func (policy *AuthorizationPolicies) AddConfig(cfgs ...*Config) { policy.addServiceRole(cfg) case *rbacproto.ServiceRoleBinding: policy.addServiceRoleBinding(cfg) - case *rbacproto.AuthorizationPolicy: - policy.addAuthorizationPolicy(cfg) } } } @@ -190,23 +151,6 @@ func (policy *AuthorizationPolicies) RoleToBindingsForNamespace(ns string) map[s return rolesAndBindings.RoleNameToBindings } -// RoleForNameAndNamespace returns a ServiceRole from this namespace, given the ServiceRole name and namespace. -// This function always return a non nil struct instance. -func (policy *AuthorizationPolicies) RoleForNameAndNamespace(roleName, ns string) *rbacproto.ServiceRole { - if policy == nil || policy.NamespaceToAuthorizationConfigV2 == nil { - return &rbacproto.ServiceRole{} - } - nsToAuthzConfigV2 := policy.NamespaceToAuthorizationConfigV2[ns] - if nsToAuthzConfigV2 == nil { - return &rbacproto.ServiceRole{} - } - serviceRole, exist := nsToAuthzConfigV2.NameToServiceRoles[roleName] - if !exist { - return &rbacproto.ServiceRole{} - } - return serviceRole -} - // NewAuthzPolicies returns the AuthorizationPolicies constructed from raw authorization policies by // storing policies into different namespaces. func NewAuthzPolicies(env *Environment) (*AuthorizationPolicies, error) { @@ -241,19 +185,5 @@ func NewAuthzPolicies(env *Environment) (*AuthorizationPolicies, error) { policy.AddConfig(&binding) } - v2Policies, err := env.List(AuthorizationPolicy.Type, NamespaceAll) - if err != nil { - return nil, err - } - if len(v2Policies) > 0 { - if len(bindings) > 0 { - return nil, fmt.Errorf("had both AuthorizationPolicy and ServiceRoleBinding") - } - policy.IsRbacV2 = true - } - for _, v2Policy := range v2Policies { - policy.AddConfig(&v2Policy) - } - return policy, nil } diff --git a/pilot/pkg/model/authorization_test.go b/pilot/pkg/model/authorization_test.go index a43ef1d99b8d..c9f19dae2e64 100644 --- a/pilot/pkg/model/authorization_test.go +++ b/pilot/pkg/model/authorization_test.go @@ -41,15 +41,6 @@ func TestAddConfig(t *testing.T) { RoleRef: &rbacproto.RoleRef{Kind: "ServiceRole", Name: "test-role-1"}, }, } - authzCfg := model.Config{ - ConfigMeta: model.ConfigMeta{ - Type: model.AuthorizationPolicy.Type, Name: "test-authz-1", Namespace: model.NamespaceAll}, - Spec: &rbacproto.AuthorizationPolicy{ - WorkloadSelector: &rbacproto.WorkloadSelector{ - Labels: map[string]string{"app": "test"}, - }, - }, - } invalidateBindingCfg := model.Config{ ConfigMeta: model.ConfigMeta{ @@ -95,24 +86,6 @@ func TestAddConfig(t *testing.T) { }, }, }, - { - name: "test add config for AuthorizationPolicy", - config: []model.Config{authzCfg, roleCfg}, - authzPolicies: &model.AuthorizationPolicies{}, - expectedAuthorizationConfigV2: &model.AuthorizationConfigV2{ - AuthzPolicies: []*model.AuthorizationPolicyConfig{ - { - Name: "test-authz-1", Policy: &rbacproto.AuthorizationPolicy{ - WorkloadSelector: &rbacproto.WorkloadSelector{ - Labels: map[string]string{"app": "test"}, - }, - }}, - }, - NameToServiceRoles: map[string]*rbacproto.ServiceRole{ - "test-role-1": {Rules: []*rbacproto.AccessRule{{Services: []string{"test-svc-1"}}}}, - }, - }, - }, { name: "test add config for both ServiceRoleBinding and ServiceRole", config: []model.Config{roleCfg, bindingCfg}, @@ -305,58 +278,6 @@ func TestRoleToBindingsForNamespace(t *testing.T) { } } -func TestRoleForNameAndNamespace(t *testing.T) { - cases := []struct { - name string - authzPolicies *model.AuthorizationPolicies - ns string - roleName string - expectedTestRoleForNameAndNamespace *rbacproto.ServiceRole - }{ - { - name: "authzPolicies is nil", - authzPolicies: nil, - ns: model.NamespaceAll, - roleName: "", - expectedTestRoleForNameAndNamespace: &rbacproto.ServiceRole{}, - }, - { - name: "authzPolicies has one ServiceRole", - authzPolicies: &model.AuthorizationPolicies{ - NamespaceToAuthorizationConfigV2: map[string]*model.AuthorizationConfigV2{ - "default": { - AuthzPolicies: []*model.AuthorizationPolicyConfig{ - { - Name: "Authz-Policy-1", - Policy: &rbacproto.AuthorizationPolicy{}, - }, - }, - NameToServiceRoles: map[string]*rbacproto.ServiceRole{ - "test-svc-1": { - Rules: []*rbacproto.AccessRule{{Services: []string{"test-svc-1"}}}, - }, - }, - }, - }, - }, - ns: "default", - roleName: "test-svc-1", - expectedTestRoleForNameAndNamespace: &rbacproto.ServiceRole{ - Rules: []*rbacproto.AccessRule{{Services: []string{"test-svc-1"}}}, - }, - }, - } - - for _, c := range cases { - t.Run(c.name, func(t *testing.T) { - actual := c.authzPolicies.RoleForNameAndNamespace(c.roleName, c.ns) - if !reflect.DeepEqual(c.expectedTestRoleForNameAndNamespace, actual) { - t.Errorf("Got different ServiceRole, Got: \n%v\n, Excepted:\n%v\n", actual, c.expectedTestRoleForNameAndNamespace) - } - }) - } -} - func TestNewAuthzPolicies(t *testing.T) { clusterRbacConfig := &rbacproto.RbacConfig{Mode: rbacproto.RbacConfig_ON} rbacConfig := &rbacproto.RbacConfig{Mode: rbacproto.RbacConfig_OFF} diff --git a/pilot/pkg/model/config.go b/pilot/pkg/model/config.go index 28c6582472e2..a95fbed1158a 100644 --- a/pilot/pkg/model/config.go +++ b/pilot/pkg/model/config.go @@ -285,9 +285,6 @@ type IstioConfigStore interface { // ServiceRoleBindings selects ServiceRoleBindings in the specified namespace. ServiceRoleBindings(namespace string) []Config - // AuthorizationPolicies selects AuthorizationPolicies in the specified namespace. - AuthorizationPolicies(namespace string) []Config - // RbacConfig selects the RbacConfig of name DefaultRbacConfigName. RbacConfig() *Config @@ -489,18 +486,6 @@ var ( Collection: metadata.IstioRbacV1alpha1Servicerolebindings.Collection.String(), } - // AuthorizationPolicy describes an authorization policy. - AuthorizationPolicy = ProtoSchema{ - ClusterScoped: false, - Type: "authorization-policy", - Plural: "authorization-policies", - Group: "rbac", - Version: "v1alpha1", - MessageName: "istio.rbac.v1alpha1.AuthorizationPolicy", - Validate: config.ValidateAuthorizationPolicy, - Collection: metadata.IstioRbacV1alpha1Authorizationpolicies.Collection.String(), - } - // RbacConfig describes the mesh level RBAC config. // Deprecated: use ClusterRbacConfig instead. // See https://github.com/istio/istio/issues/8825 for more details. @@ -542,7 +527,6 @@ var ( AuthenticationMeshPolicy, ServiceRole, ServiceRoleBinding, - AuthorizationPolicy, RbacConfig, ClusterRbacConfig, } @@ -988,16 +972,6 @@ func (store *istioConfigStore) ServiceRoleBindings(namespace string) []Config { return bindings } -func (store *istioConfigStore) AuthorizationPolicies(namespace string) []Config { - authorizationPolicies, err := store.List(AuthorizationPolicy.Type, namespace) - if err != nil { - log.Errorf("failed to get AuthorizationPolicy in namespace %s: %v", namespace, err) - return nil - } - - return authorizationPolicies -} - func (store *istioConfigStore) ClusterRbacConfig() *Config { clusterRbacConfig, err := store.List(ClusterRbacConfig.Type, "") if err != nil { diff --git a/pilot/pkg/model/config_test.go b/pilot/pkg/model/config_test.go index 31fbb07aa407..9b40b4cda847 100644 --- a/pilot/pkg/model/config_test.go +++ b/pilot/pkg/model/config_test.go @@ -694,34 +694,6 @@ func TestServiceRoleBindings(t *testing.T) { } } -func TestAuthorizationPolicies(t *testing.T) { - store := model.MakeIstioStore(memory.Make(model.IstioConfigTypes)) - addRbacConfigToStore(model.AuthorizationPolicy.Type, "policy1", "istio-system", store, t) - addRbacConfigToStore(model.AuthorizationPolicy.Type, "policy2", "default", store, t) - addRbacConfigToStore(model.AuthorizationPolicy.Type, "policy3", "istio-system", store, t) - tests := []struct { - namespace string - expectName map[string]bool - }{ - {namespace: "wrong", expectName: nil}, - {namespace: "default", expectName: map[string]bool{"policy2": true}}, - {namespace: "istio-system", expectName: map[string]bool{"policy1": true, "policy3": true}}, - } - - for _, tt := range tests { - cfg := store.AuthorizationPolicies(tt.namespace) - if tt.expectName != nil { - for _, cfg := range cfg { - if !tt.expectName[cfg.Name] { - t.Errorf("model.AuthorizationPolicy: expecting %v, but got %v", tt.expectName, cfg) - } - } - } else if len(cfg) != 0 { - t.Errorf("model.AuthorizationPolicy: expecting nil, but got %v", cfg) - } - } -} - func TestRbacConfig(t *testing.T) { store := model.MakeIstioStore(memory.Make(model.IstioConfigTypes)) addRbacConfigToStore(model.RbacConfig.Type, constants.DefaultRbacConfigName, "", store, t) @@ -750,12 +722,6 @@ func addRbacConfigToStore(configType, name, namespace string, store model.IstioC value = &rbacproto.ServiceRoleBinding{ Subjects: []*rbacproto.Subject{{User: "User0"}}, RoleRef: &rbacproto.RoleRef{Kind: "ServiceRole", Name: "ServiceRole001"}} - case model.AuthorizationPolicy.Type: - value = &rbacproto.AuthorizationPolicy{ - WorkloadSelector: &rbacproto.WorkloadSelector{ - Labels: map[string]string{"app": "test"}, - }, - } default: value = &rbacproto.RbacConfig{Mode: rbacproto.RbacConfig_ON} } diff --git a/pilot/pkg/networking/core/v1alpha3/fakes/fake_istio_config_store.go b/pilot/pkg/networking/core/v1alpha3/fakes/fake_istio_config_store.go index 74ed5e1a7ef3..41d48f8effa6 100644 --- a/pilot/pkg/networking/core/v1alpha3/fakes/fake_istio_config_store.go +++ b/pilot/pkg/networking/core/v1alpha3/fakes/fake_istio_config_store.go @@ -172,17 +172,6 @@ type IstioConfigStore struct { serviceRoleBindingsReturnsOnCall map[int]struct { result1 []model.Config } - AuthorizationPoliciesStub func(namespace string) []model.Config - authorizationPoliciesMutex sync.RWMutex - authorizationPoliciesArgsForCall []struct { - namespace string - } - authorizationPoliciesReturns struct { - result1 []model.Config - } - authorizationPoliciesReturnsOnCall map[int]struct { - result1 []model.Config - } RbacConfigStub func() *model.Config rbacConfigMutex sync.RWMutex rbacConfigArgsForCall []struct{} @@ -877,54 +866,6 @@ func (fake *IstioConfigStore) ServiceRoleBindingsReturnsOnCall(i int, result1 [] }{result1} } -func (fake *IstioConfigStore) AuthorizationPolicies(namespace string) []model.Config { - fake.authorizationPoliciesMutex.Lock() - ret, specificReturn := fake.authorizationPoliciesReturnsOnCall[len(fake.authorizationPoliciesArgsForCall)] - fake.authorizationPoliciesArgsForCall = append(fake.authorizationPoliciesArgsForCall, struct { - namespace string - }{namespace}) - fake.recordInvocation("AuthorizationPolicies", []interface{}{namespace}) - fake.authorizationPoliciesMutex.Unlock() - if fake.AuthorizationPoliciesStub != nil { - return fake.AuthorizationPoliciesStub(namespace) - } - if specificReturn { - return ret.result1 - } - return fake.authorizationPoliciesReturns.result1 -} - -func (fake *IstioConfigStore) AuthorizationPoliciesCallCount() int { - fake.authorizationPoliciesMutex.RLock() - defer fake.authorizationPoliciesMutex.RUnlock() - return len(fake.authorizationPoliciesArgsForCall) -} - -func (fake *IstioConfigStore) AuthorizationPoliciesArgsForCall(i int) string { - fake.authorizationPoliciesMutex.RLock() - defer fake.authorizationPoliciesMutex.RUnlock() - return fake.authorizationPoliciesArgsForCall[i].namespace -} - -func (fake *IstioConfigStore) AuthorizationPoliciesReturns(result1 []model.Config) { - fake.AuthorizationPoliciesStub = nil - fake.authorizationPoliciesReturns = struct { - result1 []model.Config - }{result1} -} - -func (fake *IstioConfigStore) AuthorizationPoliciesReturnsOnCall(i int, result1 []model.Config) { - fake.AuthorizationPoliciesStub = nil - if fake.authorizationPoliciesReturnsOnCall == nil { - fake.authorizationPoliciesReturnsOnCall = make(map[int]struct { - result1 []model.Config - }) - } - fake.authorizationPoliciesReturnsOnCall[i] = struct { - result1 []model.Config - }{result1} -} - func (fake *IstioConfigStore) RbacConfig() *model.Config { fake.rbacConfigMutex.Lock() ret, specificReturn := fake.rbacConfigReturnsOnCall[len(fake.rbacConfigArgsForCall)] @@ -1036,8 +977,6 @@ func (fake *IstioConfigStore) Invocations() map[string][][]interface{} { defer fake.serviceRolesMutex.RUnlock() fake.serviceRoleBindingsMutex.RLock() defer fake.serviceRoleBindingsMutex.RUnlock() - fake.authorizationPoliciesMutex.RLock() - defer fake.authorizationPoliciesMutex.RUnlock() fake.rbacConfigMutex.RLock() defer fake.rbacConfigMutex.RUnlock() fake.clusterRbacConfigMutex.RLock() diff --git a/pilot/pkg/security/authz/policy/helper.go b/pilot/pkg/security/authz/policy/helper.go index 1429d19b7c69..495d43f947a7 100644 --- a/pilot/pkg/security/authz/policy/helper.go +++ b/pilot/pkg/security/authz/policy/helper.go @@ -170,32 +170,6 @@ func AuthzPolicyTag(name string) string { return fmt.Sprintf("UserFromPolicy[%s]", name) } -func SimpleAuthorizationPolicy(name string, namespace string, labels map[string]string, role string) *model.Config { - cfg := &model.Config{ - ConfigMeta: model.ConfigMeta{ - Type: model.AuthorizationPolicy.Type, - Name: name, - Namespace: namespace, - }, - Spec: &istio_rbac.AuthorizationPolicy{ - WorkloadSelector: &istio_rbac.WorkloadSelector{ - Labels: labels, - }, - Allow: []*istio_rbac.ServiceRoleBinding{ - { - Subjects: []*istio_rbac.Subject{ - { - User: AuthzPolicyTag(name), - }, - }, - Role: role, - }, - }, - }, - } - return cfg -} - func Verify(got *envoy_rbac.RBAC, want map[string][]string) error { var err error if len(want) == 0 { diff --git a/pilot/pkg/security/authz/policy/v2/v2.go b/pilot/pkg/security/authz/policy/v2/v2.go index 6a9b153dac80..8a109b2b46f9 100644 --- a/pilot/pkg/security/authz/policy/v2/v2.go +++ b/pilot/pkg/security/authz/policy/v2/v2.go @@ -15,27 +15,14 @@ package v2 import ( - "fmt" - "strings" - http_config "github.com/envoyproxy/go-control-plane/envoy/config/filter/http/rbac/v2" envoy_rbac "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v2" - istio_rbac "istio.io/api/rbac/v1alpha1" istiolog "istio.io/pkg/log" "istio.io/istio/pilot/pkg/model" authz_model "istio.io/istio/pilot/pkg/security/authz/model" "istio.io/istio/pilot/pkg/security/authz/policy" - "istio.io/istio/pkg/config/labels" - "istio.io/istio/pkg/config/mesh" -) - -const ( - // rootNamespacePrefix is the prefix of the root namespace. This is used to refer to ServiceRoles - // that are defined in the root namespace. - // For more details, check out root_namespace field at https://github.com/istio/api/blob/master/mesh/v1alpha1/config.proto - rootNamespacePrefix = "/" ) var ( @@ -79,60 +66,10 @@ func (b *v2Generator) Generate(forTCPFilter bool) *http_config.RBAC { if authzPolicies.NamespaceToAuthorizationConfigV2 == nil { return &http_config.RBAC{Rules: rbac} } - var authzConfigV2, present = authzPolicies.NamespaceToAuthorizationConfigV2[namespace] + var _, present = authzPolicies.NamespaceToAuthorizationConfigV2[namespace] if !present { return &http_config.RBAC{Rules: rbac} } - for _, authzPolicy := range authzConfigV2.AuthzPolicies { - workloadLabels := labels.Collection{serviceMetadata.Labels} - policySelector := authzPolicy.Policy.WorkloadSelector.GetLabels() - if !(workloadLabels.IsSupersetOf(policySelector)) { - // Skip if the workload labels is not a superset of the policy selector (i.e. the workload - // is not selected by the policy). - continue - } - - for i, binding := range authzPolicy.Policy.Allow { - // TODO: optimize for multiple bindings referring to the same role. - roleName, role := roleForBinding(binding, namespace, authzPolicies) - bindings := []*istio_rbac.ServiceRoleBinding{binding} - if p := b.generatePolicy(role, bindings, forTCPFilter); p != nil { - rbacLog.Debugf("generated policy for role: %s", roleName) - policyName := fmt.Sprintf("authz-[%s]-allow[%d]", authzPolicy.Name, i) - rbac.Policies[policyName] = p - } - } - } + // TODO(yangminzhu): Implement the new authorization v1beta1 policy. return &http_config.RBAC{Rules: rbac} } - -// TODO: refactor this into model.AuthorizationPolicies. -func roleForBinding(binding *istio_rbac.ServiceRoleBinding, namespace string, ap *model.AuthorizationPolicies) (string, *istio_rbac.ServiceRole) { - var role *istio_rbac.ServiceRole - var name string - if binding.RoleRef != nil { - role = ap.RoleForNameAndNamespace(binding.RoleRef.Name, namespace) - name = binding.RoleRef.Name - } else if binding.Role != "" { - if strings.HasPrefix(binding.Role, rootNamespacePrefix) { - globalRoleName := strings.TrimPrefix(binding.Role, rootNamespacePrefix) - role = ap.RoleForNameAndNamespace(globalRoleName, mesh.DefaultMeshConfig().RootNamespace) - } else { - role = ap.RoleForNameAndNamespace(binding.Role, namespace) - } - name = binding.Role - } else if len(binding.Actions) > 0 { - role = &istio_rbac.ServiceRole{Rules: binding.Actions} - name = "%s-inline-role" - } - return name, role -} - -func (b *v2Generator) generatePolicy(role *istio_rbac.ServiceRole, bindings []*istio_rbac.ServiceRoleBinding, forTCPFilter bool) *envoy_rbac.Policy { - if role == nil || len(bindings) == 0 { - return nil - } - - m := authz_model.NewModel(role, bindings) - return m.Generate(b.serviceMetadata, forTCPFilter) -} diff --git a/pilot/pkg/security/authz/policy/v2/v2_test.go b/pilot/pkg/security/authz/policy/v2/v2_test.go index d77c3e141b07..2d15d886b361 100644 --- a/pilot/pkg/security/authz/policy/v2/v2_test.go +++ b/pilot/pkg/security/authz/policy/v2/v2_test.go @@ -27,11 +27,6 @@ func TestBuilder_buildV2(t *testing.T) { labelFoo := map[string]string{ "app": "foo", } - namespaceA := "a" - labelBar := map[string]string{ - "app": "bar", - } - namespaceB := "b" serviceFooInNamespaceA := policy.NewServiceMetadata("foo.a.svc.cluster.local", labelFoo, t) testCases := []struct { name string @@ -42,85 +37,6 @@ func TestBuilder_buildV2(t *testing.T) { { name: "no policy", }, - { - name: "no policy in namespace a", - policies: []*model.Config{ - policy.SimpleRole("role", namespaceB, ""), - policy.SimpleAuthorizationPolicy("policy", namespaceB, labelFoo, "role"), - }, - }, - { - name: "no policy matched for workload foo", - policies: []*model.Config{ - policy.SimpleRole("role", namespaceA, ""), - policy.SimpleAuthorizationPolicy("policy", namespaceA, labelBar, "role"), - }, - }, - { - name: "no role for workload foo", - policies: []*model.Config{ - policy.SimpleAuthorizationPolicy("policy-1", namespaceA, labelFoo, "role-1"), - policy.SimpleRole("role-2", namespaceA, ""), - policy.SimpleAuthorizationPolicy("policy-2", namespaceA, labelBar, "role-2"), - policy.SimpleRole("role-3", namespaceB, ""), - policy.SimpleAuthorizationPolicy("policy-3", namespaceB, labelFoo, "role-3"), - }, - }, - { - name: "one policy and one role", - policies: []*model.Config{ - policy.SimpleRole("role", namespaceA, ""), - policy.SimpleAuthorizationPolicy("policy", namespaceA, labelFoo, "role"), - }, - wantRules: map[string][]string{ - "authz-[policy]-allow[0]": {policy.RoleTag("role"), policy.AuthzPolicyTag("policy")}, - }, - }, - { - name: "one policy and one role: forTCPFilter", - policies: []*model.Config{ - policy.SimpleRole("role", namespaceA, ""), - policy.SimpleAuthorizationPolicy("policy", namespaceA, labelFoo, "role"), - }, - forTCPFilter: true, - }, - { - name: "two policies and one role", - policies: []*model.Config{ - policy.SimpleRole("role", namespaceA, ""), - policy.SimpleAuthorizationPolicy("policy-1", namespaceA, labelFoo, "role"), - policy.SimpleAuthorizationPolicy("policy-2", namespaceA, labelFoo, "role"), - }, - wantRules: map[string][]string{ - "authz-[policy-1]-allow[0]": { - policy.RoleTag("role"), - policy.AuthzPolicyTag("policy-1"), - }, - "authz-[policy-2]-allow[0]": { - policy.RoleTag("role"), - policy.AuthzPolicyTag("policy-2"), - }, - }, - }, - { - name: "two policies and two roles", - policies: []*model.Config{ - policy.SimpleRole("role-1", namespaceA, ""), - policy.SimpleAuthorizationPolicy("policy-1", namespaceA, labelFoo, "role-1"), - policy.SimpleRole("role-2", namespaceA, ""), - policy.SimpleAuthorizationPolicy("policy-2", namespaceA, labelFoo, "role-2"), - }, - wantRules: map[string][]string{ - "authz-[policy-1]-allow[0]": { - policy.RoleTag("role-1"), - policy.AuthzPolicyTag("policy-1"), - }, - "authz-[policy-2]-allow[0]": { - policy.RoleTag("role-2"), - policy.AuthzPolicyTag("policy-2"), - }, - }, - }, } for _, tc := range testCases { diff --git a/pilot/test/mock/config.go b/pilot/test/mock/config.go index 0b0d418af1c3..fefb77371ae1 100644 --- a/pilot/test/mock/config.go +++ b/pilot/test/mock/config.go @@ -201,15 +201,6 @@ var ( RoleRef: &rbac.RoleRef{Kind: "ServiceRole", Name: "ServiceRole001"}, } - ExampleAuthorizationPolicy = &rbac.AuthorizationPolicy{ - WorkloadSelector: &rbac.WorkloadSelector{ - Labels: map[string]string{ - "app": "httpbin", - "version": "v1", - }, - }, - } - // ExampleRbacConfig is an example rbac config ExampleRbacConfig = &rbac.RbacConfig{ Mode: rbac.RbacConfig_ON, @@ -441,7 +432,6 @@ func CheckIstioConfigTypes(store model.ConfigStore, namespace string, t *testing {"Policy", configName, model.AuthenticationPolicy, ExampleAuthenticationPolicy}, {"ServiceRole", configName, model.ServiceRole, ExampleServiceRole}, {"ServiceRoleBinding", configName, model.ServiceRoleBinding, ExampleServiceRoleBinding}, - {"AuthorizationPolicy", configName, model.AuthorizationPolicy, ExampleAuthorizationPolicy}, {"RbacConfig", constants.DefaultRbacConfigName, model.RbacConfig, ExampleRbacConfig}, {"ClusterRbacConfig", constants.DefaultRbacConfigName, model.ClusterRbacConfig, ExampleRbacConfig}, } diff --git a/pkg/config/validation.go b/pkg/config/validation.go index 2a4e9d2cfd90..d45cff562d43 100644 --- a/pkg/config/validation.go +++ b/pkg/config/validation.go @@ -1585,20 +1585,6 @@ func ValidateServiceRoleBinding(_, _ string, msg proto.Message) error { return checkServiceRoleBinding(in) } -// ValidateAuthorizationPolicy checks that AuthorizationPolicy is well-formed. -func ValidateAuthorizationPolicy(_, _ string, msg proto.Message) error { - in, ok := msg.(*rbac.AuthorizationPolicy) - if !ok { - return errors.New("cannot cast to AuthorizationPolicy") - } - for _, binding := range in.Allow { - if err := checkServiceRoleBinding(binding); err != nil { - return err - } - } - return nil -} - // isFirstClassFieldEmpty return false if there is at least one first class field (e.g. properties) func isFirstClassFieldEmpty(subject *rbac.Subject) bool { return len(subject.User) == 0 && len(subject.Group) == 0 && len(subject.Properties) == 0 && diff --git a/pkg/config/validation_test.go b/pkg/config/validation_test.go index 821389faaa1f..c2ea37a6ff50 100644 --- a/pkg/config/validation_test.go +++ b/pkg/config/validation_test.go @@ -4034,167 +4034,6 @@ func TestValidateServiceRoleBinding(t *testing.T) { } } -func TestValidateAuthorizationPolicy(t *testing.T) { - cases := []struct { - name string - in proto.Message - expectErrMsg string - }{ - { - name: "invalid proto", - expectErrMsg: "cannot cast to AuthorizationPolicy", - }, - { - name: "proto with no roleRef or inline role definition", - in: &rbac.AuthorizationPolicy{ - Allow: []*rbac.ServiceRoleBinding{ - { - Subjects: []*rbac.Subject{ - { - Namespaces: []string{"default, istio-system"}, - }, - }, - }, - }, - }, - expectErrMsg: "exactly one of `roleRef`, `role`, or `actions` must be specified", - }, - { - name: "proto with both roleRef and inline role definition", - in: &rbac.AuthorizationPolicy{ - Allow: []*rbac.ServiceRoleBinding{ - { - Subjects: []*rbac.Subject{ - { - Namespaces: []string{"default, istio-system"}, - }, - }, - RoleRef: &rbac.RoleRef{ - Kind: "ServiceRole", - Name: "service-role-1", - }, - Actions: []*rbac.AccessRule{ - { - Ports: []int32{3000}, - }, - }, - }, - }, - }, - expectErrMsg: "exactly one of `roleRef`, `role`, or `actions` must be specified", - }, - { - name: "proto with both roleRef and role", - in: &rbac.AuthorizationPolicy{ - Allow: []*rbac.ServiceRoleBinding{ - { - Subjects: []*rbac.Subject{ - { - Namespaces: []string{"default, istio-system"}, - }, - }, - RoleRef: &rbac.RoleRef{ - Kind: "ServiceRole", - Name: "service-role-1", - }, - Role: "service-role-1", - }, - }, - }, - expectErrMsg: "exactly one of `roleRef`, `role`, or `actions` must be specified", - }, - { - name: "proto with both role and inline role definition", - in: &rbac.AuthorizationPolicy{ - Allow: []*rbac.ServiceRoleBinding{ - { - Subjects: []*rbac.Subject{ - { - Namespaces: []string{"default, istio-system"}, - }, - }, - Role: "service-role-1", - Actions: []*rbac.AccessRule{ - { - Ports: []int32{3000}, - }, - }, - }, - }, - }, - expectErrMsg: "exactly one of `roleRef`, `role`, or `actions` must be specified", - }, - { - name: "success proto with roleRef", - in: &rbac.AuthorizationPolicy{ - Allow: []*rbac.ServiceRoleBinding{ - { - Subjects: []*rbac.Subject{ - { - Namespaces: []string{"default, istio-system"}, - }, - }, - RoleRef: &rbac.RoleRef{ - Kind: "ServiceRole", - Name: "service-role-1", - }, - }, - }, - }, - }, - { - name: "proto with inline but invalid role definition", - in: &rbac.AuthorizationPolicy{ - Allow: []*rbac.ServiceRoleBinding{ - { - Subjects: []*rbac.Subject{ - { - Namespaces: []string{"default, istio-system"}, - }, - }, - Actions: []*rbac.AccessRule{ - { - Ports: []int32{3000}, - NotPorts: []int32{8080}, - }, - }, - }, - }, - }, - expectErrMsg: "cannot have both regular and *not* attributes for the same kind (i.e. ports and not_ports) for rule 0", - }, - { - name: "success proto with inline role definition", - in: &rbac.AuthorizationPolicy{ - Allow: []*rbac.ServiceRoleBinding{ - { - Subjects: []*rbac.Subject{ - { - Namespaces: []string{"default, istio-system"}, - }, - }, - Actions: []*rbac.AccessRule{ - { - Methods: []string{"GET"}, - }, - }, - }, - }, - }, - }, - } - for _, c := range cases { - err := ValidateAuthorizationPolicy(someName, someNamespace, c.in) - if err == nil { - if len(c.expectErrMsg) != 0 { - t.Errorf("ValidateAuthorizationPolicy(%v): got nil but want %q\n", c.name, c.expectErrMsg) - } - } else if err.Error() != c.expectErrMsg { - t.Errorf("ValidateAuthorizationPolicy(%v): got %q but want %q\n", c.name, err.Error(), c.expectErrMsg) - } - } -} - func TestValidateClusterRbacConfig(t *testing.T) { cases := []struct { caseName string diff --git a/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/input.yaml b/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/input.yaml deleted file mode 100644 index 4a77297794ad..000000000000 --- a/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/input.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-access-b-http-tcp -spec: - workload_selector: - labels: - app: b - allow: - - subjects: - - names: ["allUsers"] - actions: - - methods: ["GET"] - not_paths: ["/secret*"] - - constraints: - - key: "destination.port" - values: ["90"] \ No newline at end of file diff --git a/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/mcp.yaml b/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/mcp.yaml deleted file mode 100644 index 90ff001d47ce..000000000000 --- a/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/mcp.yaml +++ /dev/null @@ -1,50 +0,0 @@ -constraints: - - collection: istio/rbac/v1alpha1/authorizationpolicies - check: - - exactlyOne: - - equals: { - "Body": { - "allow": [ - { - "actions": [ - { - "methods": [ - "GET" - ], - "not_paths": [ - "/secret*" - ] - }, - { - "constraints": [ - { - "key": "destination.port", - "values": [ - "90" - ] - } - ] - } - ], - "subjects": [ - { - "names": [ - "allUsers" - ] - } - ] - } - ], - "workload_selector": { - "labels": { - "app": "b" - } - } - }, - "Metadata": { - "name": "{{.Namespace}}/authz-policy-access-b-http-tcp" - }, - "TypeURL": "type.googleapis.com/istio.rbac.v1alpha1.AuthorizationPolicy" - } - - diff --git a/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/test.yaml b/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/test.yaml deleted file mode 100644 index c60392f3a944..000000000000 --- a/tests/integration/conformance/testdata/rbac/authorizationPolicy/basic/test.yaml +++ /dev/null @@ -1,2 +0,0 @@ -labels: - diff --git a/tests/integration/security/rbac/testdata/v2-policy-basic.yaml.tmpl b/tests/integration/security/rbac/testdata/v2-policy-basic.yaml.tmpl deleted file mode 100644 index 35f426177566..000000000000 --- a/tests/integration/security/rbac/testdata/v2-policy-basic.yaml.tmpl +++ /dev/null @@ -1,133 +0,0 @@ -# istio-rbac-v2-rules.yaml to enforce access control for both http and tcp services using Istio RBAC v2 rules. - -# For service a, allow no one to access it. -# This will also result a default tcp rule for service a that denies all access. -# This actually means nobody could access a. - -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: access-a-http -spec: - rules: - - methods: ["GET"] - constraints: - - key: "destination.labels[app]" - values: ["a"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-access-a-http -spec: - allow: - - subjects: - - not_names: ["allUsers"] - roleRef: - kind: ServiceRole - name: "access-a-http" ---- - -# For service b, only allow authenticated user to access it with GET at any paths except /secret* -# or only access it at tcp port 9090. - -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: access-b-http-tcp -spec: - rules: - - methods: ["GET"] - not_paths: ["/secret*"] - - constraints: - - key: "destination.port" - values: ["9090"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-access-b-http-tcp -spec: - workload_selector: - labels: - app: b - allow: - - subjects: - - names: ["allAuthenticatedUsers"] - roleRef: - kind: ServiceRole - name: "access-b-http-tcp" ---- - -# For service c: -# * Allow GET requests for any path, except paths ending with /admin for service account d. -# * Deny all requests for service account b. -# * Deny anyone else by default. - -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: deny-get-at-admin-prefix-path-rules -spec: - rules: - - methods: ["GET"] - not_paths: ["*/admin"] - paths: ["*"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: deny-all-access-rules -spec: - rules: - - not_methods: ["*"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-c -spec: - workload_selector: - labels: - app: c - allow: - - subjects: - - names: ["cluster.local/ns/{{ .Namespace }}/sa/d"] - roleRef: - kind: ServiceRole - name: "deny-get-at-admin-prefix-path-rules" - - subjects: - - names: ["cluster.local/ns/{{ .Namespace }}/sa/b"] - roleRef: - kind: ServiceRole - name: "deny-all-access-rules" ---- - -# For service d: -# * anyone can access it via HTTP requests -# * no one can access TCP at port 9090. - -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: access-d-http-tcp -spec: - rules: - - methods: ["*"] - - not_ports: [9090] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-access-d-http-tcp -spec: - workload_selector: - labels: - app: d - allow: - - subjects: - - names: ["allUsers"] - roleRef: - kind: ServiceRole - name: "access-d-http-tcp" ---- diff --git a/tests/integration/security/rbac/testdata/v2-policy-extended.yaml.tmpl b/tests/integration/security/rbac/testdata/v2-policy-extended.yaml.tmpl deleted file mode 100644 index e54e772c1651..000000000000 --- a/tests/integration/security/rbac/testdata/v2-policy-extended.yaml.tmpl +++ /dev/null @@ -1,73 +0,0 @@ -# istio-extended-rbac-v2-rules.yaml to enforce access control for both http and tcp services using Istio RBAC v2 rules -# such as root namespace, inline role ref, using role instead of roleRef. - -# For service a, authenticated service account b is allowed have both HTTP (except path with prefix "bad-path") and TCP access. -# For service a, authenticated service account c is allowed to have HTTP access at paths with prefix "good" only. -# Two ServiceRole with the same name will be created in the root namespace and local namespace, -# then one AuthorizationPolicy will use role with / to indicate the root namespace, and without / -# to indicate the local namespace. - -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: access-a - namespace: {{ .RootNamespace }} -spec: - rules: - - methods: ["GET"] - not_paths: ["/bad-path*"] - - constraints: - - key: "destination.port" - values: ["9090"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: access-a - namespace: {{ .Namespace }} -spec: - rules: - - methods: ["GET"] - paths: ["/good*"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-access-a - namespace: {{ .Namespace }} -spec: - workload_selector: - labels: - app: a - allow: - - subjects: - - names: ["cluster.local/ns/{{ .Namespace }}/sa/b"] - role: "/access-a" - - subjects: - - names: ["cluster.local/ns/{{ .Namespace }}/sa/c"] - role: "access-a" ---- - -# For service b, allow any user to access it with GET at any paths except /secret* -# or only access it at tcp port 9090. -# Instead of creating a separate ServiceRole policy, we create an inline role definition inside AuthorizationPolicy. - -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-access-b-http-tcp - namespace: {{ .Namespace }} -spec: - workload_selector: - labels: - app: b - allow: - - subjects: - - names: ["allUsers"] - actions: - - methods: ["GET"] - not_paths: ["/secret*"] - - constraints: - - key: "destination.port" - values: ["9090"] ---- diff --git a/tests/integration/security/rbac/testdata/v2-policy-group.yaml.tmpl b/tests/integration/security/rbac/testdata/v2-policy-group.yaml.tmpl deleted file mode 100644 index 2f8b261bca76..000000000000 --- a/tests/integration/security/rbac/testdata/v2-policy-group.yaml.tmpl +++ /dev/null @@ -1,81 +0,0 @@ -# istio-group-list-rbac-v2-rules.yaml to enforce access control based on -# groups and list claims for http services using Istio RBAC V2 policy. - -apiVersion: "authentication.istio.io/v1alpha1" -kind: "Policy" -metadata: - name: "require-jwt-for-b" -spec: - targets: - - name: b - origins: - - jwt: - issuer: "test-issuer-1@istio.io" - jwksUri: "https://raw.githubusercontent.com/istio/istio/master/tests/common/jwt/jwks.json" - - jwt: - issuer: "test-issuer-2@istio.io" - jwksUri: "https://raw.githubusercontent.com/istio/istio/master/tests/common/jwt/jwks.json" - principalBinding: USE_ORIGIN ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: b-viewer -spec: - rules: - - services: ["b.{{ .Namespace }}.svc.cluster.local"] - methods: ["GET"] ---- -# Require a JWT with valid group claim to access service b -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: bind-b-viewer -spec: - allow: - - subjects: - - groups: ["group-1"] - roleRef: - kind: ServiceRole - name: "b-viewer" ---- -apiVersion: "authentication.istio.io/v1alpha1" -kind: "Policy" -metadata: - name: "require-jwt-for-c" -spec: - targets: - - name: c - origins: - - jwt: - issuer: "test-issuer-1@istio.io" - jwksUri: "https://raw.githubusercontent.com/istio/istio/master/tests/common/jwt/jwks.json" - - jwt: - issuer: "test-issuer-2@istio.io" - jwksUri: "https://raw.githubusercontent.com/istio/istio/master/tests/common/jwt/jwks.json" - principalBinding: USE_ORIGIN ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: c-viewer -spec: - rules: - - services: ["c.{{ .Namespace }}.svc.cluster.local"] - methods: ["GET"] ---- -# Require a JWT with valid list-typed scope claim to access service c -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: bind-c-viewer -spec: - allow: - - subjects: - - properties: - request.auth.claims[sub]: "sub-1" - roleRef: - kind: ServiceRole - name: "c-viewer" ---- - diff --git a/tests/integration/security/rbac/testdata/v2-policy-grpc.yaml.tmpl b/tests/integration/security/rbac/testdata/v2-policy-grpc.yaml.tmpl deleted file mode 100644 index 24021a24290c..000000000000 --- a/tests/integration/security/rbac/testdata/v2-policy-grpc.yaml.tmpl +++ /dev/null @@ -1,59 +0,0 @@ -# istio-rbac-grpc-rules.yaml to enforce access control for gRPC services using Istio RBAC v2 rules. - -# For service a: -# * Allow b to call a's Echo method. -# * Service c cannot talk to a since GET, DELETE, and PUT are not supported in gRPC. -# * Allow d to call any methods of a. - -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: access-grpc-echo - namespace: {{ .Namespace }} -spec: - rules: - - paths: ["/proto.EchoTestService/Echo"] - # This is optional, since gRPC can only allow POST. - # If methods are not specified, it will allow all methods, which include POST. - methods: ["POST"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: not-access-grpc-not-post - namespace: {{ .Namespace }} -spec: - rules: - - paths: ["/proto.EchoTestService/Echo"] - # Since gRPC only allows POST, this will be denied (even though paths should be allowed). - # In practice, users should not define methods when writing rules for gRPC services. - methods: ["GET", "DELETE", "PUT"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: ServiceRole -metadata: - name: access-grpc-any - namespace: {{ .Namespace }} -spec: - rules: - - paths: ["*"] ---- -apiVersion: "rbac.istio.io/v1alpha1" -kind: AuthorizationPolicy -metadata: - name: authz-policy-a-grpc - namespace: {{ .Namespace }} -spec: - workload_selector: - labels: - app: a - allow: - - subjects: - - names: ["cluster.local/ns/{{ .Namespace }}/sa/b"] - role: access-grpc-echo - - subjects: - - names: ["cluster.local/ns/{{ .Namespace }}/sa/c"] - role: not-access-grpc-not-post - - subjects: - - names: ["cluster.local/ns/{{ .Namespace }}/sa/d"] - role: access-grpc-any diff --git a/tests/integration/security/rbac/v2_test.go b/tests/integration/security/rbac/v2_test.go deleted file mode 100644 index e510dcecf9ba..000000000000 --- a/tests/integration/security/rbac/v2_test.go +++ /dev/null @@ -1,705 +0,0 @@ -// Copyright 2019 Istio Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package rbac - -import ( - "testing" - - "istio.io/istio/pkg/config/mesh" - "istio.io/istio/pkg/test/echo/common/scheme" - "istio.io/istio/pkg/test/framework" - "istio.io/istio/pkg/test/framework/components/echo" - "istio.io/istio/pkg/test/framework/components/echo/echoboot" - "istio.io/istio/pkg/test/framework/components/environment" - "istio.io/istio/pkg/test/framework/components/namespace" - "istio.io/istio/pkg/test/util/file" - "istio.io/istio/pkg/test/util/tmpl" - "istio.io/istio/tests/common/jwt" - "istio.io/istio/tests/integration/security/util" - "istio.io/istio/tests/integration/security/util/connection" -) - -// TestV2_Basic tests basic features of RBAC V2 such as AuthorizationPolicy policy and exclusion. -func TestV2_Basic(t *testing.T) { - framework.NewTest(t). - RequiresEnvironment(environment.Kube). - Run(func(ctx framework.TestContext) { - ns := namespace.NewOrFail(t, ctx, "v2-basic", true) - - var a, b, c, d echo.Instance - echoboot.NewBuilderOrFail(t, ctx). - With(&a, util.EchoConfig("a", ns, false, nil, g, p)). - With(&b, util.EchoConfig("b", ns, false, nil, g, p)). - With(&c, util.EchoConfig("c", ns, false, nil, g, p)). - With(&d, util.EchoConfig("d", ns, false, nil, g, p)). - BuildOrFail(t) - - cases := []TestCase{ - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: a, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: a, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: a, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: a, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: a, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: a, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/secret", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: b, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: b, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/secrets/admin", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: c, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/credentials/admin", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: c, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/any_path/admin", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: c, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: d, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - ExpectAllowed: true, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: d, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: d, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: true, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: d, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: d, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/any_path", - }, - }, - ExpectAllowed: true, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: d, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - } - - namespaceTmpl := map[string]string{ - "Namespace": ns.Name(), - } - policies := tmpl.EvaluateAllOrFail(t, namespaceTmpl, - file.AsStringOrFail(t, rbacClusterConfigTmpl), - file.AsStringOrFail(t, "testdata/v2-policy-basic.yaml.tmpl")) - - g.ApplyConfigOrFail(t, ns, policies...) - defer g.DeleteConfigOrFail(t, ns, policies...) - - RunRBACTest(t, cases) - }) -} - -// TestV2_Extended tests extended features of RBAC v2 such as global namespace and inline role def. -func TestV2_Extended(t *testing.T) { - framework.NewTest(t). - RequiresEnvironment(environment.Kube). - Run(func(ctx framework.TestContext) { - ns := namespace.NewOrFail(t, ctx, "v2-extended", true) - - var a, b, c echo.Instance - echoboot.NewBuilderOrFail(t, ctx). - With(&a, util.EchoConfig("a", ns, false, nil, g, p)). - With(&b, util.EchoConfig("b", ns, false, nil, g, p)). - With(&c, util.EchoConfig("c", ns, false, nil, g, p)). - BuildOrFail(t) - - cases := []TestCase{ - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: a, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/some-path", - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: a, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/bad-path/black-hole", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: a, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: a, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: a, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/good-path", - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: a, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: false, - }, - - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - ExpectAllowed: true, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/secret", - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: true, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/", - }, - }, - ExpectAllowed: true, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: b, - PortName: "tcp", - Scheme: scheme.HTTP, - }, - }, - ExpectAllowed: true, - }, - } - - rootNamespace := mesh.DefaultMeshConfig().RootNamespace - namespaceTmpl := map[string]string{ - "Namespace": ns.Name(), - "RootNamespace": rootNamespace, - } - policies := tmpl.EvaluateAllOrFail(t, namespaceTmpl, - file.AsStringOrFail(t, rbacClusterConfigTmpl), - file.AsStringOrFail(t, "testdata/v2-policy-extended.yaml.tmpl")) - - // Pass in nil for namespace to apply the policies for all namespaces. - g.ApplyConfigOrFail(t, nil, policies...) - rootNs := namespace.ClaimOrFail(t, ctx, rootNamespace) - defer func() { _ = g.DeleteConfig(ns, policies...) }() - defer func() { _ = g.DeleteConfig(rootNs, policies...) }() - - RunRBACTest(t, cases) - }) -} - -func TestV2_GRPC(t *testing.T) { - framework.NewTest(t). - RequiresEnvironment(environment.Kube). - Run(func(ctx framework.TestContext) { - ns := namespace.NewOrFail(t, ctx, "v2-grpc", true) - var a, b, c, d echo.Instance - echoboot.NewBuilderOrFail(t, ctx). - With(&a, util.EchoConfig("a", ns, false, nil, g, p)). - With(&b, util.EchoConfig("b", ns, false, nil, g, p)). - With(&c, util.EchoConfig("c", ns, false, nil, g, p)). - With(&d, util.EchoConfig("d", ns, false, nil, g, p)). - BuildOrFail(t) - - cases := []TestCase{ - { - Request: connection.Checker{ - From: b, - Options: echo.CallOptions{ - Target: a, - PortName: "grpc", - Scheme: scheme.GRPC, - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - { - Request: connection.Checker{ - From: c, - Options: echo.CallOptions{ - Target: a, - PortName: "grpc", - Scheme: scheme.GRPC, - }, - }, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: d, - Options: echo.CallOptions{ - Target: a, - PortName: "grpc", - Scheme: scheme.GRPC, - }, - }, - ExpectAllowed: isMtlsEnabled, - }, - } - - namespaceTmpl := map[string]string{ - "Namespace": ns.Name(), - } - - policies := tmpl.EvaluateAllOrFail(t, namespaceTmpl, - file.AsStringOrFail(t, rbacClusterConfigTmpl), - file.AsStringOrFail(t, "testdata/v2-policy-grpc.yaml.tmpl")) - g.ApplyConfigOrFail(t, ns, policies...) - defer g.DeleteConfigOrFail(t, ns, policies...) - - RunRBACTest(t, cases) - }) -} - -func TestV2_Group(t *testing.T) { - JwtWithClaim1 := jwt.TokenIssuer1 - JwtWithClaim2 := jwt.TokenIssuer2 - - framework.NewTest(t). - // TODO(lei-tang): add the test to the native environment - RequiresEnvironment(environment.Kube). - Run(func(ctx framework.TestContext) { - - ns := namespace.NewOrFail(t, ctx, "v2-group", true) - - var a, b, c echo.Instance - echoboot.NewBuilderOrFail(t, ctx). - With(&a, util.EchoConfig("a", ns, false, nil, g, p)). - With(&b, util.EchoConfig("b", ns, false, nil, g, p)). - With(&c, util.EchoConfig("c", ns, false, nil, g, p)). - BuildOrFail(t) - - cases := []TestCase{ - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - Jwt: JwtWithClaim2, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: b, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - Jwt: JwtWithClaim1, - ExpectAllowed: true, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - Jwt: JwtWithClaim2, - ExpectAllowed: false, - }, - { - Request: connection.Checker{ - From: a, - Options: echo.CallOptions{ - Target: c, - PortName: "http", - Scheme: scheme.HTTP, - Path: "/xyz", - }, - }, - Jwt: JwtWithClaim1, - ExpectAllowed: true, - }, - } - - args := map[string]string{ - "Namespace": ns.Name(), - } - policies := tmpl.EvaluateAllOrFail(t, args, - file.AsStringOrFail(t, rbacClusterConfigTmpl), - file.AsStringOrFail(t, "testdata/v2-policy-group.yaml.tmpl")) - - g.ApplyConfigOrFail(t, ns, policies...) - defer g.DeleteConfigOrFail(t, ns, policies...) - - RunRBACTest(t, cases) - }) -}