Repository: ambari Updated Branches: refs/heads/trunk 1f8e6d83f -> 60c9f8c82
AMBARI-8801. Kerberos Wizard: Component identity principal having value should not be made observable on parent stack identity principal value. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/60c9f8c8 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/60c9f8c8 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/60c9f8c8 Branch: refs/heads/trunk Commit: 60c9f8c82c1715ada544d8ccbbba69db478e1a87 Parents: 1f8e6d8 Author: Jaimin Jetly <[email protected]> Authored: Thu Dec 18 14:48:32 2014 -0800 Committer: Jaimin Jetly <[email protected]> Committed: Thu Dec 18 14:49:04 2014 -0800 ---------------------------------------------------------------------- .../data/wizard/kerberos/stack_descriptors.json | 149 ++++++++++++++++-- .../app/mixins/wizard/addSecurityConfigs.js | 52 ++++++- ambari-web/app/routes/add_kerberos_routes.js | 3 +- .../mixins/wizard/addSeccurityConfigs_test.js | 94 +++++++++++- .../test/mock_data_setup/stack_descriptors.js | 150 +++++++++++++++++-- 5 files changed, 417 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/60c9f8c8/ambari-web/app/assets/data/wizard/kerberos/stack_descriptors.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/wizard/kerberos/stack_descriptors.json b/ambari-web/app/assets/data/wizard/kerberos/stack_descriptors.json index 3bfdf7a..ff9b669 100644 --- a/ambari-web/app/assets/data/wizard/kerberos/stack_descriptors.json +++ b/ambari-web/app/assets/data/wizard/kerberos/stack_descriptors.json @@ -9,19 +9,78 @@ }, "identities": [ { - "name": "spnego", - "principal": { - "value": "HTTP/_HOST@${realm}" + "principal" : { + "value" : "HTTP/_HOST@${realm}", + "configuration" : null }, - "keytab": { - "file": "${keytab_dir}/spnego.service.keytab", - "owner": { - "name": "root", - "access": "r" + "name" : "spnego", + "keytab" : { + "file" : "${keytab_dir}/spnego.service.keytab", + "owner" : { + "name" : "root", + "access" : "r" }, - "group": { - "name": "${cluster-env/user_group}", - "access": "r" + "configuration" : null, + "group" : { + "name" : "${hadoop-env/user_group}", + "access" : "r" + } + } + }, + { + "principal" : { + "value" : "hdfs@${realm}", + "configuration" : "cluster-env/hdfs_principal_name" + }, + "name" : "hdfs", + "keytab" : { + "file" : "${keytab_dir}/hdfs.headless.keytab", + "owner" : { + "name" : "root", + "access" : "r" + }, + "configuration" : "hadoop-env/hdfs_user_keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "r" + } + } + }, + { + "principal" : { + "value" : "hbase@${realm}", + "configuration" : "hbase-env/hbase_principal_name" + }, + "name" : "hbase", + "keytab" : { + "file" : "${keytab_dir}/hbase.headless.keytab", + "owner" : { + "name" : "root", + "access" : "r" + }, + "configuration" : "hbase-env/hbase_user_keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "r" + } + } + }, + { + "principal" : { + "value" : "ambari-qa@${realm}", + "configuration" : "cluster-env/smokeuser_principal_name" + }, + "name" : "smokeuser", + "keytab" : { + "file" : "${keytab_dir}/smokeuser.headless.keytab", + "owner" : { + "name" : "root", + "access" : "r" + }, + "configuration" : "cluster-env/smokeuser_keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "r" } } } @@ -187,6 +246,74 @@ ] } ] + }, + { + "name" : "FALCON", + "identities" : [ + { + "name" : "/spnego" + }, + { + "name" : "/smokeuser" + }, + { + "name" : "/hdfs" + } + ], + "configurations" : [ + { + "falcon-startup.properties" : { + "*.falcon.http.authentication.type" : "kerberos", + "*.falcon.authentication.type" : "kerberos", + "*.dfs.namenode.kerberos.principal" : "nn/_HOST@${realm}" + } + } + ], + "components" : [ + { + "name" : "FALCON_SERVER", + "identities" : [ + { + "principal" : { + "value" : "falcon/${host}@${realm}", + "configuration" : "falcon-startup.properties/*.falcon.service.authentication.kerberos.principal" + }, + "name" : "falcon_server", + "keytab" : { + "file" : "${keytab_dir}/falcon.service.keytab", + "owner" : { + "name" : "${falcon-env/falcon_user}", + "access" : "r" + }, + "configuration" : "falcon-startup.properties/*.falcon.service.authentication.kerberos.keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "" + } + } + }, + { + "principal" : { + "value" : "HTTP/${host}@${realm}", + "configuration" : "falcon-startup.properties/oozie.authentication.kerberos.principal" + }, + "name" : "/spnego", + "keytab" : { + "file" : null, + "owner" : { + "name" : null, + "access" : null + }, + "configuration" : "falcon-startup.properties/oozie.authentication.kerberos.keytab", + "group" : { + "name" : null, + "access" : null + } + } + } + ] + } + ] } ] } http://git-wip-us.apache.org/repos/asf/ambari/blob/60c9f8c8/ambari-web/app/mixins/wizard/addSecurityConfigs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/wizard/addSecurityConfigs.js b/ambari-web/app/mixins/wizard/addSecurityConfigs.js index 9bf1511..5e741b6 100644 --- a/ambari-web/app/mixins/wizard/addSecurityConfigs.js +++ b/ambari-web/app/mixins/wizard/addSecurityConfigs.js @@ -422,6 +422,7 @@ App.AddSecurityConfigs = Em.Mixin.create({ }); // unite cluster and service configs configs = configs.concat(clusterConfigs); + self.processConfigReferences(kerberosDescriptor, configs); // return configs with uniq names return configs.reduce(function(p,c) { if (!p.findProperty('name', c.get('name'))) p.push(c); @@ -448,9 +449,7 @@ App.AddSecurityConfigs = Em.Mixin.create({ componentName: componentName, name: identity.name }; - if (identity.name == '/spnego') { - defaultObject.isEditable = false; - } + self.parseIdentityObject(identity).forEach(function(item) { configs.push(App.ServiceConfigProperty.create($.extend({}, defaultObject, item))); }); @@ -473,8 +472,15 @@ App.AddSecurityConfigs = Em.Mixin.create({ keys.forEach(function(item) { var configObject = {}; var prop = identity[item]; - if (name == '/spnego') configObject.observesValueFrom = 'spnego_' + item; - configObject.defaultValue = configObject.value = item == 'principal' ? prop.value : prop.file; + var itemValue = prop[{keytab: 'file', principal: 'value'}[item]]; + // skip inherited property without `configuration` and `keytab` or `file` values + if (!prop.configuration && !itemValue) return; + // inherited property with value should not observe value from reference + if (name.startsWith('/') && !itemValue) { + configObject.referenceProperty = name.substring(1) + ':' + item; + configObject.isEditable = false; + } + configObject.defaultValue = configObject.value = itemValue; configObject.filename = prop.configuration ? prop.configuration.split('/')[0] : 'cluster-env'; configObject.name = configObject.displayName = prop.configuration ? prop.configuration.split('/')[1] : name + '_' + item; result.push(configObject); @@ -508,6 +514,42 @@ App.AddSecurityConfigs = Em.Mixin.create({ return configs; }, + + /** + * Take care about configs that should observe value from referenced configs. + * Reference is set with `referenceProperty` key. + * + * @param {object[]} kerberosDescriptor + * @param {App.ServiceConfigProperty[]} configs + */ + processConfigReferences: function(kerberosDescriptor, configs) { + var identities = kerberosDescriptor.identities; + identities = identities.concat(kerberosDescriptor.services.map(function(service) { + var _identities = service.identities || []; + if (service.components && !!service.components.length) { + identities = identities.concat(service.components.mapProperty('identities').reduce(function(p, c) { + return p.concat(c); + }, [])); + return identities; + } + }).reduce(function(p, c) { + return p.concat(c); + }, [])); + // clean up array + identities = identities.compact().without(undefined); + configs.forEach(function(item) { + var reference = item.get('referenceProperty'); + if (!!reference) { + var identity = identities.findProperty('name', reference.split(':')[0])[reference.split(':')[1]]; + if (identity && !!identity.configuration) { + item.set('observesValueFrom', identity.configuration.split('/')[1]); + } else { + item.set('observesValueFrom', reference.replace(':', '_')); + } + } + }); + }, + /** * update the kerberos descriptor to be put on cluster resource with user customizations * @param kerberosDescriptor {Object} http://git-wip-us.apache.org/repos/asf/ambari/blob/60c9f8c8/ambari-web/app/routes/add_kerberos_routes.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/add_kerberos_routes.js b/ambari-web/app/routes/add_kerberos_routes.js index 1697209..7241268 100644 --- a/ambari-web/app/routes/add_kerberos_routes.js +++ b/ambari-web/app/routes/add_kerberos_routes.js @@ -171,9 +171,10 @@ module.exports = App.WizardRoute.extend({ console.log('in kerberosWizardController.step4:connectOutlets'); var controller = router.get('kerberosWizardController'); var step4Controller = router.get('kerberosWizardStep4Controller'); + controller.setCurrentStep(4); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); - controller.setCurrentStep(4); + controller.setLowerStepsDisable(4); step4Controller.set('wizardController', controller); controller.connectOutlet('kerberosWizardStep4', controller.get('content')); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/60c9f8c8/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js b/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js index 2cf1768..c327d97 100644 --- a/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js +++ b/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js @@ -340,6 +340,24 @@ describe('App.AddSecurityConfigs', function () { { key: 'value', value: '${keytab_dir}/spnego.service.keytab' }, { key: 'serviceName', value: 'Cluster' }, ] + }, + // principal name inherited from /spnego with predefined value + { + property: 'oozie.authentication.kerberos.principal', + e: [ + { key: 'value', value: 'HTTP/${host}@${realm}' }, + { key: 'isEditable', value: true }, + ] + }, + // keytab inherited from /spnego without predefined file value + { + property: 'oozie.authentication.kerberos.keytab', + e: [ + { key: 'value', value: null }, + { key: 'isEditable', value: false }, + { key: 'referenceProperty', value: 'spnego:keytab' }, + { key: 'observesValueFrom', value: 'spnego_keytab' } + ] } ]; @@ -401,7 +419,7 @@ describe('App.AddSecurityConfigs', function () { { property: 'dfs.web.authentication.kerberos.principal', e: [ - { key: 'observesValueFrom', value: 'spnego_principal' }, + { key: 'referenceProperty', value: 'spnego:principal' }, { key: 'isEditable', value: false } ] } @@ -489,5 +507,77 @@ describe('App.AddSecurityConfigs', function () { }); }); }); - + + describe('#processConfigReferences', function() { + var generateProperty = function(name, reference) { + return Em.Object.create({ name: name, referenceProperty: reference}); + }; + var descriptor = { + identities: [ + { name: 'spnego', principal: { value: 'spnego_value' }, keytab: { file: 'spnego_file'} }, + { name: 'hdfs', + principal: { value: 'hdfs_value', configuration: "hadoop-env/hdfs_user_principal_name" }, + keytab: { file: 'hdfs_file', configuration: "hadoop-env/hdfs_user_keytab"} } + ], + services: [ + { + name: 'SERVICE', + identities: [ + { name: '/spnego' }, + { name: '/hdfs' } + ] + }, + { + name: 'SERVICE2', + components: [ + { + name: 'COMPONENT', + identities: [ + { + name: 'component_prop1', + keytab: { configuration: 'service2-site/component.keytab' }, + principal: { configuration: null } + }, + { + name: 'component_prop2', + keytab: { configuration: 'service2-site/component2.keytab' }, + principal: { configuration: 'service2-site/component2.principal' } + } + ] + } + ] + } + ] + }; + var configs = Em.A([ + generateProperty('spnego_inherited_keytab', 'spnego:keytab'), + generateProperty('spnego_inherited_principal', 'spnego:principal'), + generateProperty('hdfs_inherited_keytab', 'hdfs:keytab'), + generateProperty('hdfs_inherited_principal', 'hdfs:principal'), + generateProperty('component_prop1_inherited_principal', 'component_prop1:principal'), + generateProperty('component_prop1_inherited_keytab', 'component_prop1:keytab'), + generateProperty('component_prop2_inherited_keytab', 'component_prop2:keytab'), + generateProperty('component_prop2_inherited_principal', 'component_prop2:principal'), + ]); + var tests = [ + { name: 'spnego_inherited_keytab', e: 'spnego_keytab' }, + { name: 'spnego_inherited_principal', e: 'spnego_principal' }, + { name: 'hdfs_inherited_keytab', e: 'hdfs_user_keytab' }, + { name: 'hdfs_inherited_principal', e: 'hdfs_user_principal_name' }, + { name: 'component_prop1_inherited_keytab', e: 'component.keytab' }, + { name: 'component_prop1_inherited_principal', e: 'component_prop1_principal' }, + { name: 'component_prop2_inherited_keytab', e: 'component2.keytab' }, + { name: 'component_prop2_inherited_principal', e: 'component2.principal' } + ]; + before(function() { + controller.processConfigReferences(descriptor, configs); + }); + + tests.forEach(function(test) { + it('`{0}` should observe value from `{1}` property'.format(test.name, test.e), function() { + expect(configs.findProperty('name', test.name).get('observesValueFrom')).to.be.eql(test.e); + }); + }); + }); + }); http://git-wip-us.apache.org/repos/asf/ambari/blob/60c9f8c8/ambari-web/test/mock_data_setup/stack_descriptors.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mock_data_setup/stack_descriptors.js b/ambari-web/test/mock_data_setup/stack_descriptors.js index 3e92a20..989d728 100644 --- a/ambari-web/test/mock_data_setup/stack_descriptors.js +++ b/ambari-web/test/mock_data_setup/stack_descriptors.js @@ -17,7 +17,6 @@ */ module.exports = { - "href": "http://162.216.148.139:8080/api/v1/stacks/HDP/versions/2.2?fields=Versions/kerberos_descriptor", "Versions": { "stack_name": "HDP", "stack_version": "2.2", @@ -28,19 +27,78 @@ module.exports = { }, "identities": [ { - "name": "spnego", - "principal": { - "value": "HTTP/_HOST@${realm}" + "principal" : { + "value" : "HTTP/_HOST@${realm}", + "configuration" : null }, - "keytab": { - "file": "${keytab_dir}/spnego.service.keytab", - "owner": { - "name": "root", - "access": "r" + "name" : "spnego", + "keytab" : { + "file" : "${keytab_dir}/spnego.service.keytab", + "owner" : { + "name" : "root", + "access" : "r" }, - "group": { - "name": "${cluster-env/user_group}", - "access": "r" + "configuration" : null, + "group" : { + "name" : "${hadoop-env/user_group}", + "access" : "r" + } + } + }, + { + "principal" : { + "value" : "hdfs@${realm}", + "configuration" : "cluster-env/hdfs_principal_name" + }, + "name" : "hdfs", + "keytab" : { + "file" : "${keytab_dir}/hdfs.headless.keytab", + "owner" : { + "name" : "root", + "access" : "r" + }, + "configuration" : "hadoop-env/hdfs_user_keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "r" + } + } + }, + { + "principal" : { + "value" : "hbase@${realm}", + "configuration" : "hbase-env/hbase_principal_name" + }, + "name" : "hbase", + "keytab" : { + "file" : "${keytab_dir}/hbase.headless.keytab", + "owner" : { + "name" : "root", + "access" : "r" + }, + "configuration" : "hbase-env/hbase_user_keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "r" + } + } + }, + { + "principal" : { + "value" : "ambari-qa@${realm}", + "configuration" : "cluster-env/smokeuser_principal_name" + }, + "name" : "smokeuser", + "keytab" : { + "file" : "${keytab_dir}/smokeuser.headless.keytab", + "owner" : { + "name" : "root", + "access" : "r" + }, + "configuration" : "cluster-env/smokeuser_keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "r" } } } @@ -206,6 +264,74 @@ module.exports = { ] } ] + }, + { + "name" : "FALCON", + "identities" : [ + { + "name" : "/spnego" + }, + { + "name" : "/smokeuser" + }, + { + "name" : "/hdfs" + } + ], + "configurations" : [ + { + "falcon-startup.properties" : { + "*.falcon.http.authentication.type" : "kerberos", + "*.falcon.authentication.type" : "kerberos", + "*.dfs.namenode.kerberos.principal" : "nn/_HOST@${realm}" + } + } + ], + "components" : [ + { + "name" : "FALCON_SERVER", + "identities" : [ + { + "principal" : { + "value" : "falcon/${host}@${realm}", + "configuration" : "falcon-startup.properties/*.falcon.service.authentication.kerberos.principal" + }, + "name" : "falcon_server", + "keytab" : { + "file" : "${keytab_dir}/falcon.service.keytab", + "owner" : { + "name" : "${falcon-env/falcon_user}", + "access" : "r" + }, + "configuration" : "falcon-startup.properties/*.falcon.service.authentication.kerberos.keytab", + "group" : { + "name" : "${cluster-env/user_group}", + "access" : "" + } + } + }, + { + "principal" : { + "value" : "HTTP/${host}@${realm}", + "configuration" : "falcon-startup.properties/oozie.authentication.kerberos.principal" + }, + "name" : "/spnego", + "keytab" : { + "file" : null, + "owner" : { + "name" : null, + "access" : null + }, + "configuration" : "falcon-startup.properties/oozie.authentication.kerberos.keytab", + "group" : { + "name" : null, + "access" : null + } + } + } + ] + } + ] } ] }
