@@ -778,6 +778,244 @@ describe('#compileIamRole', () => {
778
778
expect ( policy . PolicyDocument . Statement [ 0 ] . Resource ) . to . equal ( '*' ) ;
779
779
} ) ;
780
780
781
+ it ( 'should give Redshift Data permissions to * for safe actions' , ( ) => {
782
+ serverless . service . stepFunctions = {
783
+ stateMachines : {
784
+ myStateMachine : {
785
+ id : 'StateMachine1' ,
786
+ definition : {
787
+ StartAt : 'A' ,
788
+ States : {
789
+ A : {
790
+ Type : 'Task' ,
791
+ Next : 'B' ,
792
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:listStatements' ,
793
+ } ,
794
+ B : {
795
+ Type : 'Task' ,
796
+ Next : 'C' ,
797
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:describeStatement' ,
798
+ } ,
799
+ C : {
800
+ Type : 'Task' ,
801
+ Next : 'D' ,
802
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:getStatementResult' ,
803
+ } ,
804
+ D : {
805
+ Type : 'Task' ,
806
+ End : true ,
807
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:cancelStatement' ,
808
+ } ,
809
+ } ,
810
+ } ,
811
+ } ,
812
+ } ,
813
+ } ;
814
+ serverlessStepFunctions . compileIamRole ( ) ;
815
+ const statement = serverlessStepFunctions . serverless . service . provider
816
+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
817
+ . PolicyDocument . Statement [ 0 ] ;
818
+ expect ( statement . Action ) . to . include ( 'redshift-data:ListStatements' ) ;
819
+ expect ( statement . Action ) . to . include ( 'redshift-data:DescribeStatement' ) ;
820
+ expect ( statement . Action ) . to . include ( 'redshift-data:GetStatementResult' ) ;
821
+ expect ( statement . Action ) . to . include ( 'redshift-data:CancelStatement' ) ;
822
+ expect ( statement . Resource ) . to . equal ( '*' ) ;
823
+ } ) ;
824
+
825
+ it ( 'should give Redshift Data permissions to clusters for unsafe actions' , ( ) => {
826
+ serverless . service . stepFunctions = {
827
+ stateMachines : {
828
+ myStateMachine : {
829
+ id : 'StateMachine1' ,
830
+ definition : {
831
+ StartAt : 'A' ,
832
+ States : {
833
+ A : {
834
+ Type : 'Task' ,
835
+ Next : 'B' ,
836
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
837
+ } ,
838
+ B : {
839
+ Type : 'Task' ,
840
+ End : true ,
841
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
842
+ } ,
843
+ } ,
844
+ } ,
845
+ } ,
846
+ } ,
847
+ } ;
848
+ serverlessStepFunctions . compileIamRole ( ) ;
849
+ const statement = serverlessStepFunctions . serverless . service . provider
850
+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
851
+ . PolicyDocument . Statement [ 0 ] ;
852
+ expect ( statement . Action ) . to . include ( 'redshift-data:ExecuteStatement' ) ;
853
+ expect ( statement . Action ) . to . include ( 'redshift-data:BatchExecuteStatement' ) ;
854
+ expect ( statement . Resource ) . to . have . deep . members ( [ {
855
+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:cluster:*' ,
856
+ } ] ) ;
857
+ } ) ;
858
+
859
+ it ( 'should give Redshift Data permissions to a specified cluster for unsafe actions' , ( ) => {
860
+ const clusterName = 'myCluster' ;
861
+ serverless . service . stepFunctions = {
862
+ stateMachines : {
863
+ myStateMachine : {
864
+ id : 'StateMachine1' ,
865
+ definition : {
866
+ StartAt : 'A' ,
867
+ States : {
868
+ A : {
869
+ Type : 'Task' ,
870
+ Next : 'B' ,
871
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
872
+ Parameters : {
873
+ ClusterIdentifier : clusterName ,
874
+ } ,
875
+ } ,
876
+ B : {
877
+ Type : 'Task' ,
878
+ End : true ,
879
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
880
+ Parameters : {
881
+ ClusterIdentifier : clusterName ,
882
+ } ,
883
+ } ,
884
+ } ,
885
+ } ,
886
+ } ,
887
+ } ,
888
+ } ;
889
+ serverlessStepFunctions . compileIamRole ( ) ;
890
+ const statement = serverlessStepFunctions . serverless . service . provider
891
+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
892
+ . PolicyDocument . Statement [ 0 ] ;
893
+ expect ( statement . Action ) . to . include ( 'redshift-data:ExecuteStatement' ) ;
894
+ expect ( statement . Action ) . to . include ( 'redshift-data:BatchExecuteStatement' ) ;
895
+ expect ( statement . Resource ) . to . have . deep . members ( [ {
896
+ 'Fn::Sub' : `arn:\${AWS::Partition}:redshift:\${AWS::Region}:\${AWS::AccountId}:cluster:${ clusterName } ` ,
897
+ } ] ) ;
898
+ } ) ;
899
+
900
+ it ( 'should give redshift:GetClusterCredentials permission to databases and database users for unsafe actions' , ( ) => {
901
+ serverless . service . stepFunctions = {
902
+ stateMachines : {
903
+ myStateMachine : {
904
+ id : 'StateMachine1' ,
905
+ definition : {
906
+ StartAt : 'A' ,
907
+ States : {
908
+ A : {
909
+ Type : 'Task' ,
910
+ Next : 'B' ,
911
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
912
+ } ,
913
+ B : {
914
+ Type : 'Task' ,
915
+ End : true ,
916
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
917
+ } ,
918
+ } ,
919
+ } ,
920
+ } ,
921
+ } ,
922
+ } ;
923
+ serverlessStepFunctions . compileIamRole ( ) ;
924
+ const statement = serverlessStepFunctions . serverless . service . provider
925
+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
926
+ . PolicyDocument . Statement [ 1 ] ;
927
+ expect ( statement . Action ) . to . include ( 'redshift:GetClusterCredentials' ) ;
928
+ expect ( statement . Resource ) . to . have . deep . members ( [ {
929
+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbname:*/*' ,
930
+ } , {
931
+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbuser:*/*' ,
932
+ } ] ) ;
933
+ } ) ;
934
+
935
+ it ( 'should give redshift:GetClusterCredentials permission to specified databases for unsafe actions' , ( ) => {
936
+ const dbName = 'myDatabase' ;
937
+ serverless . service . stepFunctions = {
938
+ stateMachines : {
939
+ myStateMachine : {
940
+ id : 'StateMachine1' ,
941
+ definition : {
942
+ StartAt : 'A' ,
943
+ States : {
944
+ A : {
945
+ Type : 'Task' ,
946
+ Next : 'B' ,
947
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
948
+ Parameters : {
949
+ Database : dbName ,
950
+ } ,
951
+ } ,
952
+ B : {
953
+ Type : 'Task' ,
954
+ End : true ,
955
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
956
+ Parameters : {
957
+ Database : dbName ,
958
+ } ,
959
+ } ,
960
+ } ,
961
+ } ,
962
+ } ,
963
+ } ,
964
+ } ;
965
+ serverlessStepFunctions . compileIamRole ( ) ;
966
+ const statement = serverlessStepFunctions . serverless . service . provider
967
+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
968
+ . PolicyDocument . Statement [ 1 ] ;
969
+ expect ( statement . Action ) . to . include ( 'redshift:GetClusterCredentials' ) ;
970
+ expect ( statement . Resource ) . to . have . deep . members ( [ {
971
+ 'Fn::Sub' : `arn:\${AWS::Partition}:redshift:\${AWS::Region}:\${AWS::AccountId}:dbname:*/${ dbName } ` ,
972
+ } , {
973
+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbuser:*/*' ,
974
+ } ] ) ;
975
+ } ) ;
976
+
977
+ it ( 'should give redshift:GetClusterCredentials permission to specified database users for unsafe actions' , ( ) => {
978
+ const dbUser = 'myDatabaseUser' ;
979
+ serverless . service . stepFunctions = {
980
+ stateMachines : {
981
+ myStateMachine : {
982
+ id : 'StateMachine1' ,
983
+ definition : {
984
+ StartAt : 'A' ,
985
+ States : {
986
+ A : {
987
+ Type : 'Task' ,
988
+ Next : 'B' ,
989
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
990
+ Parameters : {
991
+ DbUser : dbUser ,
992
+ } ,
993
+ } ,
994
+ B : {
995
+ Type : 'Task' ,
996
+ End : true ,
997
+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
998
+ Parameters : {
999
+ DbUser : dbUser ,
1000
+ } ,
1001
+ } ,
1002
+ } ,
1003
+ } ,
1004
+ } ,
1005
+ } ,
1006
+ } ;
1007
+ serverlessStepFunctions . compileIamRole ( ) ;
1008
+ const statement = serverlessStepFunctions . serverless . service . provider
1009
+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
1010
+ . PolicyDocument . Statement [ 1 ] ;
1011
+ expect ( statement . Action ) . to . include ( 'redshift:GetClusterCredentials' ) ;
1012
+ expect ( statement . Resource ) . to . have . deep . members ( [ {
1013
+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbname:*/*' ,
1014
+ } , {
1015
+ 'Fn::Sub' : `arn:\${AWS::Partition}:redshift:\${AWS::Region}:\${AWS::AccountId}:dbuser:*/${ dbUser } ` ,
1016
+ } ] ) ;
1017
+ } ) ;
1018
+
781
1019
it ( 'should give batch permissions (too permissive, but mirrors console behaviour)' , ( ) => {
782
1020
const genStateMachine = id => ( {
783
1021
id,
0 commit comments