RangerPasswordCheck extends AbstractCheckDescriptor { @Override public void perform(PrerequisiteCheck check, PrereqCheckRequest request) throws AmbariException { URLStreamProvider streamProvider = new URLStreamProvider(2000, 2000, ComponentSSLConfiguration.instance()); String rangerUrl = checkEmpty("admin-properties", "policymgr_external_url", check, request); if (null == rangerUrl) { return; } String adminUsername = checkEmpty("ranger-env", "admin_username", check, request); if (null == adminUsername) { return; } String adminPassword = checkEmpty("ranger-env", "admin_password", check, request); if (null == adminPassword) { return; } String rangerAdminUsername = checkEmpty("ranger-env", "ranger_admin_username", check, request); if (null == rangerAdminUsername) { return; } String rangerAdminPassword = checkEmpty("ranger-env", "ranger_admin_password", check, request); if (null == rangerAdminPassword) { return; } if (rangerUrl.endsWith("/")) { rangerUrl = rangerUrl.substring(0, rangerUrl.length()-1); } String rangerAuthUrl = String.format("%s/%s", rangerUrl, "service/public/api/repository/count"); String rangerUserUrl = String.format("%s/%s", rangerUrl, "service/xusers/users"); List<String> failReasons = new ArrayList<>(); List<String> warnReasons = new ArrayList<>(); try { int response = checkLogin(streamProvider, rangerAuthUrl, adminUsername, adminPassword); switch (response) { case 401: { String reason = getFailReason(KEY_RANGER_PASSWORD_MISMATCH, check, request); failReasons.add(String.format(reason, adminUsername)); break; } case 200: { break; } default: { String reason = getFailReason(KEY_RANGER_UNKNOWN_RESPONSE, check, request); warnReasons.add(String.format(reason, adminUsername, response, rangerAuthUrl)); break; } } } catch (IOException e) { LOG.warn("Could not access the url {}. Message: {}", rangerAuthUrl, e.getMessage(), e); LOG.debug("Could not access the url {}. Message: {}", rangerAuthUrl, e.getMessage()); String reason = getFailReason(KEY_RANGER_COULD_NOT_ACCESS, check, request); warnReasons.add(String.format(reason, adminUsername, rangerAuthUrl, e.getMessage())); } if (!failReasons.isEmpty()) { check.setFailReason(StringUtils.join(failReasons, '\n')); check.getFailedOn().add("RANGER"); check.setStatus(PrereqCheckStatus.FAIL); return; } else if (!warnReasons.isEmpty()) { check.setFailReason(StringUtils.join(warnReasons, '\n')); check.getFailedOn().add("RANGER"); check.setStatus(PrereqCheckStatus.WARNING); return; } boolean hasUser = checkRangerUser(streamProvider, rangerUserUrl, adminUsername, adminPassword, rangerAdminUsername, check, request, warnReasons); if (hasUser) { try { int response = checkLogin(streamProvider, rangerAuthUrl, rangerAdminUsername, rangerAdminPassword); switch (response) { case 401: { String reason = getFailReason(KEY_RANGER_PASSWORD_MISMATCH, check, request); failReasons.add(String.format(reason, rangerAdminUsername)); break; } case 200: { break; } default: { String reason = getFailReason(KEY_RANGER_UNKNOWN_RESPONSE, check, request); warnReasons.add(String.format(reason, rangerAdminUsername, response, rangerAuthUrl)); break; } } } catch (IOException e) { LOG.warn("Could not access the url {}. Message: {}", rangerAuthUrl, e.getMessage()); LOG.debug("Could not access the url {}. Message: {}", rangerAuthUrl, e.getMessage(), e); String reason = getFailReason(KEY_RANGER_COULD_NOT_ACCESS, check, request); warnReasons.add(String.format(reason, rangerAdminUsername, rangerAuthUrl, e.getMessage())); } } if (!failReasons.isEmpty()) { check.setFailReason(StringUtils.join(failReasons, '\n')); check.getFailedOn().add("RANGER"); check.setStatus(PrereqCheckStatus.FAIL); } else if (!warnReasons.isEmpty()) { check.setFailReason(StringUtils.join(warnReasons, '\n')); check.getFailedOn().add("RANGER"); check.setStatus(PrereqCheckStatus.WARNING); } else { check.setStatus(PrereqCheckStatus.PASS); } } RangerPasswordCheck(); @Override boolean isApplicable(PrereqCheckRequest request); @Override void perform(PrerequisiteCheck check, PrereqCheckRequest request);  }
@SuppressWarnings("unchecked") @Test public void testMissingProps() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); m_configMap.clear(); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not check credentials. Missing property admin-properties/policymgr_external_url", check.getFailReason()); m_configMap.put("policymgr_external_url", RANGER_URL); check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not check credentials. Missing property ranger-env/admin_username", check.getFailReason()); m_configMap.put("admin_username", "admin"); check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not check credentials. Missing property ranger-env/admin_password", check.getFailReason()); m_configMap.put("admin_password", "pass"); check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not check credentials. Missing property ranger-env/ranger_admin_username", check.getFailReason()); m_configMap.put("ranger_admin_username", "r_admin"); check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not check credentials. Missing property ranger-env/ranger_admin_password", check.getFailReason()); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_USER_RESPONSE.getBytes())); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); m_configMap.put("ranger_admin_password", "r_pass"); check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.PASS, check.getStatus()); }
@SuppressWarnings("unchecked") @Test public void testNormal() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_USER_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.PASS, check.getStatus()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testNoUser() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(NO_USER_RESPONSE.getBytes())).once(); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.PASS, check.getStatus()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testBadUserParsing() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream( "some really bad non-json".getBytes())); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); String error = "The response from Ranger was malformed. "; error += "com.google.gson.stream.MalformedJsonException: Expected EOF at line 1 column 6. "; error += "Request: " + RANGER_URL + "service/xusers/users?name=r_admin"; assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals(error, check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testJsonCasting() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream( "{ \"data\": \"bad\", \"vXUsers\": \"xyz\" }".getBytes())); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); String error = "The response from Ranger was malformed. "; error += "java.lang.String cannot be cast to java.util.List. "; error += "Request: " + RANGER_URL + "service/xusers/users?name=r_admin"; assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals(error, check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testAdminUnauthorized() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(401); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(CheckDescription.SERVICES_RANGER_PASSWORD_VERIFY, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); assertEquals("Credentials for user 'admin' in Ambari do not match Ranger.", check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testAdminUnauthorizedByRedirect() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(BAD_LOGIN_RESPONSE.getBytes())); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(CheckDescription.SERVICES_RANGER_PASSWORD_VERIFY, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); assertEquals("Credentials for user 'admin' in Ambari do not match Ranger.", check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testAdminIOException() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andThrow(new IOException("whoops")); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(CheckDescription.SERVICES_RANGER_PASSWORD_VERIFY, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not access Ranger to verify user 'admin' against " + RANGER_URL + "service/public/api/repository/count. whoops", check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testAdminBadResponse() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(404); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(CheckDescription.SERVICES_RANGER_PASSWORD_VERIFY, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not verify credentials for user 'admin'. Response code 404 received from " + RANGER_URL + "service/public/api/repository/count", check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testUserUnauthorized() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_USER_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(401); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); assertEquals("Credentials for user 'r_admin' in Ambari do not match Ranger.", check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testUserUnauthorizedByRedirect() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_USER_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(BAD_LOGIN_RESPONSE.getBytes())).once(); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); assertEquals("Credentials for user 'r_admin' in Ambari do not match Ranger.", check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testUserIOException() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_USER_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andThrow(new IOException("again!")); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn(conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not access Ranger to verify user 'r_admin' against " + RANGER_URL + "service/public/api/repository/count. again!", check.getFailReason()); verify(conn, m_streamProvider); }
@SuppressWarnings("unchecked") @Test public void testUserBadResponse() throws Exception { HttpURLConnection conn = EasyMock.createMock(HttpURLConnection.class); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_LOGIN_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(200); expect(conn.getInputStream()).andReturn(new ByteArrayInputStream(GOOD_USER_RESPONSE.getBytes())).once(); expect(conn.getResponseCode()).andReturn(500); expect(m_streamProvider.processURL((String) anyObject(), (String) anyObject(), (InputStream) anyObject(), (Map<String, List<String>>) anyObject())).andReturn( conn).anyTimes(); replay(conn, m_streamProvider); PrerequisiteCheck check = new PrerequisiteCheck(null, null); m_rpc.perform(check, new PrereqCheckRequest("cluster")); assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); assertEquals("Could not verify credentials for user 'r_admin'. Response code 500 received from " + RANGER_URL + "service/public/api/repository/count", check.getFailReason()); verify(conn, m_streamProvider); }