@@ -40,28 +40,29 @@ func newSparkVal(flagName, propName, desc string) *sparkVal {
40
40
}
41
41
42
42
type sparkArgs struct {
43
- mainClass string
44
- kerberosPrincipal string
45
- keytabSecretPath string
46
- tgtSecretPath string
47
- tgtSecretValue string
48
- keystoreSecretPath string
49
- keystorePassword string
50
- privateKeyPassword string
51
- truststoreSecretPath string
52
- truststorePassword string
53
- propertiesFile string
54
- properties map [string ]string
55
-
56
- boolVals []* sparkVal
57
- stringVals []* sparkVal
58
-
59
- app * url.URL
60
- appArgs []string
61
-
62
- isScala bool
63
- isPython bool
64
- isR bool
43
+ mainClass string
44
+ kerberosPrincipal string
45
+ keytabSecretPath string
46
+ tgtSecretPath string
47
+ tgtSecretValue string
48
+ keystoreSecretPath string
49
+ keystorePassword string
50
+ privateKeyPassword string
51
+ truststoreSecretPath string
52
+ truststorePassword string
53
+ saslSecret string
54
+ propertiesFile string
55
+ properties map [string ]string
56
+
57
+ boolVals []* sparkVal
58
+ stringVals []* sparkVal
59
+
60
+ app * url.URL
61
+ appArgs []string
62
+
63
+ isScala bool
64
+ isPython bool
65
+ isR bool
65
66
}
66
67
67
68
func NewSparkArgs () * sparkArgs {
@@ -77,6 +78,7 @@ func NewSparkArgs() *sparkArgs {
77
78
"" ,
78
79
"" ,
79
80
"" ,
81
+ "" ,
80
82
make (map [string ]string ),
81
83
make ([]* sparkVal , 0 ),
82
84
make ([]* sparkVal , 0 ),
@@ -154,23 +156,24 @@ Args:
154
156
PlaceHolder ("user@REALM" ).Default ("" ).StringVar (& args .kerberosPrincipal )
155
157
submit .Flag ("keytab-secret-path" , "Path to Keytab in secret store to be used in the Spark drivers" ).
156
158
PlaceHolder ("/mykeytab" ).Default ("" ).StringVar (& args .keytabSecretPath )
157
- submit .Flag ("tgt-secret-path" , "Path to ticket granting ticket (TGT) in secret store to be used " +
159
+ submit .Flag ("tgt-secret-path" , "Path to ticket granting ticket (TGT) in secret store to be used " +
158
160
"in the Spark drivers" ).PlaceHolder ("/mytgt" ).Default ("" ).StringVar (& args .tgtSecretPath )
159
161
submit .Flag ("tgt-secret-value" , "Value of TGT to be used in the drivers, must be base64 encoded" ).
160
162
Default ("" ).StringVar (& args .tgtSecretValue )
161
- submit .Flag ("keystore-secret-path" , "Path to keystore in secret store for TLS/SSL. " +
162
- "Make sure to set --keystore-password and --private-key-password as well." ).
163
+ submit .Flag ("keystore-secret-path" , "Path to keystore in secret store for TLS/SSL. " +
164
+ "Make sure to set --keystore-password and --private-key-password as well." ).
163
165
PlaceHolder ("__dcos_base64__keystore" ).Default ("" ).StringVar (& args .keystoreSecretPath )
164
166
submit .Flag ("keystore-password" , "A password to the keystore." ).
165
167
Default ("" ).StringVar (& args .keystorePassword )
166
168
submit .Flag ("private-key-password" , "A password to the private key in the keystore." ).
167
169
Default ("" ).StringVar (& args .privateKeyPassword )
168
- submit .Flag ("truststore-secret-path" , "Path to truststore in secret store for TLS/SSL. " +
169
- "Make sure to set --truststore-password as well." ).
170
+ submit .Flag ("truststore-secret-path" , "Path to truststore in secret store for TLS/SSL. " +
171
+ "Make sure to set --truststore-password as well." ).
170
172
PlaceHolder ("__dcos_base64__truststore" ).Default ("" ).StringVar (& args .truststoreSecretPath )
171
173
submit .Flag ("truststore-password" , "A password to the truststore." ).
172
174
Default ("" ).StringVar (& args .truststorePassword )
173
-
175
+ submit .Flag ("executor-auth-secret" , "Path to secret 'cookie' to use for Executor authentication " +
176
+ "block transfer encryption. Make one with dcos spark secret" ).Default ("" ).StringVar (& args .saslSecret )
174
177
submit .Flag ("isR" , "Force using SparkR" ).Default ("false" ).BoolVar (& args .isR )
175
178
submit .Flag ("isPython" , "Force using Python" ).Default ("false" ).BoolVar (& args .isPython )
176
179
@@ -218,8 +221,8 @@ Args:
218
221
val .flag (submit ).StringVar (& val .s )
219
222
args .stringVals = append (args .stringVals , val )
220
223
221
- val = newSparkVal ("py-files" , "spark.submit.pyFiles" , "Add .py, .zip or .egg files to " +
222
- "be distributed with your application. If you depend on multiple Python files we recommend packaging them " +
224
+ val = newSparkVal ("py-files" , "spark.submit.pyFiles" , "Add .py, .zip or .egg files to " +
225
+ "be distributed with your application. If you depend on multiple Python files we recommend packaging them " +
223
226
"into a .zip or .egg." )
224
227
val .flag (submit ).StringVar (& val .s )
225
228
args .stringVals = append (args .stringVals , val )
@@ -252,24 +255,27 @@ func prepareBase64Secret(secretPath string) string {
252
255
}
253
256
254
257
func addArgsForFileBasedSecret (args * sparkArgs , secretPath , property string ) {
255
- secretRefProp := fmt .Sprintf (SECRET_REFERENCE_TEMPLATE , "driver" )
256
- secretFileProp := fmt .Sprintf (SECRET_FILENAME_TEMPLATE , "driver" )
257
- appendToProperty (secretRefProp , secretPath , args )
258
- appendToProperty (secretFileProp , prepareBase64Secret (secretPath ), args )
258
+ taskTypes := []string {"driver" , "executor" }
259
+ for _ , taskType := range taskTypes {
260
+ secretRefProp := fmt .Sprintf (SECRET_REFERENCE_TEMPLATE , taskType )
261
+ secretFileProp := fmt .Sprintf (SECRET_FILENAME_TEMPLATE , taskType )
262
+ appendToProperty (secretRefProp , secretPath , args )
263
+ appendToProperty (secretFileProp , prepareBase64Secret (secretPath ), args )
264
+ }
259
265
args .properties [property ] = prepareBase64Secret (secretPath )
260
266
}
261
267
262
268
func setupKerberosAuthArgs (args * sparkArgs ) error {
263
269
args .properties ["spark.mesos.containerizer" ] = "mesos"
264
- if args .keytabSecretPath != "" { // using keytab secret
270
+ if args .keytabSecretPath != "" { // using keytab secret
265
271
addArgsForFileBasedSecret (args , args .keytabSecretPath , "spark.yarn.keytab" )
266
272
return nil
267
273
}
268
- if args .tgtSecretPath != "" { // using tgt secret
274
+ if args .tgtSecretPath != "" { // using tgt secret
269
275
addArgsForFileBasedSecret (args , args .tgtSecretPath , "spark.mesos.driverEnv.KRB5CCNAME" )
270
276
return nil
271
277
}
272
- if args .tgtSecretValue != "" { // using secret by value
278
+ if args .tgtSecretValue != "" { // using secret by value
273
279
appendToProperty ("spark.mesos.driver.secret.values" , args .tgtSecretValue , args )
274
280
args .properties ["spark.mesos.driverEnv.KRB5CCNAME" ] = "tgt"
275
281
appendToProperty (fmt .Sprintf (SECRET_FILENAME_TEMPLATE , "driver" ), "tgt.base64" , args )
@@ -283,8 +289,8 @@ func setupTLSArgs(args *sparkArgs) {
283
289
args .properties ["spark.ssl.enabled" ] = "true"
284
290
285
291
// Keystore and truststore
286
- const keyStoreFileName = "server.jks"
287
- const trustStoreFileName = "trust.jks"
292
+ const keyStoreFileName = "server.jks"
293
+ const trustStoreFileName = "trust.jks"
288
294
args .properties ["spark.ssl.keyStore" ] = keyStoreFileName
289
295
if args .truststoreSecretPath != "" {
290
296
args .properties ["spark.ssl.trustStore" ] = trustStoreFileName
@@ -303,7 +309,7 @@ func setupTLSArgs(args *sparkArgs) {
303
309
joinedFilenames := strings .Join (filenames , "," )
304
310
joinedEnvkeys := strings .Join (envkeys , "," )
305
311
306
- taskTypes := []string {"driver" , "executor" }
312
+ taskTypes := []string {"driver" , "executor" }
307
313
for _ , taskType := range taskTypes {
308
314
appendToProperty (fmt .Sprintf (SECRET_REFERENCE_TEMPLATE , taskType ), joinedPaths , args )
309
315
appendToProperty (fmt .Sprintf (SECRET_FILENAME_TEMPLATE , taskType ), joinedFilenames , args )
@@ -324,6 +330,21 @@ func setupTLSArgs(args *sparkArgs) {
324
330
}
325
331
}
326
332
333
+ func setupSaslProperties (secretPath string , args * sparkArgs ) {
334
+ args .properties ["spark.mesos.containerizer" ] = "mesos"
335
+ args .properties ["spark.authenticate" ] = "true"
336
+ args .properties ["spark.authenticate.enableSaslEncryption" ] = "true"
337
+ args .properties ["spark.authenticate.secret" ] = "spark_shared_secret"
338
+ args .properties ["spark.executorEnv._SPARK_AUTH_SECRET" ] = "spark_shared_secret"
339
+ taskTypes := []string {"driver" , "executor" }
340
+ for _ , taskType := range taskTypes {
341
+ secretRefProp := fmt .Sprintf (SECRET_REFERENCE_TEMPLATE , taskType )
342
+ secretFileProp := fmt .Sprintf (SECRET_FILENAME_TEMPLATE , taskType )
343
+ appendToProperty (secretRefProp , secretPath , args )
344
+ appendToProperty (secretFileProp , prepareBase64Secret (secretPath ), args )
345
+ }
346
+ }
347
+
327
348
func parseApplicationFile (args * sparkArgs ) error {
328
349
appString := args .app .String ()
329
350
fs := strings .Split (appString , "/" )
@@ -367,7 +388,7 @@ func parseApplicationFile(args *sparkArgs) error {
367
388
368
389
func cleanUpSubmitArgs (argsStr string , boolVals []* sparkVal ) ([]string , []string ) {
369
390
370
- // collapse two or more spaces to one.
391
+ // collapse two or more spaces to one.
371
392
argsCompacted := collapseSpacesPattern .ReplaceAllString (argsStr , " " )
372
393
// clean up any instances of shell-style escaped newlines: "arg1\\narg2" => "arg1 arg2"
373
394
argsCleaned := strings .TrimSpace (backslashNewlinePattern .ReplaceAllLiteralString (argsCompacted , " " ))
@@ -390,12 +411,12 @@ ARGLOOP:
390
411
// if it's not of the format --flag=val which scopt allows
391
412
if strings .HasPrefix (arg , "-" ) {
392
413
appFlags = append (appFlags , arg )
393
- if strings .Contains (arg , "=" ) || (i + 1 ) >= len (args ) {
414
+ if strings .Contains (arg , "=" ) || (i + 1 ) >= len (args ) {
394
415
i += 1
395
416
} else {
396
417
// if there's a value with this flag, add it
397
- if ! strings .HasPrefix (args [i + 1 ], "-" ) {
398
- appFlags = append (appFlags , args [i + 1 ])
418
+ if ! strings .HasPrefix (args [i + 1 ], "-" ) {
419
+ appFlags = append (appFlags , args [i + 1 ])
399
420
i += 1
400
421
}
401
422
i += 1
@@ -514,7 +535,7 @@ func buildSubmitJson(cmd *SparkCommand) (string, error) {
514
535
// then map applicable envvars
515
536
// then parse all -Dprop.key=propVal, and all --conf prop.key=propVal
516
537
// then map flags
517
- submit , args := sparkSubmitArgSetup () // setup
538
+ submit , args := sparkSubmitArgSetup () // setup
518
539
// convert and get application flags, add them to the args passed to the spark app
519
540
submitArgs , appFlags := cleanUpSubmitArgs (cmd .submitArgs , args .boolVals )
520
541
args .appArgs = append (args .appArgs , appFlags ... )
@@ -623,7 +644,7 @@ func buildSubmitJson(cmd *SparkCommand) (string, error) {
623
644
624
645
_ , contains = args .properties ["spark.mesos.executor.docker.forcePullImage" ]
625
646
if ! contains {
626
- log .Printf ("Pulling image %s for executors, by default. To bypass set " +
647
+ log .Printf ("Pulling image %s for executors, by default. To bypass set " +
627
648
"spark.mesos.executor.docker.forcePullImage=false" , args .properties ["spark.mesos.executor.docker.image" ])
628
649
args .properties ["spark.mesos.executor.docker.forcePullImage" ] = "true"
629
650
}
@@ -677,6 +698,7 @@ func buildSubmitJson(cmd *SparkCommand) (string, error) {
677
698
_ , contains := args .properties ["spark.mesos.driverEnv.KRB5_CONFIG_BASE64" ]
678
699
if ! contains {
679
700
args .properties ["spark.mesos.driverEnv.KRB5_CONFIG_BASE64" ] = krb5conf
701
+ args .properties ["spark.executorEnv.KRB5_CONFIG_BASE64" ] = krb5conf
680
702
} else {
681
703
log .Printf ("Using user-specified krb5 config" )
682
704
}
@@ -704,6 +726,11 @@ func buildSubmitJson(cmd *SparkCommand) (string, error) {
704
726
setupTLSArgs (args )
705
727
}
706
728
729
+ // RPC and SASL
730
+ if args .saslSecret != "" {
731
+ setupSaslProperties (args .saslSecret , args )
732
+ }
733
+
707
734
jsonMap := map [string ]interface {}{
708
735
"action" : "CreateSubmissionRequest" ,
709
736
"appArgs" : args .appArgs ,
0 commit comments