You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/11/13 16:57:18 UTC
[01/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC
integration (rlevas)
Repository: ambari
Updated Branches:
refs/heads/branch-feature-AMBARI-21674 c839dbfe4 -> ff8f686f8
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
index 7bf26c5..e6f0868 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
@@ -18,15 +18,13 @@
package org.apache.ambari.server.serveraction.kerberos;
-import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.easymock.EasyMock.expectLastCall;
import java.io.File;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -45,7 +43,7 @@ import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.stack.OsFamily;
-import org.easymock.EasyMock;
+import org.easymock.EasyMockSupport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -53,11 +51,10 @@ import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
-import com.google.inject.Provider;
import junit.framework.Assert;
-public class KerberosServerActionTest {
+public class KerberosServerActionTest extends EasyMockSupport {
Map<String, String> commandParams = new HashMap<>();
File temporaryDirectory;
@@ -66,49 +63,53 @@ public class KerberosServerActionTest {
@Before
public void setUp() throws Exception {
- final Cluster cluster = mock(Cluster.class);
+ Cluster cluster = createMock(Cluster.class);
- final Clusters clusters = mock(Clusters.class);
- when(clusters.getCluster(anyString())).thenReturn(cluster);
+ Clusters clusters = createMock(Clusters.class);
+ expect(clusters.getCluster(anyString())).andReturn(cluster).anyTimes();
- final ExecutionCommand mockExecutionCommand = mock(ExecutionCommand.class);
- final HostRoleCommand mockHostRoleCommand = mock(HostRoleCommand.class);
+ ExecutionCommand mockExecutionCommand = createMock(ExecutionCommand.class);
+ HostRoleCommand mockHostRoleCommand = createMock(HostRoleCommand.class);
+
+ action = new KerberosServerAction() {
+
+ @Override
+ protected CommandReport processIdentity(Map<String, String> identityRecord, String evaluatedPrincipal,
+ KerberosOperationHandler operationHandler,
+ Map<String, String> kerberosConfiguration,
+ Map<String, Object> requestSharedDataContext)
+ throws AmbariException {
+ Assert.assertNotNull(requestSharedDataContext);
+
+ if (requestSharedDataContext.get("FAIL") != null) {
+ return createCommandReport(1, HostRoleStatus.FAILED, "{}", "ERROR", "ERROR");
+ } else {
+ requestSharedDataContext.put(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL), evaluatedPrincipal);
+ return null;
+ }
+ }
+
+ @Override
+ public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
+ throws AmbariException, InterruptedException {
+ return processIdentities(requestSharedDataContext);
+ }
+ };
+ action.setExecutionCommand(mockExecutionCommand);
+ action.setHostRoleCommand(mockHostRoleCommand);
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class));
- Provider<EntityManager> entityManagerProvider = createNiceMock(Provider.class);
- bind(EntityManager.class).toProvider(entityManagerProvider);
- bind(KerberosServerAction.class).toInstance(new KerberosServerAction() {
-
- @Override
- protected CommandReport processIdentity(Map<String, String> identityRecord, String evaluatedPrincipal,
- KerberosOperationHandler operationHandler,
- Map<String, String> kerberosConfiguration,
- Map<String, Object> requestSharedDataContext)
- throws AmbariException {
- Assert.assertNotNull(requestSharedDataContext);
-
- if (requestSharedDataContext.get("FAIL") != null) {
- return createCommandReport(1, HostRoleStatus.FAILED, "{}", "ERROR", "ERROR");
- } else {
- requestSharedDataContext.put(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL), evaluatedPrincipal);
- return null;
- }
- }
-
- @Override
- public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
- throws AmbariException, InterruptedException {
- return processIdentities(requestSharedDataContext);
- }
- });
+ bind(KerberosHelper.class).toInstance(createMock(KerberosHelper.class));
+ bind(KerberosServerAction.class).toInstance(action);
+ bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
bind(Clusters.class).toInstance(clusters);
bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
bind(AuditLogger.class).toInstance(createNiceMock(AuditLogger.class));
+ bind(KerberosOperationHandlerFactory.class).toInstance(createMock(KerberosOperationHandlerFactory.class));
}
});
@@ -133,13 +134,17 @@ public class KerberosServerActionTest {
commandParams.put(KerberosServerAction.DEFAULT_REALM, "REALM.COM");
commandParams.put(KerberosServerAction.KDC_TYPE, KDCType.MIT_KDC.toString());
- when(mockExecutionCommand.getCommandParams()).thenReturn(commandParams);
- when(mockExecutionCommand.getClusterName()).thenReturn("c1");
-
- action = injector.getInstance(KerberosServerAction.class);
-
- action.setExecutionCommand(mockExecutionCommand);
- action.setHostRoleCommand(mockHostRoleCommand);
+ expect(mockExecutionCommand.getCommandParams()).andReturn(commandParams).anyTimes();
+ expect(mockExecutionCommand.getClusterName()).andReturn("c1").anyTimes();
+ expect(mockExecutionCommand.getConfigurations()).andReturn(Collections.emptyMap()).anyTimes();
+ expect(mockExecutionCommand.getRoleCommand()).andReturn(null).anyTimes();
+ expect(mockExecutionCommand.getConfigurationTags()).andReturn(null).anyTimes();
+ expect(mockExecutionCommand.getRole()).andReturn(null).anyTimes();
+ expect(mockExecutionCommand.getServiceName()).andReturn(null).anyTimes();
+ expect(mockExecutionCommand.getTaskId()).andReturn(1L).anyTimes();
+
+ expect(mockHostRoleCommand.getRequestId()).andReturn(1L).anyTimes();
+ expect(mockHostRoleCommand.getStageId()).andReturn(1L).anyTimes();
}
@After
@@ -189,17 +194,28 @@ public class KerberosServerActionTest {
@Test
public void testGetDataDirectoryPath() throws Exception {
+ replayAll();
Assert.assertEquals(temporaryDirectory.getAbsolutePath(), action.getDataDirectoryPath());
+ verifyAll();
}
@Test
public void testProcessIdentitiesSuccess() throws Exception {
KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
- expect(kerberosHelper.getKDCAdministratorCredentials(EasyMock.anyObject(String.class)))
+ expect(kerberosHelper.getKDCAdministratorCredentials(anyObject(String.class)))
.andReturn(new PrincipalKeyCredential("principal", "password"))
.anyTimes();
- replay(kerberosHelper);
+ KerberosOperationHandler kerberosOperationHandler = createMock(KerberosOperationHandler.class);
+ kerberosOperationHandler.open(anyObject(PrincipalKeyCredential.class), anyString(), anyObject(Map.class));
+ expectLastCall().atLeastOnce();
+ kerberosOperationHandler.close();
+ expectLastCall().atLeastOnce();
+
+ KerberosOperationHandlerFactory factory = injector.getInstance(KerberosOperationHandlerFactory.class);
+ expect(factory.getKerberosOperationHandler(KDCType.MIT_KDC)).andReturn(kerberosOperationHandler).once();
+
+ replayAll();
ConcurrentMap<String, Object> sharedMap = new ConcurrentHashMap<>();
CommandReport report = action.processIdentities(sharedMap);
@@ -210,17 +226,26 @@ public class KerberosServerActionTest {
Assert.assertEquals(entry.getValue(), entry.getKey());
}
- verify(kerberosHelper);
+ verifyAll();
}
@Test
public void testProcessIdentitiesFail() throws Exception {
KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
- expect(kerberosHelper.getKDCAdministratorCredentials(EasyMock.anyObject(String.class)))
+ expect(kerberosHelper.getKDCAdministratorCredentials(anyObject(String.class)))
.andReturn(new PrincipalKeyCredential("principal", "password"))
.anyTimes();
- replay(kerberosHelper);
+ KerberosOperationHandler kerberosOperationHandler = createMock(KerberosOperationHandler.class);
+ kerberosOperationHandler.open(anyObject(PrincipalKeyCredential.class), anyString(), anyObject(Map.class));
+ expectLastCall().atLeastOnce();
+ kerberosOperationHandler.close();
+ expectLastCall().atLeastOnce();
+
+ KerberosOperationHandlerFactory factory = injector.getInstance(KerberosOperationHandlerFactory.class);
+ expect(factory.getKerberosOperationHandler(KDCType.MIT_KDC)).andReturn(kerberosOperationHandler).once();
+
+ replayAll();
ConcurrentMap<String, Object> sharedMap = new ConcurrentHashMap<>();
sharedMap.put("FAIL", "true");
@@ -229,6 +254,6 @@ public class KerberosServerActionTest {
Assert.assertNotNull(report);
Assert.assertEquals(HostRoleStatus.FAILED.toString(), report.getStatus());
- verify(kerberosHelper);
+ verifyAll();
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
index 04d03be..848d479 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
@@ -19,12 +19,9 @@
package org.apache.ambari.server.serveraction.kerberos;
import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.newCapture;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
import java.lang.reflect.Method;
import java.util.HashMap;
@@ -36,11 +33,8 @@ import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.stack.OsFamily;
import org.apache.ambari.server.utils.ShellCommandUtil;
import org.easymock.Capture;
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.easymock.IMockBuilder;
+import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import com.google.inject.AbstractModule;
@@ -49,15 +43,7 @@ import com.google.inject.Injector;
import junit.framework.Assert;
-public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
-
- private static final String DEFAULT_ADMIN_PRINCIPAL = "admin/admin";
- private static final String DEFAULT_ADMIN_PASSWORD = "hadoop";
- private static final String DEFAULT_REALM = "EXAMPLE.COM";
-
- private static Injector injector;
-
- private static Method methodExecuteCommand;
+public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandlerTest {
private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
{
@@ -69,105 +55,75 @@ public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTes
}
};
+ private static Method methodIsOpen;
+
+ private static Method methodPrincipalExists;
+
+ private static Method methodInvokeKAdmin;
+
+ private Injector injector;
+
@BeforeClass
- public static void beforeClass() throws Exception {
+ public static void beforeClassMITKerberosOperationHandlerTestC() throws Exception {
+ methodIsOpen = KerberosOperationHandler.class.getDeclaredMethod("isOpen");
+ methodPrincipalExists = MITKerberosOperationHandler.class.getDeclaredMethod("principalExists", String.class, boolean.class);
+ methodInvokeKAdmin = MITKerberosOperationHandler.class.getDeclaredMethod("invokeKAdmin", String.class);
+ }
+
+ @Before
+ public void beforeMITKerberosOperationHandlerTest() throws Exception {
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- Configuration configuration = EasyMock.createNiceMock(Configuration.class);
+ Configuration configuration = createNiceMock(Configuration.class);
expect(configuration.getServerOsFamily()).andReturn("redhat6").anyTimes();
expect(configuration.getKerberosOperationRetryTimeout()).andReturn(1).anyTimes();
- replay(configuration);
- bind(Clusters.class).toInstance(EasyMock.createNiceMock(Clusters.class));
+ bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
bind(Configuration.class).toInstance(configuration);
- bind(OsFamily.class).toInstance(EasyMock.createNiceMock(OsFamily.class));
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
}
});
-
- methodExecuteCommand = KerberosOperationHandler.class.getDeclaredMethod(
- "executeCommand",
- String[].class,
- Map.class,
- ShellCommandUtil.InteractiveHandler.class);
}
+
@Test
- public void testSetPrincipalPasswordExceptions() throws Exception {
- MITKerberosOperationHandler handler = injector.getInstance(MITKerberosOperationHandler.class);
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+ public void testSetPrincipalPassword() throws Exception {
+ MITKerberosOperationHandler handler = createMockedHandler(methodIsOpen, methodPrincipalExists);
- try {
- handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, null);
- Assert.fail("KerberosOperationException not thrown for null password");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ expect(handler.isOpen()).andReturn(true).atLeastOnce();
+ expect(handler.principalExists(DEFAULT_ADMIN_PRINCIPAL, false)).andReturn(true).atLeastOnce();
+ expect(handler.principalExists(null, false)).andReturn(false).atLeastOnce();
+ expect(handler.principalExists("", false)).andReturn(false).atLeastOnce();
- try {
- handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, "");
- Assert.fail("KerberosOperationException not thrown for empty password");
- handler.createPrincipal("", "1234", false);
- Assert.fail("AmbariException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ replayAll();
+
+ Integer expected = 0;
+
+ // setPrincipalPassword should always return 0
+ Assert.assertEquals(expected, handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, null, false));
+ Assert.assertEquals(expected, handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, "", false));
try {
- handler.setPrincipalPassword(null, DEFAULT_ADMIN_PASSWORD);
- Assert.fail("KerberosOperationException not thrown for null principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
+ handler.setPrincipalPassword(null, DEFAULT_ADMIN_PASSWORD, false);
+ Assert.fail("Expected KerberosPrincipalDoesNotExistException");
+ } catch (KerberosPrincipalDoesNotExistException e) {
+ // Expected...
}
try {
- handler.setPrincipalPassword("", DEFAULT_ADMIN_PASSWORD);
- Assert.fail("KerberosOperationException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
+ handler.setPrincipalPassword("", DEFAULT_ADMIN_PASSWORD, false);
+ Assert.fail("Expected KerberosPrincipalDoesNotExistException");
+ } catch (KerberosPrincipalDoesNotExistException e) {
+ // Expected...
}
- }
-
- @Test(expected = KerberosPrincipalDoesNotExistException.class)
- public void testSetPrincipalPasswordPrincipalDoesNotExist() throws Exception {
- MITKerberosOperationHandler handler = createMockBuilder(MITKerberosOperationHandler.class)
- .addMockedMethod(methodExecuteCommand)
- .createNiceMock();
- injector.injectMembers(handler);
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(0).anyTimes();
- expect(result.isSuccessful()).andReturn(true).anyTimes();
- expect(result.getStderr())
- .andReturn("change_password: Principal does not exist while changing password for \"nonexistant@EXAMPLE.COM\".")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
-
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- handler.setPrincipalPassword("nonexistant@EXAMPLE.COM", "password");
- handler.close();
+ verifyAll();
}
@Test
public void testCreateServicePrincipal_AdditionalAttributes() throws Exception {
- Method invokeKAdmin = MITKerberosOperationHandler.class.getDeclaredMethod("invokeKAdmin", String.class, String.class);
-
Capture<? extends String> query = newCapture();
- Capture<? extends String> password = newCapture();
ShellCommandUtil.Result result1 = createNiceMock(ShellCommandUtil.Result.class);
expect(result1.getStderr()).andReturn("").anyTimes();
@@ -177,72 +133,40 @@ public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTes
expect(result2.getStderr()).andReturn("").anyTimes();
expect(result2.getStdout()).andReturn("Key: vno 1").anyTimes();
- MITKerberosOperationHandler handler = createMockBuilder(MITKerberosOperationHandler.class)
- .addMockedMethod(invokeKAdmin)
- .createStrictMock();
+ ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+ expect(kinitResult.isSuccessful()).andReturn(true);
- expect(handler.invokeKAdmin(capture(query), anyString())).andReturn(result1).once();
- expect(handler.invokeKAdmin("get_principal " + DEFAULT_ADMIN_PRINCIPAL, null)).andReturn(result2).once();
+ MITKerberosOperationHandler handler = createMockedHandler(methodInvokeKAdmin, methodExecuteCommand);
+ expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kinitResult)
+ .once();
+ expect(handler.invokeKAdmin(capture(query))).andReturn(result1).once();
- replay(handler, result1, result2);
+ replayAll();
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+ handler.open(getAdminCredentials(), DEFAULT_REALM, KERBEROS_ENV_MAP);
handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD, false);
+ handler.close();
- verify(handler, result1, result2);
+ verifyAll();
Assert.assertTrue(query.getValue().contains(" " + KERBEROS_ENV_MAP.get(MITKerberosOperationHandler.KERBEROS_ENV_KDC_CREATE_ATTRIBUTES) + " "));
}
- @Test(expected = KerberosPrincipalAlreadyExistsException.class)
- public void testCreatePrincipalPrincipalAlreadyNotExists() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(0).anyTimes();
- expect(result.isSuccessful()).andReturn(true).anyTimes();
- expect(result.getStderr())
- .andReturn("add_principal: Principal or policy already exists while creating \"existing@EXAMPLE.COM\".")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
-
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- handler.createPrincipal("existing@EXAMPLE.COM", "password", false);
- handler.close();
- }
@Test
- public void testCreateServicePrincipal_Exceptions() throws Exception {
- MITKerberosOperationHandler handler = new MITKerberosOperationHandler();
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+ public void testCreateServicePrincipalExceptions() throws Exception {
+ ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+ expect(kinitResult.isSuccessful()).andReturn(true);
- try {
- handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, null, false);
- Assert.fail("KerberosOperationException not thrown for null password");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ MITKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+ expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kinitResult)
+ .once();
- try {
- handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, "", false);
- Assert.fail("KerberosOperationException not thrown for empty password");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ replayAll();
+
+ handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
try {
handler.createPrincipal(null, DEFAULT_ADMIN_PASSWORD, false);
@@ -257,339 +181,156 @@ public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTes
} catch (Throwable t) {
Assert.assertEquals(KerberosOperationException.class, t.getClass());
}
- }
- @Test(expected = KerberosAdminAuthenticationException.class)
- public void testTestAdministratorCredentialsIncorrectAdminPassword() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(1).anyTimes();
- expect(result.isSuccessful()).andReturn(false).anyTimes();
- expect(result.getStderr())
- .andReturn("kadmin: Incorrect password while initializing kadmin interface")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
-
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- handler.testAdministratorCredentials();
- handler.close();
- }
-
- @Test(expected = KerberosAdminAuthenticationException.class)
- public void testTestAdministratorCredentialsIncorrectAdminPrincipal() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(1).anyTimes();
- expect(result.isSuccessful()).andReturn(false).anyTimes();
- expect(result.getStderr())
- .andReturn("kadmin: Client not found in Kerberos database while initializing kadmin interface")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
-
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- handler.testAdministratorCredentials();
- handler.close();
- }
-
- @Test(expected = KerberosRealmException.class)
- public void testTestAdministratorCredentialsInvalidRealm() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(1).anyTimes();
- expect(result.isSuccessful()).andReturn(false).anyTimes();
- expect(result.getStderr())
- .andReturn("kadmin: Missing parameters in krb5.conf required for kadmin client while initializing kadmin interface")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
-
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- handler.testAdministratorCredentials();
- handler.close();
- }
-
- @Test(expected = KerberosRealmException.class)
- public void testTestAdministratorCredentialsInvalidRealm2() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(1).anyTimes();
- expect(result.isSuccessful()).andReturn(false).anyTimes();
- expect(result.getStderr())
- .andReturn("kadmin: Cannot find KDC for requested realm while initializing kadmin interface")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
-
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- handler.testAdministratorCredentials();
- handler.close();
+ verifyAll();
}
@Test(expected = KerberosKDCConnectionException.class)
- public void testTestAdministratorCredentialsKDCConnectionException() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(1).anyTimes();
- expect(result.isSuccessful()).andReturn(false).anyTimes();
- expect(result.getStderr())
- .andReturn("kadmin: Cannot contact any KDC for requested realm while initializing kadmin interface")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
+ public void testKDCConnectionException() throws Exception {
+ ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+ expect(kinitResult.isSuccessful()).andReturn(true).anyTimes();
+
+ ShellCommandUtil.Result kadminResult = createMock(ShellCommandUtil.Result.class);
+ expect(kadminResult.getExitCode()).andReturn(1).anyTimes();
+ expect(kadminResult.isSuccessful()).andReturn(false).anyTimes();
+ expect(kadminResult.getStderr())
+ .andReturn("kadmin: Cannot contact any KDC for requested realm while initializing kadmin interface")
+ .anyTimes();
+ expect(kadminResult.getStdout())
+ .andReturn("Authenticating as principal admin/admin with password.")
+ .anyTimes();
+
+ MITKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+ expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kinitResult)
+ .once();
+ expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kadminResult)
+ .once();
replayAll();
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+ handler.open(getAdminCredentials(), DEFAULT_REALM, KERBEROS_ENV_MAP);
handler.testAdministratorCredentials();
handler.close();
+
+ verifyAll();
}
@Test(expected = KerberosKDCConnectionException.class)
public void testTestAdministratorCredentialsKDCConnectionException2() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(1).anyTimes();
- expect(result.isSuccessful()).andReturn(false).anyTimes();
- expect(result.getStderr())
- .andReturn("kadmin: Cannot resolve network address for admin server in requested realm while initializing kadmin interface")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
+ ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+ expect(kinitResult.isSuccessful()).andReturn(true).anyTimes();
+
+ ShellCommandUtil.Result kadminResult = createMock(ShellCommandUtil.Result.class);
+ expect(kadminResult.getExitCode()).andReturn(1).anyTimes();
+ expect(kadminResult.isSuccessful()).andReturn(false).anyTimes();
+ expect(kadminResult.getStderr())
+ .andReturn("kadmin: Cannot resolve network address for admin server in requested realm while initializing kadmin interface")
+ .anyTimes();
+ expect(kadminResult.getStdout())
+ .andReturn("Authenticating as principal admin/admin with password.")
+ .anyTimes();
+
+ MITKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+ expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kinitResult)
+ .once();
+ expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kadminResult)
+ .once();
replayAll();
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+ handler.open(getAdminCredentials(), DEFAULT_REALM, KERBEROS_ENV_MAP);
handler.testAdministratorCredentials();
handler.close();
- }
-
- @Test
- public void testTestAdministratorCredentialsNotFound() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(0).anyTimes();
- expect(result.isSuccessful()).andReturn(true).anyTimes();
- expect(result.getStderr())
- .andReturn("get_principal: Principal does not exist while retrieving \"admin/admi@EXAMPLE.COM\".")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- Assert.assertFalse(handler.testAdministratorCredentials());
- handler.close();
+ verifyAll();
}
- @Test
- public void testTestAdministratorCredentialsSuccess() throws Exception {
- MITKerberosOperationHandler handler = createMock();
-
- expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
- .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
- @Override
- public ShellCommandUtil.Result answer() throws Throwable {
- ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
- expect(result.getExitCode()).andReturn(0).anyTimes();
- expect(result.isSuccessful()).andReturn(true).anyTimes();
- expect(result.getStderr())
- .andReturn("")
- .anyTimes();
- expect(result.getStdout())
- .andReturn("Authenticating as principal admin/admin with password.\n" +
- "Principal: admin/admin@EXAMPLE.COM\n" +
- "Expiration date: [never]\n" +
- "Last password change: Thu Jan 08 13:09:52 UTC 2015\n" +
- "Password expiration date: [none]\n" +
- "Maximum ticket life: 1 day 00:00:00\n" +
- "Maximum renewable life: 0 days 00:00:00\n" +
- "Last modified: Thu Jan 08 13:09:52 UTC 2015 (root/admin@EXAMPLE.COM)\n" +
- "Last successful authentication: [never]\n" +
- "Last failed authentication: [never]\n" +
- "Failed password attempts: 0\n" +
- "Number of keys: 6\n" +
- "Key: vno 1, aes256-cts-hmac-sha1-96, no salt\n" +
- "Key: vno 1, aes128-cts-hmac-sha1-96, no salt\n" +
- "Key: vno 1, des3-cbc-sha1, no salt\n" +
- "Key: vno 1, arcfour-hmac, no salt\n" +
- "Key: vno 1, des-hmac-sha1, no salt\n" +
- "Key: vno 1, des-cbc-md5, no salt\n" +
- "MKey: vno 1\n" +
- "Attributes:\n" +
- "Policy: [none]")
- .anyTimes();
-
- replay(result);
- return result;
- }
- });
-
- replayAll();
-
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- handler.testAdministratorCredentials();
- handler.close();
+ @Override
+ protected MITKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+ MITKerberosOperationHandler handler = createMockBuilder(MITKerberosOperationHandler.class)
+ .addMockedMethods(mockedMethods)
+ .createMock();
+ injector.injectMembers(handler);
+ return handler;
}
- @Test
- @Ignore
- public void testTestAdministratorCredentialsLive() throws KerberosOperationException {
- MITKerberosOperationHandler handler = new MITKerberosOperationHandler();
- String principal = System.getProperty("principal");
- String password = System.getProperty("password");
- String realm = System.getProperty("realm");
-
- if (principal == null) {
- principal = DEFAULT_ADMIN_PRINCIPAL;
- }
-
- if (password == null) {
- password = DEFAULT_ADMIN_PASSWORD;
- }
-
- if (realm == null) {
- realm = DEFAULT_REALM;
- }
-
- PrincipalKeyCredential credentials = new PrincipalKeyCredential(principal, password);
-
- handler.open(credentials, realm, KERBEROS_ENV_MAP);
- handler.testAdministratorCredentials();
- handler.close();
+ @Override
+ protected Map<String, String> getKerberosEnv() {
+ return KERBEROS_ENV_MAP;
}
- @Test
- public void testInteractivePasswordHandler() {
- MITKerberosOperationHandler.InteractivePasswordHandler handler = new MITKerberosOperationHandler.InteractivePasswordHandler("admin_password", "user_password");
-
- handler.start();
- Assert.assertEquals("admin_password", handler.getResponse("password"));
- Assert.assertFalse(handler.done());
- Assert.assertEquals("user_password", handler.getResponse("password"));
- Assert.assertFalse(handler.done());
- Assert.assertEquals("user_password", handler.getResponse("password"));
- Assert.assertTrue(handler.done());
-
- // Test restarting
- handler.start();
- Assert.assertEquals("admin_password", handler.getResponse("password"));
- Assert.assertFalse(handler.done());
- Assert.assertEquals("user_password", handler.getResponse("password"));
- Assert.assertFalse(handler.done());
- Assert.assertEquals("user_password", handler.getResponse("password"));
- Assert.assertTrue(handler.done());
+ @Override
+ protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(0).anyTimes();
+ expect(result.isSuccessful()).andReturn(true).anyTimes();
+ expect(result.getStderr())
+ .andReturn(String.format("add_principal: Principal or policy already exists while creating \"%s@EXAMPLE.COM\".", (service) ? "service/host" : "user"))
+ .anyTimes();
+ expect(result.getStdout())
+ .andReturn("Authenticating as principal admin/admin with password.")
+ .anyTimes();
+
+ expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "add_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
}
- private MITKerberosOperationHandler createMock(){
- return createMock(false);
+ @Override
+ protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(0).anyTimes();
+ expect(result.isSuccessful()).andReturn(true).anyTimes();
+ expect(result.getStderr())
+ .andReturn(String.format("get_principal: Principal does not exist while retrieving \"%s@EXAMPLE.COM\".", (service) ? "service/host" : "user"))
+ .anyTimes();
+ expect(result.getStdout())
+ .andReturn("Authenticating as principal admin/admin with password.")
+ .anyTimes();
+
+ expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
}
- private MITKerberosOperationHandler createMock(boolean strict) {
- IMockBuilder<MITKerberosOperationHandler> mockBuilder = createMockBuilder(MITKerberosOperationHandler.class)
- .addMockedMethod(methodExecuteCommand);
- MITKerberosOperationHandler result;
- if(strict){
- result = mockBuilder.createStrictMock();
- } else {
- result = mockBuilder.createNiceMock();
- }
- injector.injectMembers(result);
- return result;
+ @Override
+ protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(0).anyTimes();
+ expect(result.isSuccessful()).andReturn(true).anyTimes();
+ expect(result.getStderr())
+ .andReturn("")
+ .anyTimes();
+ expect(result.getStdout())
+ .andReturn(String.format("Authenticating as principal admin/admin with password.\n" +
+ "Principal: %s@EXAMPLE.COM\n" +
+ "Expiration date: [never]\n" +
+ "Last password change: Thu Jan 08 13:09:52 UTC 2015\n" +
+ "Password expiration date: [none]\n" +
+ "Maximum ticket life: 1 day 00:00:00\n" +
+ "Maximum renewable life: 0 days 00:00:00\n" +
+ "Last modified: Thu Jan 08 13:09:52 UTC 2015 (root/admin@EXAMPLE.COM)\n" +
+ "Last successful authentication: [never]\n" +
+ "Last failed authentication: [never]\n" +
+ "Failed password attempts: 0\n" +
+ "Number of keys: 6\n" +
+ "Key: vno 1, aes256-cts-hmac-sha1-96, no salt\n" +
+ "Key: vno 1, aes128-cts-hmac-sha1-96, no salt\n" +
+ "Key: vno 1, des3-cbc-sha1, no salt\n" +
+ "Key: vno 1, arcfour-hmac, no salt\n" +
+ "Key: vno 1, des-hmac-sha1, no salt\n" +
+ "Key: vno 1, des-cbc-md5, no salt\n" +
+ "MKey: vno 1\n" +
+ "Attributes:\n" +
+ "Policy: [none]", (service) ? "service/host" : "user"))
+ .anyTimes();
+
+ expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
index 25e9dbf..bd8f5cb 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
@@ -24,7 +24,9 @@ import static org.apache.ambari.server.upgrade.UpgradeCatalog300.SERVICE_DESIRED
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
@@ -34,19 +36,23 @@ import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertTrue;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
import org.apache.ambari.server.controller.MaintenanceStateHelper;
+import org.apache.ambari.server.controller.ServiceConfigVersionResponse;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
@@ -130,13 +136,15 @@ public class UpgradeCatalog300Test {
Method showHcatDeletedUserMessage = UpgradeCatalog300.class.getDeclaredMethod("showHcatDeletedUserMessage");
Method setStatusOfStagesAndRequests = UpgradeCatalog300.class.getDeclaredMethod("setStatusOfStagesAndRequests");
Method updateLogSearchConfigs = UpgradeCatalog300.class.getDeclaredMethod("updateLogSearchConfigs");
-
- UpgradeCatalog300 upgradeCatalog300 = createMockBuilder(UpgradeCatalog300.class)
- .addMockedMethod(showHcatDeletedUserMessage)
- .addMockedMethod(addNewConfigurationsFromXml)
- .addMockedMethod(setStatusOfStagesAndRequests)
- .addMockedMethod(updateLogSearchConfigs)
- .createMock();
+ Method updateKerberosConfigurations = UpgradeCatalog300.class.getDeclaredMethod("updateKerberosConfigurations");
+
+ UpgradeCatalog300 upgradeCatalog300 = createMockBuilder(UpgradeCatalog300.class)
+ .addMockedMethod(showHcatDeletedUserMessage)
+ .addMockedMethod(addNewConfigurationsFromXml)
+ .addMockedMethod(setStatusOfStagesAndRequests)
+ .addMockedMethod(updateLogSearchConfigs)
+ .addMockedMethod(updateKerberosConfigurations)
+ .createMock();
upgradeCatalog300.addNewConfigurationsFromXml();
@@ -146,6 +154,9 @@ public class UpgradeCatalog300Test {
upgradeCatalog300.updateLogSearchConfigs();
expectLastCall().once();
+ upgradeCatalog300.updateKerberosConfigurations();
+ expectLastCall().once();
+
replay(upgradeCatalog300);
upgradeCatalog300.executeDMLUpdates();
@@ -168,9 +179,12 @@ public class UpgradeCatalog300Test {
Capture<DBAccessor.DBColumnInfo> hrcOpsDisplayNameColumn = newCapture();
dbAccessor.addColumn(eq(UpgradeCatalog300.HOST_ROLE_COMMAND_TABLE), capture(hrcOpsDisplayNameColumn));
- dbAccessor.dropColumn(COMPONENT_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN); expectLastCall().once();
- dbAccessor.dropColumn(COMPONENT_STATE_TABLE, SECURITY_STATE_COLUMN); expectLastCall().once();
- dbAccessor.dropColumn(SERVICE_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN); expectLastCall().once();
+ dbAccessor.dropColumn(COMPONENT_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN);
+ expectLastCall().once();
+ dbAccessor.dropColumn(COMPONENT_STATE_TABLE, SECURITY_STATE_COLUMN);
+ expectLastCall().once();
+ dbAccessor.dropColumn(SERVICE_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN);
+ expectLastCall().once();
replay(dbAccessor, configuration);
@@ -221,9 +235,9 @@ public class UpgradeCatalog300Test {
Collection<Config> configs = Arrays.asList(confSomethingElse1, confLogSearchConf1, confSomethingElse2, confLogSearchConf2);
expect(cluster.getAllConfigs()).andReturn(configs).atLeastOnce();
- configHelper.removeConfigsByType(cluster,"service-1-logsearch-conf");
+ configHelper.removeConfigsByType(cluster, "service-1-logsearch-conf");
expectLastCall().once();
- configHelper.removeConfigsByType(cluster,"service-2-logsearch-conf");
+ configHelper.removeConfigsByType(cluster, "service-2-logsearch-conf");
expectLastCall().once();
configHelper.createConfigType(anyObject(Cluster.class), anyObject(StackId.class), eq(controller),
eq("logsearch-common-properties"), eq(Collections.emptyMap()), eq("ambari-upgrade"),
@@ -307,23 +321,23 @@ public class UpgradeCatalog300Test {
Map<String, String> oldLogFeederOutputConf = ImmutableMap.of(
"content",
" \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
- " \"collection\":\"{{logsearch_solr_collection_service_logs}}\",\n" +
- " \"number_of_shards\": \"{{logsearch_collection_service_logs_numshards}}\",\n" +
- " \"splits_interval_mins\": \"{{logsearch_service_logs_split_interval_mins}}\",\n" +
- "\n" +
- " \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
- " \"collection\":\"{{logsearch_solr_collection_audit_logs}}\",\n" +
- " \"number_of_shards\": \"{{logsearch_collection_audit_logs_numshards}}\",\n" +
- " \"splits_interval_mins\": \"{{logsearch_audit_logs_split_interval_mins}}\",\n"
+ " \"collection\":\"{{logsearch_solr_collection_service_logs}}\",\n" +
+ " \"number_of_shards\": \"{{logsearch_collection_service_logs_numshards}}\",\n" +
+ " \"splits_interval_mins\": \"{{logsearch_service_logs_split_interval_mins}}\",\n" +
+ "\n" +
+ " \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
+ " \"collection\":\"{{logsearch_solr_collection_audit_logs}}\",\n" +
+ " \"number_of_shards\": \"{{logsearch_collection_audit_logs_numshards}}\",\n" +
+ " \"splits_interval_mins\": \"{{logsearch_audit_logs_split_interval_mins}}\",\n"
);
Map<String, String> expectedLogFeederOutputConf = ImmutableMap.of(
"content",
" \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
- " \"type\": \"service\",\n" +
- "\n" +
- " \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
- " \"type\": \"audit\",\n"
+ " \"type\": \"service\",\n" +
+ "\n" +
+ " \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
+ " \"type\": \"audit\",\n"
);
Config logFeederOutputConf = easyMockSupport.createNiceMock(Config.class);
@@ -343,10 +357,10 @@ public class UpgradeCatalog300Test {
new UpgradeCatalog300(injector2).updateLogSearchConfigs();
easyMockSupport.verifyAll();
- Map<String,String> newLogFeederProperties = logFeederPropertiesCapture.getValue();
+ Map<String, String> newLogFeederProperties = logFeederPropertiesCapture.getValue();
assertTrue(Maps.difference(expectedLogFeederProperties, newLogFeederProperties).areEqual());
- Map<String,String> newLogSearchProperties = logSearchPropertiesCapture.getValue();
+ Map<String, String> newLogSearchProperties = logSearchPropertiesCapture.getValue();
assertTrue(Maps.difference(Collections.emptyMap(), newLogSearchProperties).areEqual());
Map<String, String> updatedLogFeederLog4j = logFeederLog4jCapture.getValue();
@@ -364,4 +378,90 @@ public class UpgradeCatalog300Test {
Map<String, String> updatedLogFeederOutputConf = logFeederOutputConfCapture.getValue();
assertTrue(Maps.difference(expectedLogFeederOutputConf, updatedLogFeederOutputConf).areEqual());
}
+
+ @Test
+ public void testUpdateKerberosConfigurations() throws AmbariException, NoSuchFieldException, IllegalAccessException {
+ StackId stackId = new StackId("HDP", "2.6.0.0");
+
+ Map<String, Cluster> clusterMap = new HashMap<>();
+
+ Map<String, String> propertiesWithGroup = new HashMap<>();
+ propertiesWithGroup.put("group", "ambari_managed_identities");
+ propertiesWithGroup.put("kdc_host", "host1.example.com");
+
+ Config newConfig = createMock(Config.class);
+ expect(newConfig.getTag()).andReturn("version2").atLeastOnce();
+ expect(newConfig.getType()).andReturn("kerberos-env").atLeastOnce();
+
+ ServiceConfigVersionResponse response = createMock(ServiceConfigVersionResponse.class);
+
+ Config configWithGroup = createMock(Config.class);
+ expect(configWithGroup.getProperties()).andReturn(propertiesWithGroup).atLeastOnce();
+ expect(configWithGroup.getPropertiesAttributes()).andReturn(Collections.emptyMap()).atLeastOnce();
+ expect(configWithGroup.getTag()).andReturn("version1").atLeastOnce();
+
+ Cluster cluster1 = createMock(Cluster.class);
+ expect(cluster1.getDesiredConfigByType("kerberos-env")).andReturn(configWithGroup).atLeastOnce();
+ expect(cluster1.getConfigsByType("kerberos-env")).andReturn(Collections.singletonMap("v1", configWithGroup)).atLeastOnce();
+ expect(cluster1.getServiceByConfigType("kerberos-env")).andReturn("KERBEROS").atLeastOnce();
+ expect(cluster1.getClusterName()).andReturn("c1").atLeastOnce();
+ expect(cluster1.getDesiredStackVersion()).andReturn(stackId).atLeastOnce();
+ expect(cluster1.getConfig(eq("kerberos-env"), anyString())).andReturn(newConfig).atLeastOnce();
+ expect(cluster1.addDesiredConfig("ambari-upgrade", Collections.singleton(newConfig), "Updated kerberos-env during Ambari Upgrade from 2.6.0 to 3.0.0.")).andReturn(response).once();
+
+ Map<String, String> propertiesWithoutGroup = new HashMap<>();
+ propertiesWithoutGroup.put("kdc_host", "host2.example.com");
+
+ Config configWithoutGroup = createMock(Config.class);
+ expect(configWithoutGroup.getProperties()).andReturn(propertiesWithoutGroup).atLeastOnce();
+
+ Cluster cluster2 = createMock(Cluster.class);
+ expect(cluster2.getDesiredConfigByType("kerberos-env")).andReturn(configWithoutGroup).atLeastOnce();
+
+ Cluster cluster3 = createMock(Cluster.class);
+ expect(cluster3.getDesiredConfigByType("kerberos-env")).andReturn(null).atLeastOnce();
+
+ clusterMap.put("c1", cluster1);
+ clusterMap.put("c2", cluster2);
+ clusterMap.put("c3", cluster3);
+
+ Clusters clusters = createMock(Clusters.class);
+ expect(clusters.getClusters()).andReturn(clusterMap).anyTimes();
+
+ Capture<Map<String, String>> capturedProperties = newCapture();
+
+ AmbariManagementControllerImpl controller = createMockBuilder(AmbariManagementControllerImpl.class)
+ .addMockedMethod("createConfiguration")
+ .addMockedMethod("getClusters", new Class[]{})
+ .addMockedMethod("createConfig")
+ .createMock();
+ expect(controller.getClusters()).andReturn(clusters).anyTimes();
+ expect(controller.createConfig(eq(cluster1), eq(stackId), eq("kerberos-env"), capture(capturedProperties), anyString(), anyObject(Map.class))).andReturn(newConfig).once();
+
+
+ Injector injector = createNiceMock(Injector.class);
+ expect(injector.getInstance(AmbariManagementController.class)).andReturn(controller).anyTimes();
+
+ replay(controller, clusters, cluster1, cluster2, configWithGroup, configWithoutGroup, newConfig, response, injector);
+
+ Field field = AbstractUpgradeCatalog.class.getDeclaredField("configuration");
+
+ UpgradeCatalog300 upgradeCatalog300 = new UpgradeCatalog300(injector);
+ field.set(upgradeCatalog300, configuration);
+ upgradeCatalog300.updateKerberosConfigurations();
+
+ verify(controller, clusters, cluster1, cluster2, configWithGroup, configWithoutGroup, newConfig, response, injector);
+
+
+ Assert.assertEquals(1, capturedProperties.getValues().size());
+
+ Map<String, String> properties = capturedProperties.getValue();
+ Assert.assertEquals(2, properties.size());
+ Assert.assertEquals("ambari_managed_identities", properties.get("ipa_user_group"));
+ Assert.assertEquals("host1.example.com", properties.get("kdc_host"));
+
+ Assert.assertEquals(2, propertiesWithGroup.size());
+ Assert.assertEquals("ambari_managed_identities", propertiesWithGroup.get("group"));
+ Assert.assertEquals("host1.example.com", propertiesWithGroup.get("kdc_host"));
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json b/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
index 288d155..69000df 100644
--- a/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
+++ b/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
@@ -432,9 +432,7 @@
"create_ambari_principal": "true",
"service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
"executable_search_paths": "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
- "password_chat_timeout": "5",
"kdc_type": "mit-kdc",
- "set_password_expiry": "false",
"password_min_punctuation": "1",
"container_dn": "",
"case_insensitive_username_rules": "false",
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json b/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
index f7f054a..daef35d 100644
--- a/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
+++ b/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
@@ -529,9 +529,7 @@
"create_ambari_principal": "true",
"service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
"executable_search_paths": "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
- "password_chat_timeout": "5",
"kdc_type": "mit-kdc",
- "set_password_expiry": "false",
"password_min_punctuation": "1",
"container_dn": "",
"case_insensitive_username_rules": "false",
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json b/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
index 38b5906..06b247a 100644
--- a/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
+++ b/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
@@ -456,9 +456,7 @@
"create_ambari_principal": "true",
"service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
"executable_search_paths": "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
- "password_chat_timeout": "5",
"kdc_type": "mit-kdc",
- "set_password_expiry": "false",
"password_min_punctuation": "1",
"container_dn": "",
"case_insensitive_username_rules": "false",
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json b/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
index 2a744c7..0b357e9 100644
--- a/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
+++ b/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
@@ -95,7 +95,6 @@
"manage_auth_to_local": "true",
"manage_identities": "true",
"master_kdc": "",
- "password_chat_timeout": "5",
"password_length": "20",
"password_min_digits": "1",
"password_min_lowercase_letters": "1",
@@ -104,7 +103,6 @@
"password_min_whitespace": "0",
"preconfigure_services": "DEFAULT",
"realm": "EXAMPLE.COM",
- "service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
- "set_password_expiry": "false"
+ "service_check_principal_name": "${cluster_name|toLower()}-${short_date}"
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
index 05b0b31..a97e04e 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
@@ -46,7 +46,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
type: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc')
},
'ipa': {
- configNames: ['group', 'set_password_expiry', 'password_chat_timeout'],
+ configNames: ['ipa_user_group'],
type: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa')
}
},
[44/51] [abbrv] ambari git commit: AMBARI-22415. Blueprint deploys
failing with missing smoke user keytab file (echekanskiy)
Posted by nc...@apache.org.
AMBARI-22415. Blueprint deploys failing with missing smoke user keytab file (echekanskiy)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ec02a14c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ec02a14c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ec02a14c
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: ec02a14c02529ec7fec647e6fed7c8c401f10e6d
Parents: 22b2d55
Author: Eugene Chekanskiy <ec...@gmail.com>
Authored: Fri Nov 10 17:17:34 2017 +0200
Committer: Eugene Chekanskiy <ec...@gmail.com>
Committed: Fri Nov 10 18:29:43 2017 +0200
----------------------------------------------------------------------
.../kerberos/CreateKeytabFilesServerAction.java | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ec02a14c/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
index aa65e61..5ec4c10 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
@@ -218,17 +218,18 @@ public class CreateKeytabFilesServerAction extends KerberosServerAction {
}
boolean regenerateKeytabs = getOperationType(getCommandParameters()) == OperationType.RECREATE_ALL;
+
+ KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
+ String cachedKeytabPath = (principalEntity == null) ? null : principalEntity.getCachedKeytabPath();
+
if (password == null) {
if (!regenerateKeytabs && (hostName.equalsIgnoreCase(KerberosHelper.AMBARI_SERVER_HOST_NAME) || kerberosPrincipalHostDAO
- .exists(evaluatedPrincipal, hostEntity.getHostId(), keytabFilePath))) {
+ .exists(evaluatedPrincipal, hostEntity.getHostId(), keytabFilePath)) && cachedKeytabPath == null) {
// There is nothing to do for this since it must already exist and we don't want to
// regenerate the keytab
message = String.format("Skipping keytab file for %s, missing password indicates nothing to do", evaluatedPrincipal);
LOG.debug(message);
} else {
- KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
- String cachedKeytabPath = (principalEntity == null) ? null : principalEntity.getCachedKeytabPath();
-
if (cachedKeytabPath == null) {
message = String.format("Failed to create keytab for %s, missing cached file", evaluatedPrincipal);
actionLog.writeStdErr(message);
[21/51] [abbrv] ambari git commit: AMBARI-22376 Log Search UI: add
navigation to first and last page. (Istvan Tobias via ababiichuk)
Posted by nc...@apache.org.
AMBARI-22376 Log Search UI: add navigation to first and last page. (Istvan Tobias via ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/38f6740c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/38f6740c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/38f6740c
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 38f6740cdacc0c18e87f1b5b979e1ddb9519dcd8
Parents: cbce5e8
Author: Istvan Tobias <to...@gmail.com>
Authored: Tue Nov 7 17:00:58 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Tue Nov 7 17:33:35 2017 +0200
----------------------------------------------------------------------
.../pagination-controls.component.html | 15 ++-
.../pagination-controls.component.spec.ts | 101 +++++++++++++++++++
.../pagination-controls.component.ts | 71 ++++++++++++-
3 files changed, 177 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/38f6740c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
index c227a2b..370d1c7 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
@@ -14,10 +14,15 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<button class="btn btn-link" [disabled]="currentPage === 0" (click)="updateValue(true)">
- <span class="pagination-control fa fa-chevron-left"></span>
+<button class="btn btn-link" [disabled]="!hasPreviousPage()" (click)="setFirstPage()">
+ <span class="pagination-control fa fa-angle-double-left"></span>
+</button>
+<button class="btn btn-link" [disabled]="!hasPreviousPage()" (click)="setPreviousPage()">
+ <span class="pagination-control fa fa-angle-left"></span>
+</button>
+<button class="btn btn-link" [disabled]="!hasNextPage()" (click)="setNextPage()">
+ <span class="pagination-control fa fa-angle-right"></span>
</button>
-<button class="btn btn-link" [disabled]="currentPage === pagesCount - 1" (click)="updateValue()">
- <span class="pagination-control fa fa-chevron-right"></span>
+<button class="btn btn-link" [disabled]="!hasNextPage()" (click)="setLastPage()">
+ <span class="pagination-control fa fa-angle-double-right"></span>
</button>
http://git-wip-us.apache.org/repos/asf/ambari/blob/38f6740c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
index 489f79c..999609c 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
@@ -34,10 +34,111 @@ describe('PaginationControlsComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(PaginationControlsComponent);
component = fixture.componentInstance;
+ component.registerOnChange(() => {});
+ component.pagesCount = 3;
+ component.totalCount = 30;
fixture.detectChanges();
});
it('should create component', () => {
expect(component).toBeTruthy();
});
+
+ it('should the hasNextPage function return true when the currentPage is less than the pagesCount', () => {
+ component.pagesCount = 3;
+ component.totalCount = 30;
+ fixture.detectChanges();
+ expect(component.hasNextPage()).toBe(true);
+ });
+ it('should the hasNextPage function return false when the currentPage is equal than the pagesCount', () => {
+ component.currentPage = 3;
+ fixture.detectChanges();
+ expect(component.hasNextPage()).toBe(false);
+ });
+ it('should the hasNextPage function return false when the pagesCount is 0', () => {
+ component.pagesCount = 0;
+ component.totalCount = 0;
+ component.currentPage = 0;
+ fixture.detectChanges();
+ expect(component.hasNextPage()).toBe(false);
+ });
+
+ it('should the hasPreviousPage function return true when the currentPage is greater than 0 and the pagesCount is greater than 0', () => {
+ component.currentPage = 1;
+ fixture.detectChanges();
+ expect(component.hasPreviousPage()).toBe(true);
+ });
+ it('should the hasPreviousPage function return false when the currentPage is equal to 0', () => {
+ component.currentPage = 0;
+ fixture.detectChanges();
+ expect(component.hasPreviousPage()).toBe(false);
+ });
+ it('should the hasPreviousPage function return false when the pagesCount is 0', () => {
+ component.pagesCount = 0;
+ component.totalCount = 0;
+ fixture.detectChanges();
+ expect(component.hasPreviousPage()).toBe(false);
+ });
+
+ it('should the setNextPage function increment the value/currentPage when it is less then the pagesCount', () => {
+ let initialPage = 0;
+ let pagesCount = 3;
+ component.pagesCount = pagesCount;
+ component.totalCount = 30;
+ component.currentPage = initialPage;
+ fixture.detectChanges();
+ component.setNextPage();
+ fixture.detectChanges();
+ expect(component.currentPage).toEqual(initialPage + 1);
+ });
+
+ it('should not the setNextPage function increment the value/currentPage when it is on the last page', () => {
+ let pagesCount = 3;
+ component.pagesCount = pagesCount;
+ component.totalCount = 30;
+ component.currentPage = pagesCount - 1;
+ fixture.detectChanges();
+ component.setNextPage();
+ fixture.detectChanges();
+ expect(component.currentPage).toEqual(pagesCount - 1);
+ });
+
+ it('should the setPreviousPage function decrement the value/currentPage', () => {
+ let initialPage = 1;
+ component.pagesCount = 3;
+ component.totalCount = 30;
+ component.currentPage = initialPage;
+ fixture.detectChanges();
+ component.setPreviousPage();
+ fixture.detectChanges();
+ expect(component.currentPage).toEqual(initialPage - 1);
+ });
+
+ it('should not the setPreviousPage function decrement the value/currentPage when it is equal to 0', () => {
+ component.pagesCount = 3;
+ component.totalCount = 30;
+ component.currentPage = 0;
+ fixture.detectChanges();
+ component.setPreviousPage();
+ fixture.detectChanges();
+ expect(component.currentPage).toEqual(0);
+ });
+
+ it('should the setFirstPage set the value/currentPage to 0', () => {
+ component.pagesCount = 3;
+ component.totalCount = 30;
+ component.currentPage = 1;
+ fixture.detectChanges();
+ component.setFirstPage();
+ fixture.detectChanges();
+ expect(component.currentPage).toEqual(0);
+ });
+
+
+ it('should the setLastPage set the value/currentPage to the value of pagesCount', () => {
+ component.setLastPage();
+ fixture.detectChanges();
+ expect(component.currentPage).toEqual(component.pagesCount - 1);
+ });
+
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/38f6740c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
index c71844c..81676a9 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
@@ -51,13 +51,74 @@ export class PaginationControlsComponent implements ControlValueAccessor {
}
set value(newValue: number) {
- this.currentPage = newValue;
- this.currentPageChange.emit(newValue);
- this.onChange(newValue);
+ if (this.isValidValue(newValue)) { // this is the last validation check
+ this.currentPage = newValue;
+ this.currentPageChange.emit(newValue);
+ this.onChange(newValue);
+ } else {
+ throw new Error(`Invalid value ${newValue}. The currentPage should be between 0 and ${this.pagesCount}.`);
+ }
+ }
+
+ /**
+ * A simple check if the given value is valid for the current pagination instance
+ * @param {number} value The new value to test
+ * @returns {boolean}
+ */
+ private isValidValue(value: number): boolean {
+ return value <= this.pagesCount || value >= 0;
+ }
+
+ /**
+ * The goal is to set the value to the first page... obviously to zero. It is just to have a centralized api for that.
+ */
+ setFirstPage(): void {
+ this.value = 0;
+ }
+
+ /**
+ * The goal is to set the value to the last page which is the pagesCount property anyway.
+ */
+ setLastPage(): void {
+ this.value = this.pagesCount - 1;
+ }
+
+ /**
+ * The goal is to decrease the value (currentPage) property if it is possible (checking with 'hasPreviousPage').
+ * @returns {number} The new value of the currentPage
+ */
+ setPreviousPage(): number {
+ if (this.hasPreviousPage()) {
+ this.value -= 1;
+ }
+ return this.value;
+ }
+
+ /**
+ * The goal is to increase the value (currentPage) property if it is possible (checking with 'hasNextPage').
+ * @returns {number} The new value of the currentPage
+ */
+ setNextPage(): number {
+ if (this.hasNextPage()){
+ this.value += 1;
+ }
+ return this.value;
+ }
+
+ /**
+ * The goal is to have a single source of true to check if we can set a next page or not.
+ * @returns {boolean}
+ */
+ hasNextPage(): boolean {
+ return this.pagesCount > 0 && this.value < this.pagesCount - 1;
}
- updateValue(isDecrement?: boolean) {
- isDecrement? this.value-- : this.value++;
+ /**
+ * The goal is to have a single source of true to check if we can set a previous page or not.
+ * @returns {boolean}
+ */
+ hasPreviousPage(): boolean {
+ return this.pagesCount > 0 && this.value > 0;
}
writeValue() {
[06/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement
new design for Admin View. (atkach)
Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css
new file mode 100644
index 0000000..7d1ad61
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css
@@ -0,0 +1,1518 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+@font-face {
+ font-family: 'Roboto';
+ font-weight: normal;
+ font-style: normal;
+ src: url('fonts/Roboto-Regular-webfont.eot');
+ src: url('fonts/Roboto-Regular-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/Roboto-Regular-webfont.woff') format('woff'), url('fonts/Roboto-Regular-webfont.ttf') format('truetype'), url('fonts/Roboto-Regular-webfont.svg#robotoregular') format('svg');
+}
+.font-mixin {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+}
+.btn,
+.btn:focus {
+ outline: none;
+ font-family: 'Roboto', sans-serif;
+ text-transform: uppercase;
+ height: 34px;
+ font-size: 14px;
+ padding: 10px 20px;
+ line-height: 14px;
+}
+.btn .glyphicon,
+.btn:focus .glyphicon {
+ top: -1px;
+ float: left;
+}
+.box-shadow {
+ box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-disabled {
+ opacity: 0.6;
+ box-shadow: none;
+}
+.btn-default-disabled {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #FFF;
+ background-color: #808793;
+ border: none;
+}
+.btn-default,
+.btn-default:focus {
+ color: #666;
+ background-color: #FFF;
+ border: 1px solid #CFD3D7;
+}
+.btn-default:hover,
+.btn-default:focus:hover {
+ color: #FFF;
+ background-color: #808793;
+}
+.btn-default:active,
+.btn-default:focus:active {
+ color: #666;
+ background-color: #FFF;
+ border: 1px solid #CFD3D7;
+ box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-default[disabled],
+.btn-default:focus[disabled],
+.btn-default.disabled,
+.btn-default:focus.disabled {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #FFF;
+ background-color: #808793;
+ border: none;
+}
+.btn-default[disabled]:active,
+.btn-default:focus[disabled]:active,
+.btn-default.disabled:active,
+.btn-default:focus.disabled:active,
+.btn-default[disabled].active,
+.btn-default:focus[disabled].active,
+.btn-default.disabled.active,
+.btn-default:focus.disabled.active,
+.btn-default[disabled]:hover,
+.btn-default:focus[disabled]:hover,
+.btn-default.disabled:hover,
+.btn-default:focus.disabled:hover {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #FFF;
+ background-color: #808793;
+ border: none;
+}
+.btn-primary-disabled {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #D1E8D1;
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+}
+.btn-primary,
+.btn-primary:focus {
+ color: #FFF;
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+}
+.btn-primary:hover,
+.btn-primary:focus:hover {
+ color: #FFF;
+ background-color: #429929;
+ border: 1px solid #429929;
+}
+.btn-primary:active,
+.btn-primary:focus:active,
+.btn-primary.active,
+.btn-primary:focus.active {
+ color: #FFF;
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+ box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-primary[disabled],
+.btn-primary:focus[disabled],
+.btn-primary.disabled,
+.btn-primary:focus.disabled {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #D1E8D1;
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+}
+.btn-primary[disabled]:active,
+.btn-primary:focus[disabled]:active,
+.btn-primary.disabled:active,
+.btn-primary:focus.disabled:active,
+.btn-primary[disabled].active,
+.btn-primary:focus[disabled].active,
+.btn-primary.disabled.active,
+.btn-primary:focus.disabled.active,
+.btn-primary[disabled]:hover,
+.btn-primary:focus[disabled]:hover,
+.btn-primary.disabled:hover,
+.btn-primary:focus.disabled:hover {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #D1E8D1;
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+}
+.btn-secondary-disabled {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #D1E8D1;
+ background-color: #429929;
+ border: 1px solid #3FAE2A;
+}
+.btn-secondary,
+.btn-secondary:focus {
+ color: #429929;
+ background-color: #FFF;
+ border: 1px solid #3FAE2A;
+}
+.btn-secondary:hover,
+.btn-secondary:focus:hover {
+ color: #FFF;
+ background-color: #429929;
+}
+.btn-secondary:active,
+.btn-secondary:focus:active {
+ color: #429929;
+ background-color: #FFF;
+ box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-secondary[disabled],
+.btn-secondary:focus[disabled],
+.btn-secondary.disabled,
+.btn-secondary:focus.disabled {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #D1E8D1;
+ background-color: #429929;
+ border: 1px solid #3FAE2A;
+}
+.btn-secondary[disabled]:active,
+.btn-secondary:focus[disabled]:active,
+.btn-secondary.disabled:active,
+.btn-secondary:focus.disabled:active,
+.btn-secondary[disabled].active,
+.btn-secondary:focus[disabled].active,
+.btn-secondary.disabled.active,
+.btn-secondary:focus.disabled.active,
+.btn-secondary[disabled]:hover,
+.btn-secondary:focus[disabled]:hover,
+.btn-secondary.disabled:hover,
+.btn-secondary:focus.disabled:hover {
+ opacity: 0.6;
+ box-shadow: none;
+ color: #D1E8D1;
+ background-color: #429929;
+ border: 1px solid #3FAE2A;
+}
+.btn-success {
+ border: none;
+}
+.btn-regular-default-state {
+ background-color: #FFF;
+ color: #666;
+ border: 1px solid #cfd3d7;
+}
+.btn-primary-default-state {
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+ color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle,
+.dropdown.open .btn.dropdown-toggle {
+ box-shadow: inset 0px 0px 3px 0px #1391c1;
+}
+.btn-group.open .btn.dropdown-toggle,
+.dropdown.open .btn.dropdown-toggle,
+.btn-group.open .btn.dropdown-toggle.btn-default,
+.dropdown.open .btn.dropdown-toggle.btn-default {
+ background-color: #FFF;
+ color: #666;
+ border: 1px solid #cfd3d7;
+}
+.btn-group.open .btn.dropdown-toggle:hover,
+.dropdown.open .btn.dropdown-toggle:hover,
+.btn-group.open .btn.dropdown-toggle.btn-default:hover,
+.dropdown.open .btn.dropdown-toggle.btn-default:hover {
+ background-color: #FFF;
+ color: #666;
+ border: 1px solid #cfd3d7;
+}
+.btn-group.open .btn.dropdown-toggle + .dropdown-menu > li > a:hover,
+.dropdown.open .btn.dropdown-toggle + .dropdown-menu > li > a:hover,
+.btn-group.open .btn.dropdown-toggle.btn-default + .dropdown-menu > li > a:hover,
+.dropdown.open .btn.dropdown-toggle.btn-default + .dropdown-menu > li > a:hover {
+ background-color: #808793;
+ color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle.btn-primary,
+.dropdown.open .btn.dropdown-toggle.btn-primary {
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+ color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle.btn-primary:hover,
+.dropdown.open .btn.dropdown-toggle.btn-primary:hover {
+ background-color: #3FAE2A;
+ border: 1px solid #3FAE2A;
+ color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle.btn-primary + .dropdown-menu > li > a:hover,
+.dropdown.open .btn.dropdown-toggle.btn-primary + .dropdown-menu > li > a:hover {
+ background-color: #429929;
+ color: #FFF;
+}
+.btn-group.open .dropdown-menu,
+.dropdown.open .dropdown-menu {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ border-radius: 2px;
+ font-size: 14px;
+ min-width: 200px;
+ background: #FFF;
+ color: #666;
+ border: 1px solid #cfd3d7;
+}
+.btn-group.open .dropdown-menu > li,
+.dropdown.open .dropdown-menu > li {
+ margin-bottom: 1px;
+}
+.btn-group.open .dropdown-menu > li > a,
+.dropdown.open .dropdown-menu > li > a {
+ height: 24px;
+}
+.btn-group .btn.dropdown-toggle:first-child,
+.dropdown .btn.dropdown-toggle:first-child {
+ min-width: 80px;
+}
+.btn-group .btn.dropdown-toggle.disabled,
+.dropdown .btn.dropdown-toggle.disabled,
+.btn-group .btn.dropdown-toggle[disabled],
+.dropdown .btn.dropdown-toggle[disabled] {
+ opacity: 0.6;
+}
+input.form-control {
+ font-size: 14px;
+ border-radius: 2px;
+ color: #666;
+ border: 1px solid #CFD3D7;
+ height: 34px;
+ padding: 10px;
+}
+input.form-control:focus {
+ border-color: #1291c1;
+ box-shadow: none;
+}
+.help-block {
+ color: #999999;
+ font-size: 14px;
+}
+.help-block.validation-block {
+ color: #999999;
+ margin-top: 10px;
+}
+.help-block.validation-block::before {
+ position: relative;
+ top: 2px;
+ margin-right: 5px;
+ font-family: 'Glyphicons Halflings';
+}
+.has-success input.form-control {
+ color: #666;
+ border: 1px solid #1EB475;
+}
+.has-success input.form-control:focus {
+ border-color: #1EB475;
+ box-shadow: none;
+}
+.has-success .help-block.validation-block::before {
+ content: '\e084';
+ color: #1EB475;
+}
+.has-error input.form-control {
+ color: #666;
+ border: 1px solid #EF6162;
+}
+.has-error input.form-control:focus {
+ border-color: #EF6162;
+ box-shadow: none;
+}
+.has-error .help-block.validation-block::before {
+ content: '\e083';
+ color: #EF6162;
+}
+.has-warning input.form-control {
+ color: #666;
+ border: 1px solid #E98A40;
+}
+.has-warning input.form-control:focus {
+ border-color: #E98A40;
+ box-shadow: none;
+}
+.has-warning .help-block.validation-block::before {
+ content: '\e101';
+ color: #E98A40;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ color: #999999;
+ border-color: #cccccc;
+ background-color: #dddddd;
+}
+h2.table-title {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ margin-top: 10px;
+ font-size: 20px;
+}
+.table {
+ color: #666;
+ font-size: 13px;
+}
+.table thead,
+.table tfoot {
+ color: #999;
+}
+.table input[type="checkbox"] + label {
+ position: relative;
+ line-height: 1.3em;
+ font-size: initial;
+ top: 4px;
+ margin-bottom: 0;
+}
+.table thead > tr > th {
+ border-bottom-color: #EEE;
+}
+.table tfoot > tr:first-of-type > td {
+ border-top-width: 2px;
+ border-top-color: #EEE;
+}
+.table > tbody > tr > td {
+ border-top-color: #EEE;
+}
+.table > tbody > tr.active {
+ background-color: #EEE;
+}
+.table > tbody > tr.active > td {
+ background-color: #EEE;
+}
+.table.table-hover .action {
+ visibility: hidden;
+ padding: 0;
+ line-height: 1;
+}
+.table.table-hover .action:hover {
+ text-decoration: none;
+}
+.table.table-hover > tbody > tr {
+ border-width: 0 1px 1px;
+ border-style: solid;
+ border-color: #EEE transparent;
+}
+.table.table-hover > tbody > tr > td {
+ border-width: 0;
+}
+.table.table-hover > tbody > tr:hover {
+ border-color: #A7DFF2;
+ background-color: #E7F6FC;
+}
+.table.table-hover > tbody > tr:hover > td {
+ border-top: 1px solid #A7DFF2;
+ background-color: #E7F6FC;
+}
+.table.table-hover > tbody > tr:hover > td .action {
+ visibility: visible;
+}
+.table.table-hover > tbody > tr:first-of-type > td {
+ border-top: 1px solid transparent;
+}
+.table.table-hover > tbody > tr:first-of-type:hover > td {
+ border-color: #A7DFF2;
+}
+.pagination-block .pagination-block-item {
+ float: left;
+ padding: 0 5px;
+}
+.pagination-block .pagination-block-item a,
+.pagination-block .pagination-block-item a:visited,
+.pagination-block .pagination-block-item a:focus {
+ text-decoration: none;
+}
+.pagination-block .pagination-block-item select {
+ border: none;
+ background-color: transparent;
+ color: #1491C1;
+}
+.nav.nav-tabs {
+ border: none;
+ margin-bottom: 20px;
+}
+.nav.nav-tabs li a {
+ border-width: 0;
+ border-radius: 0;
+ border-bottom: 3px solid transparent;
+ color: #6B6C6C;
+ text-transform: uppercase;
+}
+.nav.nav-tabs li a:hover,
+.nav.nav-tabs li a:active,
+.nav.nav-tabs li a:focus {
+ color: #333;
+ border-top-width: 0;
+ border-left-width: 0;
+ border-right-width: 0;
+ background: none;
+}
+.nav.nav-tabs li a .badge.badge-important {
+ display: inline;
+ vertical-align: baseline;
+}
+.nav.nav-tabs li.active a {
+ color: #333;
+ border-bottom: 3px solid #3FAE2A;
+ padding-bottom: 2px;
+}
+.nav-tabs-left li,
+.nav-tabs-right li {
+ float: none;
+ margin-bottom: 3px;
+}
+.nav-tabs-left li a,
+.nav-tabs-right li a {
+ margin-right: 0;
+}
+.nav-tabs-left li {
+ margin-right: -1px;
+}
+.nav-tabs-left li a {
+ border: 3px solid transparent !important;
+}
+.nav-tabs-left li.active a,
+.nav-tabs-left li.active a:hover,
+.nav-tabs-left li.active a:active,
+.nav-tabs-left li.active a:focus {
+ border-right: 3px solid #3FAE2A !important;
+}
+.nav-tabs-right li {
+ margin-left: -1px;
+}
+.nav-tabs-right li a {
+ border: 3px solid transparent !important;
+}
+.nav-tabs-right li.active a,
+.nav-tabs-right li.active a:hover,
+.nav-tabs-right li.active a:active,
+.nav-tabs-right li.active a:focus {
+ border-left: 3px solid #3FAE2A !important;
+}
+.wizard {
+ border: 2px solid #ebecf1;
+}
+.wizard .wizard-header h3 {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ font-size: 20px;
+ color: #333;
+ margin: 15px 20px;
+}
+.wizard .wizard-body {
+ overflow: hidden;
+ margin: 0;
+}
+.wizard .wizard-body .wizard-content {
+ background: #ebecf1;
+ padding-top: 25px;
+ float: left;
+ margin-bottom: -99999px;
+ padding-bottom: 99999px;
+}
+.wizard .wizard-body .wizard-content .step-title {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-weight: bold;
+ font-size: 18px;
+ color: #666;
+}
+.wizard .wizard-body .wizard-content .step-description {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 14px;
+ line-height: 1.4;
+ color: #999;
+}
+.wizard .wizard-body .wizard-content .panel.panel-default {
+ border: none;
+ box-shadow: none;
+ margin-top: 20px;
+}
+.wizard .wizard-body .wizard-content .panel.panel-default .panel-body {
+ padding: 30px 20px;
+}
+.wizard .wizard-body .wizard-nav {
+ min-height: 550px;
+ padding-top: 25px;
+ background-color: #323544;
+ float: left;
+ margin-bottom: -99999px;
+ padding-bottom: 99999px;
+}
+.wizard .wizard-body .wizard-nav .nav li {
+ padding: 0px 15px;
+}
+.wizard .wizard-body .wizard-nav .nav li a {
+ height: 48px;
+ padding: 0px 5px;
+ display: table-cell;
+ vertical-align: middle;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-marker {
+ position: absolute;
+ top: 9px;
+ line-height: 16px;
+ text-align: center;
+ width: 20px;
+ height: 20px;
+ border: 2px solid #1EB475;
+ border-radius: 50%;
+ font-size: 12px;
+ font-style: inherit;
+ color: #1EB475;
+ background-color: #323544;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-name {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 14px;
+ color: #999;
+ margin-left: 30px;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-index {
+ line-height: 18px;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-description {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 12px;
+ color: #999;
+ margin-left: 30px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed .step-marker {
+ background-color: #1EB475;
+ color: white;
+ font-size: 10px;
+ padding-left: 2px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed .step-marker .step-index {
+ display: none;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed .step-marker:after {
+ font-family: "Glyphicons Halflings";
+ content: "\e013";
+ position: relative;
+ top: 1px;
+ left: -1px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed:after {
+ width: 2px;
+ height: 100%;
+ position: absolute;
+ background-color: #1EB475;
+ content: "";
+ top: 25px;
+ left: 29px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed:last-child:after {
+ content: none;
+}
+.wizard .wizard-body .wizard-nav .nav li.active .step-name {
+ font-weight: bold;
+}
+.wizard .wizard-body .wizard-nav .nav li.disabled .step-marker {
+ color: #666;
+ border-color: #666;
+}
+.wizard .wizard-body .wizard-nav .nav li.disabled .step-name,
+.wizard .wizard-body .wizard-nav .nav li.disabled .step-description {
+ color: #666;
+}
+.wizard .wizard-body .wizard-nav .nav li.disabled.completed .step-marker {
+ background-color: #1EB475;
+ border: 2px solid #1EB475;
+ color: white;
+}
+.wizard .wizard-body .wizard-nav .nav-pills > li.active > a,
+.wizard .wizard-body .wizard-nav .nav-pills > li.active > a:focus,
+.wizard .wizard-body .wizard-nav .nav-pills > li.active > a:hover,
+.wizard .wizard-body .wizard-nav .nav > li > a:focus,
+.wizard .wizard-body .wizard-nav .nav > li > a:hover {
+ background-color: inherit;
+}
+.wizard .wizard-body .wizard-footer {
+ background: white;
+ padding: 15px 20px;
+}
+.wizard .wizard-body .wizard-footer button {
+ margin: 0 10px;
+}
+.checkbox-disabled-style {
+ background-color: #b2b8c1;
+ border-color: #b2b8c1;
+}
+input[type="checkbox"]:not(:checked),
+input[type="radio"]:not(:checked),
+input[type="checkbox"]:checked,
+input[type="radio"]:checked {
+ display: none;
+}
+input[type="checkbox"]:not(:checked) + label,
+input[type="radio"]:not(:checked) + label,
+input[type="checkbox"]:checked + label,
+input[type="radio"]:checked + label {
+ position: relative;
+ padding-left: 20px;
+}
+input[type="checkbox"]:not(:checked) + label:hover:before,
+input[type="radio"]:not(:checked) + label:hover:before,
+input[type="checkbox"]:checked + label:hover:before,
+input[type="radio"]:checked + label:hover:before {
+ border-color: #1491C1;
+ background-color: #1491C1;
+}
+input[type="checkbox"]:checked + label:before,
+input[type="radio"]:checked + label:before {
+ background-color: #1491C1;
+ border-color: #1491C1;
+}
+input[type="checkbox"][disabled] + label:before,
+input[type="radio"][disabled] + label:before,
+input[type="checkbox"].disabled + label:before,
+input[type="radio"].disabled + label:before,
+input[type="checkbox"][disabled] + label:hover:before,
+input[type="radio"][disabled] + label:hover:before,
+input[type="checkbox"].disabled + label:hover:before,
+input[type="radio"].disabled + label:hover:before {
+ background-color: #b2b8c1;
+ border-color: #b2b8c1;
+}
+input[type="checkbox"] + label:before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 4px;
+ width: 10px;
+ height: 10px;
+ box-sizing: border-box;
+ border-radius: 2px;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #ddd;
+}
+input[type="checkbox"]:checked + label:after {
+ content: '\2714';
+ color: #FFF;
+ position: absolute;
+ top: 0;
+ left: 2px;
+ font-size: 9px;
+}
+input[type="radio"] + label:before,
+input.radio + label:before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 12px;
+ height: 12px;
+ box-sizing: border-box;
+ border-radius: 12px;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #ddd;
+}
+input[type="radio"]:checked + label:after,
+input.radio:checked + label:after {
+ content: '';
+ background-color: #FFF;
+ position: absolute;
+ top: 3px;
+ left: 3px;
+ width: 6px;
+ height: 6px;
+ border-radius: 6px;
+}
+.navigation-bar-container {
+ height: auto;
+ width: 230px;
+ background-color: #323544;
+ padding: 0;
+ -ms-overflow-style: none;
+ transition: width 0.5s ease-out;
+ -webkit-font-smoothing: antialiased;
+}
+.navigation-bar-container ul.nav.side-nav-header {
+ width: 230px;
+ transition: width 0.5s ease-out;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header {
+ background: #313d54;
+ padding: 15px 5px 15px 25px;
+ height: 55px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header > a.ambari-logo {
+ padding: 0;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header > a.ambari-logo > img {
+ height: 25px;
+ float: left;
+ margin-left: -3px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group {
+ cursor: pointer;
+ margin-top: 3px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group:hover span.ambari-header {
+ color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group span.ambari-header {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 20px;
+ width: 55px;
+ display: inline;
+ color: #b8bec4;
+ padding: 0 8px 0 10px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group span.toggle-icon {
+ margin-bottom: 5px;
+ font-size: 13px;
+ display: inline-block;
+ vertical-align: middle;
+ color: #43AD49;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header ul.dropdown-menu {
+ top: 30px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header ul.dropdown-menu li > a {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 14px;
+ color: #666;
+ line-height: 1.42;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header ul.dropdown-menu li > a:hover {
+ background: #f5f5f5;
+}
+.navigation-bar-container ul.nav.side-nav-menu,
+.navigation-bar-container ul.nav.side-nav-footer {
+ background-color: #323544;
+ width: 230px;
+ transition: width 0.5s ease-out;
+}
+.navigation-bar-container ul.nav.side-nav-menu li,
+.navigation-bar-container ul.nav.side-nav-footer li {
+ padding: 0;
+ margin: 0;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a {
+ display: table-cell;
+ vertical-align: middle;
+ width: 230px;
+ border-radius: 0;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ white-space: nowrap;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a .navigation-menu-item {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 14px;
+ color: #b8bec4;
+ padding-left: 8px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a .navigation-icon {
+ line-height: 18px;
+ font-size: 16px;
+ color: #b8bec4;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a .toggle-icon {
+ line-height: 14px;
+ font-size: 14px;
+ color: #b8bec4;
+ padding: 3px 5px 3px 10px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a {
+ padding: 10px 5px 10px 20px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a {
+ padding: 14px 5px 14px 20px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a {
+ padding: 10px 5px 10px 25px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer {
+ background: #313d54;
+ height: 48px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer a .navigation-icon {
+ color: #3fae2a;
+ font-size: 19px;
+ position: relative;
+ padding: 0 15px;
+ left: calc(30%);
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer a .navigation-icon:hover,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer a .navigation-icon:hover {
+ color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li {
+ background-color: #323544;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li a,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li a {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 14px;
+ color: #999;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li a .submenu-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li a .submenu-icon {
+ line-height: 14px;
+ font-size: 14px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover {
+ background: #404351;
+ cursor: pointer;
+ color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .submenu-item,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .submenu-item {
+ color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu),
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu),
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed {
+ background: #404351;
+ cursor: pointer;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a {
+ color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .toggle-icon {
+ color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a:after,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a:after,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a:after,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a:after {
+ left: 0;
+ top: 50%;
+ border: solid transparent;
+ border-width: 10px 7px;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ border-color: transparent;
+ border-left-color: #3fae2a;
+ margin-top: -12px;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions {
+ display: block;
+ position: absolute;
+ top: 14px;
+ right: 33px;
+ line-height: 25px;
+ width: 20px;
+ text-align: center;
+ font-size: 14px;
+ cursor: pointer;
+ vertical-align: middle;
+ color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a {
+ color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a i,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a i {
+ color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a:hover,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a:hover {
+ background: #f5f5f5;
+}
+.navigation-bar-container ul.nav.side-nav-menu .menu-item-name,
+.navigation-bar-container ul.nav.side-nav-footer .menu-item-name {
+ display: inline-block;
+ vertical-align: bottom;
+ max-width: 100px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ -o-text-overflow: ellipsis;
+ -ms-text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.navigation-bar-container .nav-pills > li.active > a,
+.navigation-bar-container .nav-pills > li.active > a:focus,
+.navigation-bar-container .nav-pills > li.active > a:hover,
+.navigation-bar-container .nav > li > a:focus,
+.navigation-bar-container .nav > li > a:hover {
+ background-color: inherit;
+}
+.navigation-bar-container.collapsed {
+ width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-header {
+ width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header {
+ padding: 15px 0 15px 15px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header span.ambari-header,
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header span.toggle-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header .dropdown-menu {
+ display: none;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer {
+ width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a {
+ padding: 15px 0 15px 15px;
+ width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a .toggle-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a .toggle-icon {
+ display: none;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a .navigation-icon {
+ font-size: 19px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.navigation-footer a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.navigation-footer a .navigation-icon {
+ padding: 0 5px;
+ left: 0;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li ul.sub-menu,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li ul.sub-menu {
+ display: none;
+ width: 230px;
+ position: absolute;
+ z-index: 100;
+ top: 0;
+ left: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.submenu-li > a,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.submenu-li > a {
+ padding: 10px 5px 10px 25px;
+ width: 230px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active {
+ background: #404351;
+ cursor: pointer;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a {
+ color: #fff;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .submenu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .submenu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .toggle-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .toggle-icon {
+ color: #fff;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a:after,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a:after {
+ left: 0;
+ top: 50%;
+ border: solid transparent;
+ border-width: 12px 6px;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ border-color: transparent;
+ border-left-color: #3fae2a;
+ margin-top: -12px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu .more-actions,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer .more-actions {
+ display: none;
+}
+.navigation-bar-fit-height {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 2079;
+}
+.navigation-bar-fit-height .side-nav-header {
+ position: absolute;
+ top: 0;
+}
+.navigation-bar-fit-height .side-nav-menu {
+ position: absolute;
+ top: 55px;
+ bottom: 50px;
+}
+.navigation-bar-fit-height .side-nav-footer {
+ position: absolute;
+ bottom: 0;
+}
+.navigation-bar-fit-height .more-actions .dropdown-menu {
+ position: fixed;
+ top: auto;
+ left: auto;
+}
+.navigation-bar-fit-height .navigation-bar-container {
+ height: 100%;
+}
+.navigation-bar-fit-height .navigation-bar-container .side-nav-menu {
+ overflow-y: auto;
+}
+.notifications-group {
+ position: relative;
+ top: 1px;
+}
+.notifications-dropdown,
+#notifications-dropdown.dropdown-menu {
+ min-width: 400px;
+ max-width: 400px;
+ min-height: 150px;
+ padding: 0px;
+ z-index: 1000;
+ right: -50px;
+ left: auto;
+ top: 260%;
+ border: none;
+ -webkit-box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+ -moz-box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+ box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+}
+.notifications-dropdown .popup-arrow-up,
+#notifications-dropdown.dropdown-menu .popup-arrow-up {
+ position: absolute;
+ right: 37px;
+ top: -40px;
+ width: 40px;
+ height: 40px;
+ overflow: hidden;
+}
+.notifications-dropdown .popup-arrow-up:after,
+#notifications-dropdown.dropdown-menu .popup-arrow-up:after {
+ content: "";
+ position: absolute;
+ width: 20px;
+ height: 20px;
+ background: #fff;
+ transform: rotate(45deg);
+ top: 30px;
+ left: 10px;
+ box-shadow: -1px -1px 10px -2px rgba(0, 0, 0, 0.5);
+}
+.notifications-dropdown .notifications-header,
+#notifications-dropdown.dropdown-menu .notifications-header {
+ border-bottom: 1px solid #eee;
+ padding: 15px 20px;
+}
+.notifications-dropdown .notifications-header .notifications-title,
+#notifications-dropdown.dropdown-menu .notifications-header .notifications-title {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 16px;
+}
+.notifications-dropdown .notifications-body,
+#notifications-dropdown.dropdown-menu .notifications-body {
+ padding: 0px 15px;
+ overflow: auto;
+ max-height: 500px;
+}
+.notifications-dropdown .notifications-body .no-alert-text,
+#notifications-dropdown.dropdown-menu .notifications-body .no-alert-text {
+ padding: 15px 5px;
+}
+.notifications-dropdown .notifications-body .table-controls,
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls {
+ padding: 10px 0px;
+ margin: 0px;
+ border-bottom: 1px solid #eee;
+}
+.notifications-dropdown .notifications-body .table-controls .state-filter,
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls .state-filter {
+ padding: 0px;
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 12px;
+ color: #666;
+ position: relative;
+}
+.notifications-dropdown .notifications-body .table-controls .state-filter .form-control.filter-select,
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls .state-filter .form-control.filter-select {
+ font-size: 12px;
+ color: #666;
+ height: 25px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table {
+ margin-top: 0px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody tr,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr {
+ cursor: pointer;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover {
+ cursor: default;
+ border-color: transparent;
+ border-bottom-color: #eee;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover > td,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover > td {
+ border-color: transparent;
+ background-color: white;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.status,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status {
+ width: 9%;
+ padding: 15px 3px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.status .alert-state-CRITICAL,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status .alert-state-CRITICAL {
+ color: #EF6162;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.status .alert-state-WARNING,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status .alert-state-WARNING {
+ color: #E98A40;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content {
+ width: 90%;
+ padding: 15px 3px 10px 3px;
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ line-height: 1.3;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content .name,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .name {
+ font-weight: bold;
+ font-size: 14px;
+ color: #333;
+ margin-bottom: 5px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content .description,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .description {
+ font-size: 12px;
+ color: #666;
+ margin-bottom: 4px;
+ display: block;
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ max-height: 47px;
+ /* For firefox */
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ /* Break long urls*/
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ -ms-word-break: break-all;
+ word-break: break-all;
+ word-break: break-word;
+ /* Adds a hyphen where the word breaks*/
+ -ms-hyphens: auto;
+ -moz-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content .timestamp,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .timestamp {
+ text-align: right;
+ font-size: 11px;
+ color: #999;
+}
+.notifications-dropdown .notifications-footer,
+#notifications-dropdown.dropdown-menu .notifications-footer {
+ border-top: 1px solid #eee;
+ padding: 15px;
+}
+.modal-backdrop {
+ background-color: #808080;
+}
+.modal .modal-content {
+ border-radius: 2px;
+}
+.modal .modal-content .modal-header,
+.modal .modal-content .modal-body,
+.modal .modal-content .modal-footer {
+ padding-left: 20px;
+ padding-right: 20px;
+}
+.modal .modal-content .modal-header {
+ border-bottom: none;
+ padding-top: 20px;
+ color: #666;
+ font-size: 20px;
+}
+.modal .modal-content .modal-header h4 {
+ margin: 0;
+ color: inherit;
+ font-size: inherit;
+}
+.modal .modal-content .modal-body {
+ color: #666;
+ font-size: 12px;
+}
+.modal .modal-content .modal-footer {
+ border-top: none;
+ padding-bottom: 20px;
+}
+.modal .modal-content .modal-footer .btn ~ .btn {
+ margin-left: 10px;
+}
+.accordion .panel-group,
+.wizard .wizard-body .wizard-content .accordion .panel-group {
+ margin-bottom: 0;
+}
+.accordion .panel-group .panel,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel {
+ border-radius: 0;
+ border: none;
+ margin-top: 0;
+ padding: 0 10px;
+}
+.accordion .panel-group .panel .panel-heading,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading {
+ height: 50px;
+ padding: 15px 10px;
+ border: 1px solid;
+ border-color: #ddd transparent;
+ border-top: none;
+ background: #fff;
+}
+.accordion .panel-group .panel .panel-heading .panel-title,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading .panel-title {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+}
+.accordion .panel-group .panel .panel-heading .panel-title > a,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading .panel-title > a {
+ font-size: 18px;
+ color: #333;
+}
+.accordion .panel-group .panel .panel-heading .panel-title > i,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading .panel-title > i {
+ font-size: 20px;
+ color: #1491c1;
+}
+.accordion .panel-group .panel .panel-heading:hover,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading:hover {
+ background: #f3faff;
+ cursor: pointer;
+}
+.accordion .panel-group .panel .panel-body,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-body {
+ padding: 15px 10px 20px 20px;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: 'Roboto', sans-serif;
+}
+h1,
+.h1 {
+ font-size: 24px;
+}
+h2,
+.h2 {
+ font-size: 18px;
+}
+body,
+.body {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 14px;
+}
+.description {
+ font-family: 'Roboto', sans-serif;
+ font-size: 12px;
+ color: #000;
+}
+a,
+a:visited,
+a:focus {
+ color: #1491C1;
+ text-decoration: none;
+}
+a:hover,
+a:visited:hover,
+a:focus:hover {
+ text-decoration: underline;
+}
+a:active,
+a:visited:active,
+a:focus:active {
+ text-decoration: none;
+}
+a[disabled],
+a:visited[disabled],
+a:focus[disabled],
+a.disabled,
+a:visited.disabled,
+a:focus.disabled {
+ cursor: not-allowed;
+ color: #666;
+ text-decoration: none;
+}
+a[disabled]:hover,
+a:visited[disabled]:hover,
+a:focus[disabled]:hover,
+a.disabled:hover,
+a:visited.disabled:hover,
+a:focus.disabled:hover {
+ text-decoration: none;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css
new file mode 100644
index 0000000..f93b2e6
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css
@@ -0,0 +1,197 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+
+#top-nav .navbar.navbar-static-top {
+ background: #fff;
+ border-top: 1px solid #e3e3e3;
+ border-bottom: 1px solid #e3e3e3;
+ margin-bottom: 10px;
+ min-height: 55px;
+}
+
+#top-nav .breadcrumb li {
+ padding: 15px 0;
+}
+
+#top-nav .navbar-text {
+ padding: 2px 0;
+}
+
+#top-nav .navbar-right {
+ font-size: 16px;
+}
+
+
+/** Override bootstrap styles **/
+@media (min-width: 0) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+ .navbar-nav > li {
+ float: left;
+ }
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+ .navbar-left {
+ float: left !important;
+ }
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto;
+ }
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0;
+ }
+ .navbar {
+ border-radius: 4px;
+ }
+ .navbar-header {
+ float: left;
+ }
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+ .navbar-static-top {
+ border-radius: 0;
+ }
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+ .navbar-toggle {
+ display: none;
+ }
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
+ }
+ .navbar-header {
+ float: left;
+ }
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0;
+ }
+ .navbar {
+ border-radius: 4px;
+ }
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: absolute;
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
index 8457065..5271ceb 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
@@ -21,7 +21,9 @@
<li class="active">{{'common.groups' | translate}}</li>
</ol>
<div class="pull-right top-margin-4">
- <link-to route="groups.create" class="btn btn-primary creategroup-btn"><span class="glyphicon glyphicon-plus"></span> {{'groups.createLocal' | translate}}</link-to>
+ <link-to route="groups.create" class="btn btn-default creategroup-btn">
+ {{'groups.createLocal' | translate}}
+ </link-to>
</div>
</div>
<hr>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
deleted file mode 100644
index a7fc18a..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
+++ /dev/null
@@ -1,126 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you 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.
--->
-<div class="left-navbar" xmlns="http://www.w3.org/1999/html">
- <div class="panel panel-default">
- <div class="panel-heading"><span class="glyphicon glyphicon-cloud"></span> {{'common.clusters' | translate}}</div>
- <div class="panel-body">
- <div class="cluster-section" ng-show="cluster">
- <div id="cluster-name" ng-switch on="editCluster.editingName">
- <h5 ng-switch-when="false"><div title={{cluster.Clusters.cluster_name}} class="clusterDisplayName">{{clusterDisplayName()}}</div>
- <i ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
- ng-click="toggleEditName()"
- class="glyphicon glyphicon-edit pull-right edit-cluster-name renameCluster" tooltip="{{'common.renameCluster' | translate}}">
- </i>
- </h5>
-
- <form ng-keyup="toggleEditName($event)"
- tabindex="1"
- name="editClusterNameForm"
- class="editClusterNameForm"
- ng-switch-when="true"
- ng-submit="editCluster.name !== cluster.Clusters.cluster_name && editClusterNameForm.newClusterName.$valid && confirmClusterNameChange()">
- <div class="form-group"
- ng-class="{'has-error': editClusterNameForm.newClusterName.$invalid && !editClusterNameForm.newClusterName.$pristine }">
- <input
- autofocus
- type="text"
- name="newClusterName"
- ng-required="true"
- ng-pattern="/^\w*$/"
- ng-trim="false"
- ng-model="editCluster.name"
- class="form-control input-sm"
- ng-maxlength="80"
- tooltip="{{'common.renameClusterTip' | translate}}"
- tooltip-trigger="focus">
- <button ng-click="toggleEditName()"
- class="btn btn-xs">
- <i class="glyphicon glyphicon-remove"></i>
- </button>
- <button
- type="submit"
- class="btn btn-primary btn-xs"
- ng-class="{'disabled': editClusterNameForm.newClusterName.$invalid || editCluster.name == cluster.Clusters.cluster_name}">
- <i class="glyphicon glyphicon-ok"></i>
- </button>
- </div>
- </form>
-
- </div>
-
- <ul class="nav nav-pills nav-stacked" ng-show="cluster.Clusters.provisioning_state == 'INSTALLED' ">
- <li ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}">
- <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="permissions">{{'common.roles' | translate}}</a>
- </li>
- <li><a href="{{fromSiteRoot('/#/dashboard')}}" class="gotodashboard">{{'common.goToDashboard' | translate}}</a></li>
- <li ng-class="{active: isActive('clusters.exportBlueprint')}">
- <a href="#/clusters/{{cluster.Clusters.cluster_name}}/exportBlueprint" class="exportblueprint">{{'common.exportBlueprint' | translate}}</a>
- </li>
- </ul>
- <span class="cluster-installation-progress-label" ng-show="cluster.Clusters.provisioning_state == 'INIT'"><a href="{{fromSiteRoot('/#/')}}">{{'common.clusterCreationInProgress' | translate}}</a></span>
- </div>
-
-
- <div ng-hide="cluster">
- <ul class="nav nav-pills nav-stacked">
- <li><p class="noclusters">{{'common.noClusters' | translate}}</p></li>
- </ul>
- </div>
- <ul class="nav nav-pills nav-stacked" >
- <li ng-class="{active: isActive('stackVersions.list')}" ng-show="cluster && totalRepos > 0">
- <a href="#/stackVersions">{{'common.versions' | translate}}</a>
- </li>
- <li ng-class="{active: isActive('remoteClusters.list')}">
- <a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a>
- </li>
- </ul>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading"><span class="glyphicon glyphicon-th"></span> {{'common.views' | translate}}</div>
- <div class="panel-body">
- <ul class="nav nav-pills nav-stacked">
- <li ng-class="{active: isActive('views.list')}"><link-to route="views.list" class="viewslist-link">{{'common.views' | translate}}</link-to></li>
- <li ng-class="{active: isActive('views.listViewUrls') || isActive('views.createViewUrl') || isActive('views.editViewUrl') }"><link-to route="views.listViewUrls" class="viewslistviewurls-link">{{'common.viewUrls' | translate}}</link-to></li>
- </ul>
- </div>
- </div>
-
-
- <div class="panel panel-default">
- <div class="panel-heading"><span class="glyphicon glyphicon-user"></span> {{'common.userGroupManagement' | translate}}</div>
- <div class="panel-body">
- <ul class="nav nav-pills nav-stacked">
- <li ng-class="{active: isActive('users.list')}"><link-to route="users.list" class="userslist-link">{{'common.users' | translate}}</link-to></li>
- <li ng-class="{active: isActive('groups.list')}"><link-to route="groups.list" class="groupslist-link">{{'common.groups' | translate}}</link-to></li>
- </ul>
- </div>
- </div>
-
- <div class="panel panel-default" ng-show="settings.isLoginActivitiesSupported || settings.isLDAPConfigurationSupported">
- <div class="panel-heading"><span class="glyphicon glyphicon-cog"></span> {{'common.settings' | translate}}</div>
- <div class="panel-body">
- <ul class="nav nav-pills nav-stacked">
- <li ng-class="{active: isActive('authentication.main')}" ng-show="settings.isLDAPConfigurationSupported"><link-to route="authentication.main">{{'common.authentication' | translate}}</link-to></li>
- <li ng-class="{active: isActive('loginActivities.loginMessage')}" ng-show="settings.isLoginActivitiesSupported"><link-to route="loginActivities.loginMessage">{{'common.loginActivities.loginActivities' | translate}}</link-to></li>
- </ul>
- </div>
- </div>
-</div>
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
index 3bdb80e..3c382af 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
@@ -19,7 +19,7 @@
<div class="panel-body">
<h1>{{'main.title' | translate}}</h1>
- <div ng-if="isLoaded" id="main-operations-boxes" class="row thumbnails">
+ <div id="main-operations-boxes" class="row thumbnails">
<p ng-hide="cluster">{{'main.noClusterDescription' | translate}}</p>
<p ng-show="cluster">{{'main.hasClusterDescription' | translate}}</p>
@@ -32,24 +32,29 @@
<div class="glyphicon glyphicon-cloud"></div>
<div class="buttons">
<span ng-class="{active: isActive('clusters.manageAccess')}">
- <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href class="btn btn-primary permission-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'main.operateCluster.manageRoles' |
- translate}}</a>
+ <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
+ class="btn btn-primary permission-button"
+ ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+ {{'main.operateCluster.manageRoles' | translate}}
+ </a>
<a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
- href="#/clusters/{{cluster.Clusters.cluster_name}}/userAccessList"
- class="btn btn-primary permission-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'main.operateCluster.manageRoles' |
- translate}}</a>
+ href="#/clusters/{{cluster.Clusters.cluster_name}}/userAccessList"
+ class="btn btn-primary permission-button"
+ ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+ {{'main.operateCluster.manageRoles' | translate}}
+ </a>
</span>
<span>
<a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
- class="btn btn-primary go-dashboard-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'common.goToDashboard' |
- translate}}</a>
+ class="btn btn-primary go-dashboard-button"
+ ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+ {{'common.goToDashboard' | translate}}
+ </a>
<a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
- href="{{fromSiteRoot('/#/main/dashboard/metrics')}}" class="btn btn-primary go-dashboard-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'common.goToDashboard' |
- translate}}</a>
+ href="{{fromSiteRoot('/#/main/dashboard/metrics')}}" class="btn btn-primary go-dashboard-button"
+ ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+ {{'common.goToDashboard' | translate}}
+ </a>
</span>
</div>
</div>
@@ -58,9 +63,11 @@
<div class="description">{{'main.createCluster.description' | translate}}</div>
<div class="glyphicon glyphicon-cloud"></div>
- <div class="buttons"><a href="{{fromSiteRoot('/#/installer/step0')}}"
- class="btn btn-primary create-cluster-button">{{'main.createCluster.launchInstallWizard'
- | translate}}</a></div>
+ <div class="buttons">
+ <a href="{{fromSiteRoot('/#/installer/step0')}}" class="btn btn-primary create-cluster-button">
+ {{'main.createCluster.launchInstallWizard' | translate}}
+ </a>
+ </div>
</div>
<!--Manage Users and groups-->
@@ -70,14 +77,16 @@
<div class="description">{{'main.manageUsersAndGroups.description' | translate}}</div>
<div class="glyphicon glyphicon-user"></div>
<div class="buttons">
- <span ng-class="{active: isActive('users.list')}"><link-to route="users.list"
- class="btn btn-primary userslist-button">
+ <span ng-class="{active: isActive('users.list')}">
+ <link-to route="users.list" class="btn btn-primary userslist-button">
{{'common.users' | translate}}
- </link-to></span>
- <span ng-class="{active: isActive('groups.list')}"><link-to route="groups.list"
- class="btn btn-primary groupslist-button">
+ </link-to>
+ </span>
+ <span ng-class="{active: isActive('groups.list')}">
+ <link-to route="groups.list" class="btn btn-primary groupslist-button">
{{'common.groups' | translate}}
- </link-to></span>
+ </link-to>
+ </span>
</div>
</div>
@@ -88,7 +97,9 @@
<div class="description">{{'main.deployViews.description' | translate}}</div>
<div class="glyphicon glyphicon-th"></div>
<div ng-class="{active: isActive('views.list')}" class="buttons">
- <link-to route="views.list" class="btn btn-primary viewslist-button">{{'common.views' | translate}}</link-to>
+ <link-to route="views.list" class="btn btn-primary viewslist-button">
+ {{'common.views' | translate}}
+ </link-to>
</div>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
index 3bbf09d..e3e11d5 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
@@ -22,8 +22,7 @@
<li class="active">{{'common.remoteClusters' | translate}}</li>
</ol>
<div class="pull-right top-margin-4">
- <a href="#/remoteClusters/create" class="btn btn-primary">
- <span class="glyphicon glyphicon-plus"></span>
+ <a href="#/remoteClusters/create" class="btn btn-default">
{{'views.registerRemoteCluster' | translate}}
</a>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
new file mode 100644
index 0000000..09b4cd9
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
@@ -0,0 +1,106 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.
+-->
+
+<div id="side-nav" class="navigation-bar navigation-bar-fit-height">
+ <div class="navigation-bar-container">
+ <ul class="side-nav-header nav nav-pills nav-stacked">
+ <li class="navigation-header active">
+ <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="ambari-logo">
+ <img src="/img/ambari-logo.png" alt="{{'common.apacheAmbari' | translate}}" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-logo">
+ </a>
+ <div class="btn-group">
+ <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="ambari-header-link" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-title">
+ <span class="ambari-header">
+ {{'common.ambari' | translate}}
+ </span>
+ </a>
+ </div>
+ </li>
+ </ul>
+ <ul class="nav side-nav-menu nav-pills nav-stacked">
+ <li class="mainmenu-li active">
+ <a title="{{'common.dashboard' | translate}}" rel="tooltip" data-placement="right" href="{{fromSiteRoot('/#/dashboard')}}" class="gotodashboard">
+ <i class="navigation-icon fa fa-tachometer" aria-hidden="true"></i>
+ <span class="navigation-menu-item">{{'common.dashboard' | translate}}</span>
+ </a>
+ </li>
+ <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+ <a title="{{'common.clusterManagement' | translate}}" data-toggle="collapse-sub-menu" rel="tooltip" data-placement="right">
+ <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
+ <i class="navigation-icon fa fa-cloud" aria-hidden="true"></i>
+ <span class="navigation-menu-item">{{'common.clusterManagement' | translate}}</span>
+ </a>
+ <ul class="sub-menu nav nav-pills nav-stacked">
+ <li class="submenu-li" ng-class="{active: isActive('stackVersions.list')}" ng-show="cluster && totalRepos > 0">
+ <a href="#/stackVersions">{{'common.clusterInformation' | translate}}</a>
+ </li>
+ <li class="submenu-li" ng-class="{active: isActive('remoteClusters.list')}">
+ <a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a>
+ </li>
+ </ul>
+ </li>
+ <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+ <a title="{{'common.userManagement' | translate}}" rel="tooltip" data-placement="right" data-toggle="collapse-sub-menu">
+ <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
+ <i class="navigation-icon fa fa-users" aria-hidden="true"></i>
+ <span class="navigation-menu-item">{{'common.userManagement' | translate}}</span>
+ </a>
+ <ul class="sub-menu nav nav-pills nav-stacked">
+ <li class="submenu-li" ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}">
+ <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="roles">Roles</a>
+ </li>
+ <li class="submenu-li" ng-class="{active: isActive('users.list')}">
+ <link-to route="users.list" class="userslist-link">{{'common.users' | translate}}</link-to>
+ </li>
+ <li class="submenu-li" ng-class="{active: isActive('groups.list')}">
+ <link-to route="groups.list" class="groupslist-link">{{'common.groups' | translate}}</link-to>
+ </li>
+ </ul>
+ </li>
+ <li class="mainmenu-li" ng-class="{active: isActive('views.list')}">
+ <link-to route="views.list" class="viewslist-link" title="{{'common.views' | translate}}" rel="tooltip" data-placement="right">
+ <i class="navigation-icon fa fa-th" aria-hidden="true"></i>
+ <span class="navigation-menu-item">{{'common.views' | translate}}</span>
+ </link-to>
+ </li>
+ <li class="mainmenu-li dropdown has-sub-menu" ng-show="settings.isLoginActivitiesSupported || settings.isLDAPConfigurationSupported">
+ <a title="{{'common.settings' | translate}}" data-toggle="collapse-sub-menu" rel="tooltip" data-placement="right">
+ <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
+ <i class="navigation-icon glyphicon glyphicon-cog" aria-hidden="true"></i>
+ <span class="navigation-menu-item">{{'common.settings' | translate}}</span>
+ </a>
+ <ul class="sub-menu nav nav-pills nav-stacked">
+ <li class="submenu-li" ng-class="{active: isActive('authentication.main')}" ng-show="settings.isLDAPConfigurationSupported">
+ <link-to route="authentication.main">{{'common.authentication' | translate}}</link-to>
+ </li>
+ <li class="submenu-li" ng-class="{active: isActive('loginActivities.loginMessage')}" ng-show="settings.isLoginActivitiesSupported">
+ <link-to route="loginActivities.loginMessage">{{'common.loginActivities.loginActivities' | translate}}</link-to>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ <ul class="side-nav-footer nav nav-pills nav-stacked">
+ <li class="navigation-footer">
+ <a href="#" data-toggle="collapse-side-nav">
+ <span class="navigation-icon fa fa-angle-double-left" aria-hidden="true"></span>
+ </a>
+ </li>
+ </ul>
+ </div>
+</div>
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
index 3e788f8..f6b6ee9 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
@@ -22,9 +22,8 @@
<li class="active">{{'common.versions' | translate}}</li>
</ol>
<div class="pull-right top-margin-4">
- <a href="#/stackVersions/create" class="btn btn-primary">
- <span class="glyphicon glyphicon-plus"></span>
- {{'versions.register.title' | translate}}
+ <a href="#/stackVersions/create" class="btn btn-default">
+ {{'versions.add.title' | translate}}
</a>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
index 09024a5..7b8e12a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
@@ -22,7 +22,9 @@
<li class="active">{{'common.users' | translate}}</li>
</ol>
<div class="pull-right top-margin-4">
- <link-to route="users.create" class="btn btn-primary createuser-btn"><span class="glyphicon glyphicon-plus"></span> {{'users.create' | translate}}</link-to>
+ <link-to route="users.create" class="btn btn-default createuser-btn">
+ </span> {{'users.create' | translate}}
+ </link-to>
</div>
</div>
<hr>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/bower.json
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/bower.json b/ambari-admin/src/main/resources/ui/admin-web/bower.json
index dbdf005..c38f464 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/bower.json
+++ b/ambari-admin/src/main/resources/ui/admin-web/bower.json
@@ -2,7 +2,7 @@
"name": "adminconsole",
"private": true,
"dependencies": {
- "bootstrap": "3.1.1",
+ "bootstrap": "3.3.7",
"angular": "1.2.26",
"angular-route": "1.2.26",
"angular-bootstrap": "0.11.0",
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
index 2f47b85..9b377d1 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
@@ -24,10 +24,10 @@ var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
gulp.task('styles', function () {
- return gulp.src('app/styles/*.css')
+ return gulp.src('app/styles/**/*.css')
.pipe($.order([
- 'app/styles/main.css',
- 'app/styles/custom-admin-ui.css' // This should always be the last stylesheet. So it can be dropped and be effective on build time
+ 'app/styles/theme/bootstrap-ambari.css',
+ 'app/styles/main.css'
], { base: './' }))
.pipe($.concat('main.css'))
.pipe($.autoprefixer('last 1 version'))
@@ -64,8 +64,8 @@ gulp.task('images', function () {
});
gulp.task('fonts', function () {
- return $.bowerFiles()
- .pipe($.filter('**/*.{eot,svg,ttf,woff}'))
+ return gulp.src('app/bower_components/**/fonts/*.{eot,svg,ttf,woff}')
+ .pipe($.addSrc('app/assets/fonts/*'))
.pipe($.flatten())
.pipe(gulp.dest('dist/fonts'))
.pipe($.size());
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/package.json
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/package.json b/ambari-admin/src/main/resources/ui/admin-web/package.json
index efcd9d4..b7c514c 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/package.json
+++ b/ambari-admin/src/main/resources/ui/admin-web/package.json
@@ -5,19 +5,19 @@
"devDependencies": {
"bower": "1.3.8",
"gulp": "^3.8.8",
+ "gulp-add-src": "^0.2.0",
"gulp-autoprefixer": "0.0.7",
- "gulp-bower-files": "0.2.1",
"gulp-cache": "0.1.1",
"gulp-clean": "0.2.4",
+ "gulp-concat": "2.6.0",
"gulp-filter": "0.4.1",
"gulp-flatten": "0.0.2",
"gulp-load-plugins": "0.5.0",
+ "gulp-order": "1.1.1",
"gulp-plumber": "0.6.6",
"gulp-size": "0.3.0",
"gulp-uglify": "0.2.1",
"gulp-useref": "0.4.2",
- "gulp-concat": "2.6.0",
- "gulp-order": "1.1.1",
"http-server": "0.6.1",
"karma": "0.12.16",
"karma-chrome-launcher": "0.1.4",
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
new file mode 100644
index 0000000..1bbe47a
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
@@ -0,0 +1,211 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+describe('#AppCtrl', function () {
+
+ var scope, ctrl, $httpBackend, $window, clusterService, deferred;
+
+ beforeEach(function () {
+ module('ambariAdminConsole', function ($provide) {
+ $provide.value('$route', {
+ current: null
+ });
+ $provide.value('$window', {
+ location: {
+ pathname: 'http://c6401.ambari.apache.org:8080/views/ADMIN_VIEW/2.0.0/INSTANCE/#/'
+ },
+ localStorage: {
+ getItem: function () {
+ return null;
+ },
+ setItem: angular.noop
+ }
+ });
+ localStorage.ambari = JSON.stringify({
+ app: {
+ authenticated: true,
+ loginName: 'admin',
+ user: 'user'
+ }
+ });
+ });
+ inject(function (_$httpBackend_, $rootScope, $controller, _$window_, _Cluster_, _$q_) {
+ clusterService = _Cluster_;
+ deferred = _$q_.defer();
+ spyOn(clusterService, 'getStatus').andReturn(deferred.promise);
+ deferred.resolve({
+ Clusters: {
+ provisioning_state: 'INIT'
+ }
+ });
+ $window = _$window_;
+ $httpBackend = _$httpBackend_;
+ $httpBackend.whenGET(/api\/v1\/services\/AMBARI\/components\/AMBARI_SERVER.+/).respond(200, {
+ RootServiceComponents: {
+ component_version: 2.2,
+ properties: {
+ 'user.inactivity.timeout.default': 20
+ }
+ }
+ });
+ $httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
+ "href": "http://c6401.ambari.apache.org:8080/api/v1/views?fields=versions/instances/ViewInstanceInfo&versions/ViewVersionInfo/system=false&versions/instances/ViewInstanceInfo/visible=true",
+ "items": [
+ {
+ "ViewInfo": {
+ "view_name": "SLIDER"
+ },
+ "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER",
+ "versions": [
+ {
+ "ViewVersionInfo": {
+ "system": false,
+ "version": "1.0.0",
+ "view_name": "SLIDER"
+ },
+ "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0",
+ "instances": [
+ {
+ "ViewInstanceInfo": {
+ "context_path": "/views/SLIDER/1.0.0/VisibleInstance",
+ "description": "VisibleInstance",
+ "icon64_path": null,
+ "icon_path": null,
+ "instance_data": {},
+ "instance_name": "VisibleInstance",
+ "label": "VisibleInstance",
+ "properties": {
+ "ambari.server.password": "123",
+ "ambari.server.url": "123",
+ "ambari.server.username": "123",
+ "slider.user": null,
+ "view.kerberos.principal": null,
+ "view.kerberos.principal.keytab": null
+ },
+ "static": false,
+ "version": "1.0.0",
+ "view_name": "SLIDER",
+ "visible": true
+ },
+ "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0/instances/VisibleInstance"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ });
+ $httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, {
+ data: {
+ data: {
+ addingNewRepository: true
+ }
+ }
+ });
+ scope = $rootScope.$new();
+ scope.$apply();
+ ctrl = $controller('AppCtrl', {
+ $scope: scope
+ });
+ });
+ });
+
+ afterEach(function() {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+ describe('signout', function () {
+
+ beforeEach(function () {
+ $httpBackend.whenGET(/\/api\/v1\/logout\?_=\d+/).respond(200,{
+ message: "successfully logged out"
+ });
+ $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
+ items: [
+ {
+ AuthorizationInfo: {
+ authorization_id: "AMBARI.RENAME_CLUSTER"
+ }
+ }
+ ]
+ });
+ });
+
+ it('should reset window.location and ambari localstorage', function () {
+ scope.signOut();
+
+ runs(function() {
+ chai.expect($window.location.pathname).to.equal('/');
+ });
+
+ var data = JSON.parse(localStorage.ambari);
+ chai.expect(data.app.authenticated).to.equal(undefined);
+ chai.expect(data.app.loginName).to.equal(undefined);
+ chai.expect(data.app.user).to.equal(undefined);
+ $httpBackend.flush();
+ });
+ });
+
+ describe('roles loading', function () {
+
+ var mock = {
+ callback: angular.noop
+ },
+ cases = [
+ {
+ canPersistData: true,
+ items: [
+ {
+ AuthorizationInfo: {
+ authorization_id: 'CLUSTER.MANAGE_USER_PERSISTED_DATA'
+ }
+ }
+ ],
+ title: 'user can persist data'
+ },
+ {
+ canPersistData: false,
+ items: [],
+ title: 'user can\'t persist data'
+ }
+ ];
+
+ angular.forEach(cases, function (item) {
+
+ describe(item.title, function () {
+
+ beforeEach(function () {
+ $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
+ items: item.items
+ });
+ spyOn(mock, 'callback');
+ scope.authDataLoad.promise.then(mock.callback);
+ $httpBackend.flush();
+ });
+
+ it('authDataLoad should be resolved with the correct argument', function () {
+ expect(mock.callback).toHaveBeenCalledWith(item.canPersistData);
+ });
+
+ });
+
+ });
+
+ });
+});
[16/51] [abbrv] ambari git commit: AMBARI-22360. Send
ClusterVersionSummary to install_packages and conf-select exclusion (ncole)
Posted by nc...@apache.org.
AMBARI-22360. Send ClusterVersionSummary to install_packages and conf-select exclusion (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1afee609
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1afee609
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1afee609
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 1afee6096639b26ed74178bcdd2b6984fda42b32
Parents: 1fefbba
Author: Nate Cole <nc...@hortonworks.com>
Authored: Mon Nov 6 10:11:21 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Nov 6 12:16:26 2017 -0500
----------------------------------------------------------------------
.../libraries/functions/conf_select.py | 58 +++++
.../ambari/server/agent/ExecutionCommand.java | 34 ++-
.../ClusterStackVersionResourceProvider.java | 3 +-
.../HostStackVersionResourceProvider.java | 2 +-
.../state/repository/ClusterVersionSummary.java | 3 +
.../state/repository/ServiceVersionSummary.java | 11 +-
.../state/repository/VersionDefinitionXml.java | 2 +-
.../stack/upgrade/RepositoryVersionHelper.java | 28 ++-
.../custom_actions/scripts/install_packages.py | 12 +-
.../HDP/2.0.6/properties/stack_packages.json | 101 ++++++++
.../HDP/3.0/properties/stack_packages.json | 108 ++++++++-
...ClusterStackVersionResourceProviderTest.java | 239 +++++++++++++++++++
.../stacks/2.2/common/test_conf_select.py | 14 +-
13 files changed, 600 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py b/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
index c89e767..d38e273 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
@@ -294,6 +294,64 @@ def convert_conf_directories_to_symlinks(package, version, dirs):
Logger.warning("Could not change symlink for package {0} to point to current directory. Error: {1}".format(package, e))
+def get_restricted_packages():
+ """
+ Gets the list of conf-select 'package' names that need to be invoked on the command.
+ When the server passes down the list of packages to install, check the service names
+ and use the information in stack_packages json to determine the list of packages that should
+ be executed. That is valid only for PATCH or MAINT upgrades. STANDARD upgrades should be
+ conf-select'ing everything it can find.
+ """
+ package_names = []
+
+ # shortcut the common case if we are not patching
+ cluster_version_summary = default("/roleParameters/cluster_version_summary/services", None)
+
+ if cluster_version_summary is None:
+ Logger.info("Cluster Summary is not available, there are no restrictions for conf-select")
+ return package_names
+
+ service_names = []
+
+ # pick out the services that are targeted
+ for servicename, servicedetail in cluster_version_summary.iteritems():
+ if servicedetail['upgrade']:
+ service_names.append(servicename)
+
+ if 0 == len(service_names):
+ Logger.info("No services found, there are no restrictions for conf-select")
+ return package_names
+
+ stack_name = default("/hostLevelParams/stack_name", None)
+ if stack_name is None:
+ Logger.info("The stack name is not present in the command. Restricted names skipped.")
+ return package_names
+
+ stack_packages_config = default("/configurations/cluster-env/stack_packages", None)
+ if stack_packages_config is None:
+ Logger.info("The stack packages are not defined on the command. Restricted names skipped.")
+ return package_names
+
+ data = json.loads(stack_packages_config)
+
+ if stack_name not in data:
+ Logger.info("Cannot find conf-select packages for the {0} stack".format(stack_name))
+ return package_names
+
+ conf_select_key = "conf-select-patching"
+ if conf_select_key not in data[stack_name]:
+ Logger.info("There are no conf-select-patching elements defined for this command for the {0} stack".format(stack_name))
+ return package_names
+
+ service_dict = data[stack_name][conf_select_key]
+
+ for servicename in service_names:
+ if servicename in service_dict and 'packages' in service_dict[servicename]:
+ package_names.extend(service_dict[servicename]['packages'])
+
+ return package_names
+
+
def _seed_new_configuration_directories(package, created_directories):
"""
Copies any files from the "current" configuration directory to the directories which were
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 9198164..e475c05 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -160,6 +160,9 @@ public class ExecutionCommand extends AgentCommand {
@SerializedName("upgradeSummary")
private UpgradeSummary upgradeSummary;
+ @SerializedName("roleParameters")
+ private Map<String, Object> roleParameters;
+
public void setConfigurationCredentials(Map<String, Map<String, String>> configurationCredentials) {
this.configurationCredentials = configurationCredentials;
}
@@ -235,6 +238,10 @@ public class ExecutionCommand extends AgentCommand {
return roleParams;
}
+ /**
+ * Sets the roleParams for the command. Consider instead using {@link #setRoleParameters}
+ * @param roleParams
+ */
public void setRoleParams(Map<String, String> roleParams) {
this.roleParams = roleParams;
}
@@ -332,11 +339,11 @@ public class ExecutionCommand extends AgentCommand {
}
public String getServiceType() {
- return serviceType;
+ return serviceType;
}
public void setServiceType(String serviceType) {
- this.serviceType = serviceType;
+ this.serviceType = serviceType;
}
/**
@@ -413,6 +420,23 @@ public class ExecutionCommand extends AgentCommand {
}
/**
+ * Gets the object-based role parameters for the command.
+ */
+ public Map<String, Object> getRoleParameters() {
+ return roleParameters;
+ }
+
+ /**
+ * Sets the role parameters for the command. This is preferred over {@link #setRoleParams(Map)},
+ * as this form will pass values as structured data, as opposed to unstructured, escaped json.
+ *
+ * @param params
+ */
+ public void setRoleParameters(Map<String, Object> params) {
+ roleParameters = params;
+ }
+
+ /**
* Contains key name strings. These strings are used inside maps
* incapsulated inside command.
*/
@@ -512,6 +536,12 @@ public class ExecutionCommand extends AgentCommand {
feature = ExperimentalFeature.PATCH_UPGRADES,
comment = "Change this to reflect the component version")
String VERSION = "version";
+
+
+ /**
+ * When installing packages, includes what services will be included in the upgrade
+ */
+ String CLUSTER_VERSION_SUMMARY = "cluster_version_summary";
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 969fca1..98adcd1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -730,7 +730,6 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
return null;
}
-
Map<String, String> roleParams = repoVersionHelper.buildRoleParams(managementController, repoVersion,
osFamily, servicesOnHost);
@@ -744,7 +743,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
actionContext.setRepositoryVersion(repoVersion);
actionContext.setTimeout(Short.valueOf(configuration.getDefaultAgentTaskTimeout(true)));
- repoVersionHelper.addCommandRepository(actionContext, repoVersion, osEntity);
+ repoVersionHelper.addCommandRepository(actionContext, cluster, repoVersion, osEntity);
return actionContext;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
index ba5fccc..b106209 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
@@ -443,7 +443,7 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
roleParams);
actionContext.setTimeout(Short.valueOf(configuration.getDefaultAgentTaskTimeout(true)));
- repoVersionHelper.addCommandRepository(actionContext, repoVersionEnt, osEntity);
+ repoVersionHelper.addCommandRepository(actionContext, cluster, repoVersionEnt, osEntity);
String caption = String.format(INSTALL_PACKAGES_FULL_NAME + " on host %s", hostName);
RequestStageContainer req = createRequest(caption);
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
index e9d9920..5486ecd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
@@ -24,11 +24,14 @@ import java.util.Set;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
+import com.google.gson.annotations.SerializedName;
+
/**
* For a version, collects summary information for a cluster.
*/
public class ClusterVersionSummary {
+ @SerializedName("services")
@JsonProperty("services")
private Map<String, ServiceVersionSummary> m_services;
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
index 29505c8..d87caef 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
@@ -20,25 +20,26 @@ package org.apache.ambari.server.state.repository;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
+import com.google.gson.annotations.SerializedName;
+
/**
* Used to hold information about Service's ability to upgrade for a repository version.
*/
public class ServiceVersionSummary {
- @JsonProperty("display_name")
- private String m_displayName;
-
+ @SerializedName("version")
@JsonProperty("version")
private String m_version;
+ @SerializedName("release_version")
@JsonProperty("release_version")
private String m_releaseVersion;
+ @SerializedName("upgrade")
@JsonProperty("upgrade")
private boolean m_upgrade = false;
- ServiceVersionSummary(String displayName) {
- m_displayName = displayName;
+ ServiceVersionSummary() {
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
index 62f78de..a519d00 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
@@ -300,7 +300,7 @@ public class VersionDefinitionXml {
continue;
}
- ServiceVersionSummary summary = new ServiceVersionSummary(service.getDisplayName());
+ ServiceVersionSummary summary = new ServiceVersionSummary();
summaries.put(service.getName(), summary);
String serviceVersion = service.getDesiredRepositoryVersion().getVersion();
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
index 8f34613..87943d1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
@@ -41,10 +41,14 @@ import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
import org.apache.ambari.server.orm.entities.RepositoryEntity;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.ambari.server.state.RepositoryType;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.ServiceOsSpecific;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.repository.ClusterVersionSummary;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.server.state.stack.UpgradePack;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
@@ -312,7 +316,7 @@ public class RepositoryVersionHelper {
* @param osEntity the OS family
* @param repoVersion the repository version entity
*/
- public void addCommandRepository(ActionExecutionContext context,
+ public void addCommandRepository(ActionExecutionContext context, Cluster cluster,
RepositoryVersionEntity repoVersion, OperatingSystemEntity osEntity) {
final CommandRepository commandRepo = new CommandRepository();
@@ -344,12 +348,34 @@ public class RepositoryVersionHelper {
commandRepo.getFeature().setIsScoped(false);
}
+ ClusterVersionSummary summary = null;
+ if (RepositoryType.STANDARD != repoVersion.getType()) {
+ try {
+ VersionDefinitionXml xml = repoVersion.getRepositoryXml();
+ summary = xml.getClusterSummary(cluster);
+ } catch (Exception e) {
+ LOG.warn("Could not determine repository from %s/%s. Will not pass cluster version.");
+ }
+ }
+
+ final ClusterVersionSummary clusterSummary = summary;
+
context.addVisitor(new ExecutionCommandVisitor() {
@Override
public void visit(ExecutionCommand command) {
if (null == command.getRepositoryFile()) {
command.setRepositoryFile(commandRepo);
}
+
+ if (null != clusterSummary) {
+ Map<String, Object> params = command.getRoleParameters();
+ if (null == params) {
+ params = new HashMap<>();
+ command.setRoleParameters(params);
+ }
+ params.put(KeyNames.CLUSTER_VERSION_SUMMARY, clusterSummary);
+ }
+
}
});
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
index 47f9a74..fff18bb 100644
--- a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
+++ b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
@@ -179,8 +179,18 @@ class InstallPackages(Script):
and not sudo.path_exists("/usr/bin/conf-select") and sudo.path_exists("/usr/bin/hdfconf-select"):
Link("/usr/bin/conf-select", to="/usr/bin/hdfconf-select")
+
+ restricted_packages = conf_select.get_restricted_packages()
+
+ if 0 == len(restricted_packages):
+ Logger.info("There are no restricted conf-select packages for this installation")
+ else:
+ Logger.info("Restricting conf-select packages to {0}".format(restricted_packages))
+
for package_name, directories in conf_select.get_package_dirs().iteritems():
- conf_select.convert_conf_directories_to_symlinks(package_name, stack_version, directories)
+ if 0 == len(restricted_packages) or package_name in restricted_packages:
+ conf_select.convert_conf_directories_to_symlinks(package_name, stack_version, directories)
+
def compute_actual_version(self):
"""
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
index 20b12a9..23c6d32 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
@@ -994,6 +994,12 @@
"current_dir": "{0}/current/atlas-client/conf"
}
],
+ "beacon": [
+ {
+ "conf_dir": "/etc/beacon/conf",
+ "current_dir": "{0}/current/beacon-client/conf"
+ }
+ ],
"druid": [
{
"conf_dir": "/etc/druid/conf",
@@ -1060,6 +1066,12 @@
"current_dir": "{0}/current/knox-server/conf"
}
],
+ "livy": [
+ {
+ "conf_dir": "/etc/livy/conf",
+ "current_dir": "{0}/current/livy"
+ }
+ ],
"mahout": [
{
"conf_dir": "/etc/mahout/conf",
@@ -1175,6 +1187,95 @@
}
]
},
+ "conf-select-patching": {
+ "ACCUMULO": {
+ "packages": ["accumulo"]
+ },
+ "ATLAS": {
+ "packages": ["atlas"]
+ },
+ "BEACON": {
+ "packages": ["beacon"]
+ },
+ "DRUID": {
+ "packages": ["druid", "superset"]
+ },
+ "FALCON": {
+ "packages": ["falcon"]
+ },
+ "FLUME": {
+ "packages": ["flume"]
+ },
+ "HBASE": {
+ "packages": ["hbase"]
+ },
+ "HDFS": {
+ "packages": []
+ },
+ "HIVE": {
+ "packages": ["hive", "hive-hcatalog", "hive2", "tez_hive2"]
+ },
+ "KAFKA": {
+ "packages": ["kafka"]
+ },
+ "KNOX": {
+ "packages": ["knox"]
+ },
+ "MAHOUT": {
+ "packages": ["mahout"]
+ },
+ "MAPREDUCE2": {
+ "packages": []
+ },
+ "OOZIE": {
+ "packages": ["oozie"]
+ },
+ "PIG": {
+ "packages": ["pig"]
+ },
+ "R4ML": {
+ "packages": []
+ },
+ "RANGER": {
+ "packages": ["ranger-admin", "ranger-usersync", "ranger-tagsync"]
+ },
+ "RANGER_KMS": {
+ "packages": ["ranger-kms"]
+ },
+ "SLIDER": {
+ "packages": ["slider"]
+ },
+ "SPARK": {
+ "packages": ["spark", "livy"]
+ },
+ "SPARK2": {
+ "packages": ["spark2", "livy"]
+ },
+ "SQOOP": {
+ "packages": ["sqoop"]
+ },
+ "STORM": {
+ "packages": ["storm", "storm-slider-client"]
+ },
+ "SYSTEMML": {
+ "packages": []
+ },
+ "TEZ": {
+ "packages": ["tez"]
+ },
+ "TITAN": {
+ "packages": []
+ },
+ "YARN": {
+ "packages": []
+ },
+ "ZEPPELIN": {
+ "packages": ["zeppelin"]
+ },
+ "ZOOKEEPER": {
+ "packages": ["zookeeper"]
+ }
+ },
"upgrade-dependencies" : {
"YARN": ["TEZ"],
"TEZ": ["YARN"],
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
index be4c718..d8cd015 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
@@ -871,6 +871,12 @@
"current_dir": "{0}/current/atlas-client/conf"
}
],
+ "beacon": [
+ {
+ "conf_dir": "/etc/beacon/conf",
+ "current_dir": "{0}/current/beacon-client/conf"
+ }
+ ],
"druid": [
{
"conf_dir": "/etc/druid/conf",
@@ -937,6 +943,12 @@
"current_dir": "{0}/current/knox-server/conf"
}
],
+ "livy": [
+ {
+ "conf_dir": "/etc/livy/conf",
+ "current_dir": "{0}/current/livy"
+ }
+ ],
"mahout": [
{
"conf_dir": "/etc/mahout/conf",
@@ -1051,6 +1063,100 @@
"current_dir": "{0}/current/zookeeper-client/conf"
}
]
- }
+ },
+ "conf-select-patching": {
+ "ACCUMULO": {
+ "packages": ["accumulo"]
+ },
+ "ATLAS": {
+ "packages": ["atlas"]
+ },
+ "BEACON": {
+ "packages": ["beacon"]
+ },
+ "DRUID": {
+ "packages": ["druid", "superset"]
+ },
+ "FALCON": {
+ "packages": ["falcon"]
+ },
+ "FLUME": {
+ "packages": ["flume"]
+ },
+ "HBASE": {
+ "packages": ["hbase"]
+ },
+ "HDFS": {
+ "packages": []
+ },
+ "HIVE": {
+ "packages": ["hive", "hive-hcatalog", "hive2", "tez_hive2"]
+ },
+ "KAFKA": {
+ "packages": ["kafka"]
+ },
+ "KNOX": {
+ "packages": ["knox"]
+ },
+ "MAHOUT": {
+ "packages": ["mahout"]
+ },
+ "MAPREDUCE2": {
+ "packages": []
+ },
+ "OOZIE": {
+ "packages": ["oozie"]
+ },
+ "PIG": {
+ "packages": ["pig"]
+ },
+ "R4ML": {
+ "packages": []
+ },
+ "RANGER": {
+ "packages": ["ranger-admin", "ranger-usersync", "ranger-tagsync"]
+ },
+ "RANGER_KMS": {
+ "packages": ["ranger-kms"]
+ },
+ "SLIDER": {
+ "packages": ["slider"]
+ },
+ "SPARK": {
+ "packages": ["spark", "livy"]
+ },
+ "SPARK2": {
+ "packages": ["spark2", "livy"]
+ },
+ "SQOOP": {
+ "packages": ["sqoop"]
+ },
+ "STORM": {
+ "packages": ["storm", "storm-slider-client"]
+ },
+ "SYSTEMML": {
+ "packages": []
+ },
+ "TEZ": {
+ "packages": ["tez"]
+ },
+ "TITAN": {
+ "packages": []
+ },
+ "YARN": {
+ "packages": []
+ },
+ "ZEPPELIN": {
+ "packages": ["zeppelin"]
+ },
+ "ZOOKEEPER": {
+ "packages": ["zookeeper"]
+ }
+ },
+ "upgrade-dependencies" : {
+ "YARN": ["TEZ"],
+ "TEZ": ["YARN"],
+ "MAHOUT": ["MAPREDUCE2"]
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
index 9840106..f45ff75 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
@@ -99,6 +99,7 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.cluster.ClusterImpl;
import org.apache.ambari.server.state.repository.AvailableService;
+import org.apache.ambari.server.state.repository.ClusterVersionSummary;
import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.server.state.stack.upgrade.Direction;
import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
@@ -1883,6 +1884,244 @@ public class ClusterStackVersionResourceProviderTest {
}
+ @Test
+ public void testCreateResourcesPatch() throws Exception {
+ JsonArray json = new JsonParser().parse(OS_JSON).getAsJsonArray();
+
+ JsonObject jsonObj = json.get(0).getAsJsonObject();
+ jsonObj.addProperty(OperatingSystemResourceProvider.OPERATING_SYSTEM_AMBARI_MANAGED_REPOS, false);
+
+ String os_json = json.toString();
+
+ Cluster cluster = createNiceMock(Cluster.class);
+ StackId stackId = new StackId("HDP", "2.0.1");
+
+ StackEntity fromStack = new StackEntity();
+ fromStack.setStackName(stackId.getStackName());
+ fromStack.setStackVersion(stackId.getStackVersion());
+
+ RepositoryVersionEntity fromRepo = new RepositoryVersionEntity();
+ fromRepo.setId(0L);
+ fromRepo.setOperatingSystems(os_json);
+ fromRepo.setVersionXsd("version_definition.xsd");
+ fromRepo.setType(RepositoryType.STANDARD);
+ fromRepo.setStack(fromStack);
+ fromRepo.setVersion("2.0.1.0-1234");
+
+
+ StackEntity stackEntity = new StackEntity();
+ stackEntity.setStackName("HDP");
+ stackEntity.setStackVersion("2.1.1");
+
+ File f = new File("src/test/resources/hbase_version_test.xml");
+ String xmlString = IOUtils.toString(new FileInputStream(f));
+ // hack to remove ZK
+ xmlString = xmlString.replace("<service idref=\"ZOOKEEPER-346\" />", "");
+
+
+ RepositoryVersionEntity repoVersion = new RepositoryVersionEntity();
+ repoVersion.setId(1l);
+ repoVersion.setOperatingSystems(os_json);
+ repoVersion.setVersionXml(xmlString);
+ repoVersion.setVersionXsd("version_definition.xsd");
+ repoVersion.setType(RepositoryType.PATCH);
+ repoVersion.setStack(stackEntity);
+
+ ambariMetaInfo.getComponent("HDP", "2.1.1", "HBASE", "HBASE_MASTER").setVersionAdvertised(true);
+ ambariMetaInfo.getComponent("HDP", "2.0.1", "HBASE", "HBASE_MASTER").setVersionAdvertised(true);
+
+ final String hostWithoutVersionableComponents = "host3";
+ List<Host> hostsNeedingInstallCommands = new ArrayList<>();
+
+ Map<String, Host> hostsForCluster = new HashMap<>();
+ int hostCount = 10;
+ for (int i = 0; i < hostCount; i++) {
+ String hostname = "host" + i;
+ Host host = createNiceMock(hostname, Host.class);
+ expect(host.getHostName()).andReturn(hostname).anyTimes();
+ expect(host.getOsFamily()).andReturn("redhat6").anyTimes();
+ expect(host.getMaintenanceState(EasyMock.anyLong())).andReturn(
+ MaintenanceState.OFF).anyTimes();
+ expect(host.getAllHostVersions()).andReturn(
+ Collections.<HostVersionEntity>emptyList()).anyTimes();
+ expect(host.getHostAttributes()).andReturn(new HashMap<String, String>()).anyTimes();
+ replay(host);
+ hostsForCluster.put(hostname, host);
+
+ if (StringUtils.equals(hostWithoutVersionableComponents, hostname)) {
+ hostsNeedingInstallCommands.add(host);
+ }
+ }
+
+ Service hdfsService = createNiceMock(Service.class);
+ expect(hdfsService.getName()).andReturn("HDFS").anyTimes();
+ expect(hdfsService.getServiceComponents()).andReturn(new HashMap<String, ServiceComponent>());
+ expect(hdfsService.getDesiredRepositoryVersion()).andReturn(fromRepo).anyTimes();
+
+ Service hbaseService = createNiceMock(Service.class);
+ expect(hbaseService.getName()).andReturn("HBASE").anyTimes();
+ expect(hbaseService.getServiceComponents()).andReturn(new HashMap<String, ServiceComponent>());
+ expect(hbaseService.getDesiredRepositoryVersion()).andReturn(fromRepo).anyTimes();
+
+ Map<String, Service> serviceMap = new HashMap<>();
+ serviceMap.put("HDFS", hdfsService);
+ serviceMap.put("HBASE", hbaseService);
+
+ final ServiceComponentHost schDatanode = createMock(ServiceComponentHost.class);
+ expect(schDatanode.getServiceName()).andReturn("HDFS").anyTimes();
+ expect(schDatanode.getServiceComponentName()).andReturn("DATANODE").anyTimes();
+
+ final ServiceComponentHost schNamenode = createMock(ServiceComponentHost.class);
+ expect(schNamenode.getServiceName()).andReturn("HDFS").anyTimes();
+ expect(schNamenode.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
+
+ final ServiceComponentHost schHBM = createMock(ServiceComponentHost.class);
+ expect(schHBM.getServiceName()).andReturn("HBASE").anyTimes();
+ expect(schHBM.getServiceComponentName()).andReturn("HBASE_MASTER").anyTimes();
+
+ // First host contains versionable components
+ final List<ServiceComponentHost> schsH1 = Arrays.asList(schDatanode, schNamenode);
+
+ // Second host contains versionable components
+ final List<ServiceComponentHost> schsH2 = Arrays.asList(schDatanode);
+
+ // Third host only has hbase
+ final List<ServiceComponentHost> schsH3 = Arrays.asList(schHBM);
+
+ ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+ hdfsPackage.setName("hdfs");
+
+ List<ServiceOsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
+
+ ActionManager actionManager = createNiceMock(ActionManager.class);
+
+ RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+ ResourceProvider csvResourceProvider = createNiceMock(ResourceProvider.class);
+
+ Map<String, Map<String, String>> hostConfigTags = new HashMap<>();
+ expect(configHelper.getEffectiveDesiredTags(anyObject(ClusterImpl.class), anyObject(String.class))).andReturn(hostConfigTags);
+
+ expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+ expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
+ expect(managementController.getAuthName()).andReturn("admin").anyTimes();
+ expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
+ expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
+ expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+ EasyMock.<Map<String, String>>anyObject(), anyObject(String.class))).
+ andReturn(packages).anyTimes(); // only one host has the versionable component
+
+ expect(managementController.findConfigurationTagsWithOverrides(anyObject(Cluster.class), EasyMock.anyString()))
+ .andReturn(new HashMap<String, Map<String, String>>()).anyTimes();
+
+ expect(clusters.getCluster(anyObject(String.class))).andReturn(cluster);
+ expect(clusters.getHostsForCluster(anyObject(String.class))).andReturn(
+ hostsForCluster).anyTimes();
+
+ String clusterName = "Cluster100";
+ expect(cluster.getClusterId()).andReturn(1L).anyTimes();
+ expect(cluster.getHosts()).andReturn(hostsForCluster.values()).atLeastOnce();
+ expect(cluster.getServices()).andReturn(serviceMap).anyTimes();
+ expect(cluster.getCurrentStackVersion()).andReturn(stackId);
+ expect(cluster.getServiceComponentHosts(anyObject(String.class))).andAnswer(new IAnswer<List<ServiceComponentHost>>() {
+ @Override
+ public List<ServiceComponentHost> answer() throws Throwable {
+ String hostname = (String) EasyMock.getCurrentArguments()[0];
+ if (hostname.equals("host2")) {
+ return schsH2;
+ } else if (hostname.equals("host3")) {
+ return schsH3;
+ } else {
+ return schsH1;
+ }
+ }
+ }).anyTimes();
+
+ expect(cluster.transitionHostsToInstalling(anyObject(RepositoryVersionEntity.class),
+ anyObject(VersionDefinitionXml.class), eq(false))).andReturn(hostsNeedingInstallCommands).atLeastOnce();
+
+ ExecutionCommand executionCommand = new ExecutionCommand();
+ ExecutionCommandWrapper executionCommandWrapper = createNiceMock(ExecutionCommandWrapper.class);
+
+ expect(executionCommandWrapper.getExecutionCommand()).andReturn(executionCommand).anyTimes();
+
+ Stage stage = createNiceMock(Stage.class);
+ expect(stage.getExecutionCommandWrapper(anyObject(String.class), anyObject(String.class))).
+ andReturn(executionCommandWrapper).anyTimes();
+
+ Map<Role, Float> successFactors = new HashMap<>();
+ expect(stage.getSuccessFactors()).andReturn(successFactors).atLeastOnce();
+
+ // Check that we create proper stage count
+ expect(stageFactory.createNew(anyLong(), anyObject(String.class),
+ anyObject(String.class), anyLong(),
+ anyObject(String.class), anyObject(String.class),
+ anyObject(String.class))).andReturn(stage).
+ times((int) Math.ceil(hostCount / MAX_TASKS_PER_STAGE));
+
+ expect(repositoryVersionDAOMock.findByStackAndVersion(anyObject(StackId.class),
+ anyObject(String.class))).andReturn(repoVersion);
+
+ Capture<org.apache.ambari.server.actionmanager.Request> c = Capture.newInstance();
+ Capture<ExecuteActionRequest> ear = Capture.newInstance();
+
+ actionManager.sendActions(capture(c), capture(ear));
+ expectLastCall().atLeastOnce();
+ expect(actionManager.getRequestTasks(anyLong())).andReturn(Collections.<HostRoleCommand>emptyList()).anyTimes();
+
+ ClusterEntity clusterEntity = new ClusterEntity();
+ clusterEntity.setClusterId(1l);
+ clusterEntity.setClusterName(clusterName);
+
+ StageUtils.setTopologyManager(injector.getInstance(TopologyManager.class));
+ StageUtils.setConfiguration(injector.getInstance(Configuration.class));
+
+ // replay
+ replay(managementController, response, clusters, hdfsService, hbaseService, csvResourceProvider,
+ cluster, repositoryVersionDAOMock, configHelper, schDatanode, schNamenode, schHBM, actionManager,
+ executionCommandWrapper,stage, stageFactory);
+
+ ResourceProvider provider = createProvider(managementController);
+ injector.injectMembers(provider);
+
+ // add the property map to a set for the request. add more maps for multiple creates
+ Set<Map<String, Object>> propertySet = new LinkedHashSet<>();
+
+ Map<String, Object> properties = new LinkedHashMap<>();
+
+ // add properties to the request map
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_REPOSITORY_VERSION_PROPERTY_ID, "2.2.0.1-885");
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_STACK_PROPERTY_ID, "HDP");
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_VERSION_PROPERTY_ID, "2.1.1");
+
+ propertySet.add(properties);
+
+ // create the request
+ Request request = PropertyHelper.getCreateRequest(propertySet, null);
+
+ SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+
+ RequestStatus status = provider.createResources(request);
+ Assert.assertNotNull(status);
+
+ // check that the success factor was populated in the stage
+ Float successFactor = successFactors.get(Role.INSTALL_PACKAGES);
+ Assert.assertEquals(Float.valueOf(0.85f), successFactor);
+
+ Assert.assertNotNull(executionCommand.getRepositoryFile());
+ Assert.assertNotNull(executionCommand.getRoleParameters());
+ Map<String, Object> roleParams = executionCommand.getRoleParameters();
+ Assert.assertTrue(roleParams.containsKey(KeyNames.CLUSTER_VERSION_SUMMARY));
+ Assert.assertEquals(ClusterVersionSummary.class,
+ roleParams.get(KeyNames.CLUSTER_VERSION_SUMMARY).getClass());
+
+ Assert.assertEquals(2, executionCommand.getRepositoryFile().getRepositories().size());
+ for (CommandRepository.Repository repo : executionCommand.getRepositoryFile().getRepositories()) {
+ Assert.assertFalse(repo.isAmbariManaged());
+ }
+
+ }
+
private ClusterStackVersionResourceProvider createProvider(AmbariManagementController amc) {
ResourceProviderFactory factory = injector.getInstance(ResourceProviderFactory.class);
AbstractControllerResourceProvider.init(factory);
http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py b/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
index 92dd634..a199d00 100644
--- a/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
+++ b/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
@@ -185,4 +185,16 @@ class TestConfSelect(RMFTestCase):
conf_select.convert_conf_directories_to_symlinks("hadoop", "2.3.0.0-1234", packages["hadoop"])
- self.assertEqual(pprint.pformat(self.env.resource_list), "[]")
\ No newline at end of file
+ self.assertEqual(pprint.pformat(self.env.resource_list), "[]")
+
+
+ def test_restrictions(self):
+
+ Script.config.update({'roleParameters': {'cluster_version_summary': {'services': {'HIVE': {'upgrade': True}}}}})
+
+ restricted = conf_select.get_restricted_packages()
+ self.assertTrue("hive" in restricted)
+ self.assertTrue("hive-hcatalog" in restricted)
+ self.assertTrue("hive2" in restricted)
+ self.assertTrue("tez_hive2" in restricted)
+ self.assertTrue("hadoop" not in restricted)
[20/51] [abbrv] ambari git commit: AMBARI-22369. Remove
Auto-Installation of Mysql Connector (ncole)
Posted by nc...@apache.org.
AMBARI-22369. Remove Auto-Installation of Mysql Connector (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/cbce5e87
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/cbce5e87
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/cbce5e87
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: cbce5e87971264819e4e7d62621c5463947fd863
Parents: f74b2f8
Author: Nate Cole <nc...@hortonworks.com>
Authored: Tue Nov 7 09:00:28 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Tue Nov 7 09:23:03 2017 -0500
----------------------------------------------------------------------
.../libraries/functions/package_conditions.py | 6 +-----
.../common-services/HIVE/0.12.0.2.0/metainfo.xml | 5 -----
.../resources/common-services/HIVE/2.1.0.3.0/metainfo.xml | 10 ----------
.../common-services/OOZIE/4.2.0.2.3/metainfo.xml | 5 -----
.../common-services/OOZIE/4.2.0.3.0/metainfo.xml | 5 -----
.../common-services/SQOOP/1.4.4.2.0/metainfo.xml | 5 -----
.../common-services/SQOOP/1.4.4.3.0/metainfo.xml | 10 ----------
.../stacks/BIGTOP/0.8/services/HIVE/metainfo.xml | 4 ----
.../stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml | 4 ----
.../stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml | 4 ----
.../HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml | 4 ----
.../stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml | 4 ----
.../stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml | 4 ----
.../resources/stacks/HDP/2.1/services/HIVE/metainfo.xml | 5 -----
.../resources/stacks/HDP/2.2/services/HIVE/metainfo.xml | 10 ----------
.../resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml | 5 -----
.../resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml | 10 ----------
.../stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml | 9 ---------
.../stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml | 9 ---------
.../resources/stacks/HDP/2.3/services/HIVE/metainfo.xml | 10 ----------
.../resources/stacks/HDP/2.5/services/HIVE/metainfo.xml | 10 ----------
.../resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml | 10 ----------
22 files changed, 1 insertion(+), 147 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
index 5a16061..31e78b9 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
@@ -20,7 +20,7 @@ Ambari Agent
"""
__all__ = ["is_lzo_enabled", "should_install_phoenix", "should_install_ams_collector", "should_install_ams_grafana",
- "should_install_mysql", "should_install_mysql_connector", "should_install_ranger_tagsync"]
+ "should_install_mysql", "should_install_ranger_tagsync"]
import os
from resource_management.libraries.script import Script
@@ -85,10 +85,6 @@ def should_install_mysql():
return False
return _has_applicable_local_component(config, "MYSQL_SERVER")
-def should_install_mysql_connector():
- mysql_jdbc_driver_jar = "/usr/share/java/mysql-connector-java.jar"
- return not os.path.exists(mysql_jdbc_driver_jar)
-
def should_install_hive_atlas():
atlas_hosts = default('/clusterHostInfo/atlas_server_hosts', [])
has_atlas = len(atlas_hosts) > 0
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
index d84a85d..c2c8189 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
@@ -276,11 +276,6 @@
<package>
<name>webhcat-tar-pig</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
</packages>
</osSpecific>
<osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
index db490c9..48dda31 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
@@ -369,16 +369,6 @@
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
index d818074..fca2bba 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
@@ -123,11 +123,6 @@
<name>zip</name>
</package>
<package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- <package>
<name>extjs</name>
</package>
</packages>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
index d351cbe..47b3705 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
@@ -126,11 +126,6 @@
<name>zip</name>
</package>
<package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- <package>
<name>extjs</name>
</package>
</packages>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
index a7ec1ec..56071ec 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
@@ -74,11 +74,6 @@
<package>
<name>sqoop</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
</packages>
</osSpecific>
</osSpecifics>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
index 999d93a..e02d9f4 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
@@ -69,16 +69,6 @@
</components>
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
index d14ce67..d9ee0a3 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
@@ -233,10 +233,6 @@
<package>
<name>postgresql-jdbc</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
</packages>
</osSpecific>
<osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
index 20c3b32..8382662 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
@@ -121,10 +121,6 @@
<package>
<name>oozie-client</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
</packages>
</osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
index 633f3a6..ca92e98 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
@@ -57,10 +57,6 @@
<package>
<name>webhcat-tar-pig</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
</packages>
</osSpecific>
<osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
index 27d4ba4..150cbde 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
@@ -40,10 +40,6 @@
<package>
<name>zip</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
</packages>
</osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
index 7bad9fc..7ac6a63 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
@@ -57,10 +57,6 @@
<package>
<name>webhcat-tar-pig</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
</packages>
</osSpecific>
<osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
index a62ef78..82e74ae 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
@@ -40,10 +40,6 @@
<package>
<name>zip</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
</packages>
</osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
index 28dfb37..f3eaa8c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
@@ -55,11 +55,6 @@
<package>
<name>webhcat-tar-pig</name>
</package>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
</packages>
</osSpecific>
<osSpecific>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
index 051cad1..49a4e69 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
@@ -58,16 +58,6 @@
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>amazon2015,redhat6,redhat7,suse11,suse12</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
index cb84a5d..87afb5c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
@@ -65,11 +65,6 @@
<name>zip</name>
</package>
<package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- <package>
<name>extjs</name>
</package>
</packages>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
index 884019c..c0e6b3e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
@@ -23,16 +23,6 @@
<version>1.4.5.2.2</version>
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
index 0e12f09..7340b79 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
@@ -24,15 +24,6 @@
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat5,redhat6,suse11</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
index 5238914..5b02eea 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
@@ -23,15 +23,6 @@
<version>1.4.6.2.3</version>
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat5,redhat6,suse11</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
index accbedd..53b8dd0 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
@@ -24,16 +24,6 @@
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
index f2a1161..fb72d98 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
@@ -142,16 +142,6 @@
</requiredServices>
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_mysql_connector</condition>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
<packages>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml b/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
index 5d1c898..3fb083b 100755
--- a/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
+++ b/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
@@ -307,16 +307,6 @@
<metricsFileName>metrics.json</metricsFileName>
<osSpecifics>
<osSpecific>
- <osFamily>any</osFamily>
- <packages>
- <package>
- <name>mysql-connector-java</name>
- <condition>should_install_mysql_connector</condition>
- <skipUpgrade>true</skipUpgrade>
- </package>
- </packages>
- </osSpecific>
- <osSpecific>
<osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
<packages>
<package>
[10/51] [abbrv] ambari git commit: AMBARI-22354 Service Action Menu
issues. (atkach)
Posted by nc...@apache.org.
AMBARI-22354 Service Action Menu issues. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1b020cd9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1b020cd9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1b020cd9
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 1b020cd98e8aca05097a8a829927e2d0415d480c
Parents: b8f7369
Author: Andrii Tkach <at...@apache.org>
Authored: Fri Nov 3 12:48:55 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Fri Nov 3 12:48:55 2017 +0200
----------------------------------------------------------------------
.../app/styles/theme/bootstrap-ambari.css | 35 +++++++++++++++-----
.../admin/kerberos/step2_controller_test.js | 2 +-
.../vendor/scripts/theme/bootstrap-ambari.js | 7 ----
3 files changed, 28 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/1b020cd9/ambari-web/app/styles/theme/bootstrap-ambari.css
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/theme/bootstrap-ambari.css b/ambari-web/app/styles/theme/bootstrap-ambari.css
index 7d1ad61..e85bb32 100644
--- a/ambari-web/app/styles/theme/bootstrap-ambari.css
+++ b/ambari-web/app/styles/theme/bootstrap-ambari.css
@@ -537,20 +537,27 @@ h2.table-title {
}
.wizard .wizard-body .wizard-content {
background: #ebecf1;
- padding-top: 25px;
+ padding-top: 15px;
float: left;
margin-bottom: -99999px;
padding-bottom: 99999px;
}
+.wizard .wizard-body .wizard-content .step-header {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ color: #666;
+ font-size: 14px;
+ font-style: normal;
+ line-height: 1;
+ margin-bottom: 5px;
+}
.wizard .wizard-body .wizard-content .step-title {
font-family: 'Roboto', sans-serif;
font-weight: normal;
font-style: normal;
line-height: 1;
color: #333;
- font-weight: bold;
- font-size: 18px;
- color: #666;
+ font-size: 16px;
}
.wizard .wizard-body .wizard-content .step-description {
font-family: 'Roboto', sans-serif;
@@ -558,7 +565,7 @@ h2.table-title {
font-style: normal;
line-height: 1;
color: #333;
- font-size: 14px;
+ font-size: 12px;
line-height: 1.4;
color: #999;
}
@@ -568,7 +575,7 @@ h2.table-title {
margin-top: 20px;
}
.wizard .wizard-body .wizard-content .panel.panel-default .panel-body {
- padding: 30px 20px;
+ padding: 10px 20px;
}
.wizard .wizard-body .wizard-nav {
min-height: 550px;
@@ -1042,16 +1049,28 @@ input.radio:checked + label:after {
}
.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a,
.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a {
- color: #666;
+ color: #333;
}
.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a i,
.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a i {
- color: #666;
+ color: #333;
}
.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a:hover,
.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a:hover {
background: #f5f5f5;
}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a.disabled,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a.disabled {
+ color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a.disabled i,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a.disabled i {
+ color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a.disabled:hover,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a.disabled:hover {
+ background: #f5f5f5;
+}
.navigation-bar-container ul.nav.side-nav-menu .menu-item-name,
.navigation-bar-container ul.nav.side-nav-footer .menu-item-name {
display: inline-block;
http://git-wip-us.apache.org/repos/asf/ambari/blob/1b020cd9/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
index 794fe4a..a9103a8 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
@@ -451,7 +451,7 @@ describe('App.KerberosWizardStep2Controller', function() {
});
it("ipa type configs", function() {
- var configs = [{name: 'group'}];
+ var configs = [{name: 'ipa_user_group'}];
controller.setConfigVisibility('ipa', configs, Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'));
expect(configs[0].isVisible).to.be.true;
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1b020cd9/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
----------------------------------------------------------------------
diff --git a/ambari-web/vendor/scripts/theme/bootstrap-ambari.js b/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
index 5fd713a..6102bc3 100644
--- a/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
+++ b/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
@@ -158,13 +158,6 @@ $(document).ready(function () {
});
});
}
- $dropdownMenu.on('click', function () {
- // some action was triggered, should hide this icon
- var moreIcon = $(this).parent();
- setTimeout(function () {
- moreIcon.hide();
- }, 1000);
- });
$navigationContainer.children('.side-nav-menu').scroll(function () {
$moreActions.removeClass('open');
});
[09/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement
new design for Admin View. (atkach)
Posted by nc...@apache.org.
AMBARI-22352 Ambari 3.0: Implement new design for Admin View. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b8f7369b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b8f7369b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b8f7369b
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: b8f7369bf31ee0186db50816206068cf8bc890df
Parents: fe02abf
Author: Andrii Tkach <at...@apache.org>
Authored: Thu Nov 2 18:14:18 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Fri Nov 3 12:39:30 2017 +0200
----------------------------------------------------------------------
ambari-admin/pom.xml | 2 +-
.../app/assets/fonts/Roboto-Regular-webfont.eot | Bin 0 -> 79547 bytes
.../app/assets/fonts/Roboto-Regular-webfont.svg | 7606 ++++++++++++++++++
.../app/assets/fonts/Roboto-Regular-webfont.ttf | Bin 0 -> 234464 bytes
.../assets/fonts/Roboto-Regular-webfont.woff | Bin 0 -> 105700 bytes
.../main/resources/ui/admin-web/app/index.html | 78 +-
.../app/scripts/controllers/AppCtrl.js | 177 +
.../app/scripts/controllers/NavbarCtrl.js | 106 -
.../app/scripts/controllers/SideNavCtrl.js | 68 +
.../app/scripts/controllers/mainCtrl.js | 168 +-
.../ui/admin-web/app/scripts/i18n.config.js | 11 +-
.../ui/admin-web/app/scripts/routes.js | 69 +-
.../app/scripts/theme/bootstrap-ambari.js | 269 +
.../resources/ui/admin-web/app/styles/main.css | 433 +-
.../app/styles/theme/bootstrap-ambari.css | 1518 ++++
.../ui/admin-web/app/styles/top-nav.css | 197 +
.../ui/admin-web/app/views/groups/list.html | 4 +-
.../ui/admin-web/app/views/leftNavbar.html | 126 -
.../resources/ui/admin-web/app/views/main.html | 59 +-
.../app/views/remoteClusters/list.html | 3 +-
.../ui/admin-web/app/views/sideNav.html | 106 +
.../admin-web/app/views/stackVersions/list.html | 5 +-
.../ui/admin-web/app/views/users/list.html | 4 +-
.../src/main/resources/ui/admin-web/bower.json | 2 +-
.../src/main/resources/ui/admin-web/gulpfile.js | 10 +-
.../main/resources/ui/admin-web/package.json | 6 +-
.../test/unit/controllers/AppCtrl_test.js | 211 +
.../test/unit/controllers/mainCtrl_test.js | 215 -
.../test/unit/services/Utility_test.js | 3 +-
29 files changed, 10334 insertions(+), 1122 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-admin/pom.xml b/ambari-admin/pom.xml
index cb82e45..281280a 100644
--- a/ambari-admin/pom.xml
+++ b/ambari-admin/pom.xml
@@ -192,7 +192,7 @@
<exclude>src/main/resources/ui/admin-web/bower_components/**</exclude>
<exclude>src/main/resources/ui/admin-web/dist/**</exclude>
<exclude>src/main/resources/ui/admin-web/node/**</exclude>
- <exclude>src/main/resources/ui/admin-web/app/assets/data/**</exclude>
+ <exclude>src/main/resources/ui/admin-web/app/assets/**</exclude>
<exclude>src/main/resources/ui/admin-web/node_modules/**</exclude>
<exclude>src/main/resources/ui/admin-web/app/bower_components/**</exclude>
<exclude>src/main/resources/ui/admin-web/test/bower_components/**</exclude>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot
new file mode 100644
index 0000000..d4e185d
Binary files /dev/null and b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot differ
[18/51] [abbrv] ambari git commit: AMBARI-22332 Falcon Service check
failed during cluster deploy (dgrinenko)
Posted by nc...@apache.org.
AMBARI-22332 Falcon Service check failed during cluster deploy (dgrinenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ec3f1e4d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ec3f1e4d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ec3f1e4d
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: ec3f1e4dcf4d0e53f10b7f7fe913b1bfdbcab82a
Parents: 976153f
Author: Dmytro Grinenko <ha...@apache.org>
Authored: Tue Nov 7 08:11:09 2017 +0200
Committer: Dmytro Grinenko <ha...@apache.org>
Committed: Tue Nov 7 08:13:08 2017 +0200
----------------------------------------------------------------------
.../main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ec3f1e4d/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
index 79296c3..1066f6c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
@@ -30,7 +30,7 @@
<name>falcon_${stack_version}</name>
</package>
<package>
- <name>atlas-metadata_${stack_version}-hive-plugin</name>
+ <name>atlas-metadata_${stack_version}-falcon-plugin</name>
<condition>should_install_falcon_atlas_hook</condition>
</package>
</packages>
@@ -42,7 +42,7 @@
<name>falcon-${stack_version}</name>
</package>
<package>
- <name>atlas-metadata-${stack_version}-hive-plugin</name>
+ <name>atlas-metadata-${stack_version}-falcon-plugin</name>
<condition>should_install_falcon_atlas_hook</condition>
</package>
</packages>
[46/51] [abbrv] ambari git commit: AMBARI-22416 Log Search UI: fixes
for filtering form. (ababiichuk)
Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
deleted file mode 100644
index 2b3e326..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import {TestBed, inject} from '@angular/core/testing';
-import {StoreModule} from '@ngrx/store';
-import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
-import {AppStateService, appState} from '@app/services/storage/app-state.service';
-import {ClustersService, clusters} from '@app/services/storage/clusters.service';
-import {ComponentsService, components} from '@app/services/storage/components.service';
-import {HostsService, hosts} from '@app/services/storage/hosts.service';
-import {UtilsService} from '@app/services/utils.service';
-import {HttpClientService} from '@app/services/http-client.service';
-import {ListItem} from '@app/classes/list-item';
-import {Node} from '@app/classes/models/node';
-
-import {FilteringService} from './filtering.service';
-
-describe('FilteringService', () => {
- beforeEach(() => {
- const httpClient = {
- get: () => {
- return {
- subscribe: () => {
- }
- }
- }
- };
- TestBed.configureTestingModule({
- imports: [
- StoreModule.provideStore({
- appSettings,
- appState,
- clusters,
- components,
- hosts
- })
- ],
- providers: [
- FilteringService,
- AppSettingsService,
- AppStateService,
- ClustersService,
- ComponentsService,
- HostsService,
- UtilsService,
- {
- provide: HttpClientService,
- useValue: httpClient
- }
- ]
- });
- });
-
- it('should create service', inject([FilteringService], (service: FilteringService) => {
- expect(service).toBeTruthy();
- }));
-
- describe('#getListItemFromString()', () => {
- it('should convert string to ListItem', inject([FilteringService], (service: FilteringService) => {
- const getListItemFromString: (name: string) => ListItem = service['getListItemFromString'];
- expect(getListItemFromString('customName')).toEqual({
- label: 'customName',
- value: 'customName'
- });
- }));
- });
-
- describe('#getListItemFromNode()', () => {
- it('should convert Node to ListItem', inject([FilteringService], (service: FilteringService) => {
- const getListItemFromNode: (node: Node) => ListItem = service['getListItemFromNode'];
- expect(getListItemFromNode({
- name: 'customName',
- value: '1',
- isParent: true,
- isRoot: true
- })).toEqual({
- label: 'customName (1)',
- value: 'customName'
- });
- }));
- });
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
deleted file mode 100644
index 85dc408..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import {Injectable, Input} from '@angular/core';
-import {FormGroup} from '@angular/forms';
-import {Response} from '@angular/http';
-import {Subject} from 'rxjs/Subject';
-import {Observable} from 'rxjs/Observable';
-import 'rxjs/add/observable/timer';
-import 'rxjs/add/operator/takeUntil';
-import * as moment from 'moment-timezone';
-import {ListItem} from '@app/classes/list-item';
-import {FilterCondition, filters} from '@app/classes/filtering';
-import {Node} from '@app/classes/models/node';
-import {AppSettingsService} from '@app/services/storage/app-settings.service';
-import {ClustersService} from '@app/services/storage/clusters.service';
-import {ComponentsService} from '@app/services/storage/components.service';
-import {HostsService} from '@app/services/storage/hosts.service';
-import {AppStateService} from '@app/services/storage/app-state.service';
-import {HttpClientService} from '@app/services/http-client.service';
-
-@Injectable()
-export class FilteringService {
-
- constructor(private httpClient: HttpClientService, private appSettings: AppSettingsService, private clustersStorage: ClustersService, private componentsStorage: ComponentsService, private hostsStorage: HostsService, private appState: AppStateService) {
- this.loadClusters();
- this.loadComponents();
- this.loadHosts();
- appSettings.getParameter('timeZone').subscribe(value => this.timeZone = value || this.defaultTimeZone);
- clustersStorage.getAll().subscribe((clusters: string[]): void => {
- this.filters.clusters.options = [...this.filters.clusters.options, ...clusters.map(this.getListItemFromString)];
- });
- componentsStorage.getAll().subscribe((components: Node[]): void => {
- this.filters.components.options = [...this.filters.components.options, ...components.map(this.getListItemFromNode)];
- });
- hostsStorage.getAll().subscribe((hosts: Node[]): void => {
- this.filters.hosts.options = [...this.filters.hosts.options, ...hosts.map(this.getListItemFromNode)];
- });
- appState.getParameter('activeFiltersForm').subscribe((form: FormGroup) => this.activeFiltersForm = form);
- }
-
- /**
- * Get instance for dropdown list from string
- * @param name {string}
- * @returns {ListItem}
- */
- private getListItemFromString(name: string): ListItem {
- return {
- label: name,
- value: name
- };
- }
-
- /**
- * Get instance for dropdown list from Node object
- * @param node {Node}
- * @returns {ListItem}
- */
- private getListItemFromNode(node: Node): ListItem {
- return {
- label: `${node.name} (${node.value})`,
- value: node.name
- };
- }
-
- private readonly defaultTimeZone = moment.tz.guess();
-
- timeZone: string = this.defaultTimeZone;
-
- /**
- * A configurable property to indicate the maximum capture time in milliseconds.
- * @type {number}
- * @default 600000 (10 minutes)
- */
- @Input()
- maximumCaptureTimeLimit: number = 600000;
-
- filters: {[key: string]: FilterCondition} = Object.assign({}, filters);
-
- activeFiltersForm: FormGroup;
-
- queryParameterNameChange: Subject<any> = new Subject();
-
- queryParameterAdd: Subject<any> = new Subject();
-
- private stopTimer: Subject<any> = new Subject();
-
- private stopAutoRefreshCountdown: Subject<any> = new Subject();
-
- captureSeconds: number = 0;
-
- private readonly autoRefreshInterval: number = 30000;
-
- autoRefreshRemainingSeconds: number = 0;
-
- private startCaptureTime: number;
-
- private stopCaptureTime: number;
-
- startCaptureTimer(): void {
- this.startCaptureTime = new Date().valueOf();
- const maxCaptureTimeInSeconds = this.maximumCaptureTimeLimit / 1000;
- Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe((seconds: number): void => {
- this.captureSeconds = seconds;
- if (this.captureSeconds >= maxCaptureTimeInSeconds) {
- this.stopCaptureTimer();
- }
- });
- }
-
- stopCaptureTimer(): void {
- const autoRefreshIntervalSeconds = this.autoRefreshInterval / 1000;
- this.stopCaptureTime = new Date().valueOf();
- this.captureSeconds = 0;
- this.stopTimer.next();
- this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
- Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe((seconds: number): void => {
- this.autoRefreshRemainingSeconds = autoRefreshIntervalSeconds - seconds;
- if (!this.autoRefreshRemainingSeconds) {
- this.stopAutoRefreshCountdown.next();
- this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
- }
- });
- }
-
- loadClusters(): void {
- this.httpClient.get('clusters').subscribe((response: Response): void => {
- const clusterNames = response.json();
- if (clusterNames) {
- this.clustersStorage.addInstances(clusterNames);
- }
- });
- }
-
- loadComponents(): void {
- this.httpClient.get('components').subscribe((response: Response): void => {
- const jsonResponse = response.json(),
- components = jsonResponse && jsonResponse.vNodeList.map((item): Node => Object.assign(item, {
- value: item.logLevelCount.reduce((currentValue: number, currentItem): number => {
- return currentValue + Number(currentItem.value);
- }, 0)
- }));
- if (components) {
- this.componentsStorage.addInstances(components);
- }
- });
- }
-
- loadHosts(): void {
- this.httpClient.get('hosts').subscribe((response: Response): void => {
- const jsonResponse = response.json(),
- hosts = jsonResponse && jsonResponse.vNodeList;
- if (hosts) {
- this.hostsStorage.addInstances(hosts);
- }
- });
- }
-
- setCustomTimeRange(startTime: number, endTime: number): void {
- this.activeFiltersForm.controls.timeRange.setValue({
- type: 'CUSTOM',
- start: moment(startTime),
- end: moment(endTime)
- });
- }
-
- private getStartTime = (value: any, current: string): string => {
- let time;
- if (value) {
- const endTime = moment(moment(current).valueOf());
- switch (value.type) {
- case 'LAST':
- time = endTime.subtract(value.interval, value.unit);
- break;
- case 'CURRENT':
- time = moment().tz(this.timeZone).startOf(value.unit);
- break;
- case 'PAST':
- time = endTime.startOf(value.unit);
- break;
- case 'CUSTOM':
- time = value.start;
- break;
- default:
- break;
- }
- }
- return time ? time.toISOString() : '';
- };
-
- private getEndTime = (value: any): string => {
- let time;
- if (value) {
- switch (value.type) {
- case 'LAST':
- time = moment();
- break;
- case 'CURRENT':
- time = moment().tz(this.timeZone).endOf(value.unit);
- break;
- case 'PAST':
- time = moment().tz(this.timeZone).startOf(value.unit).millisecond(-1);
- break;
- case 'CUSTOM':
- time = value.end;
- break;
- default:
- break;
- }
- }
- return time ? time.toISOString() : '';
- };
-
- private getQuery(isExclude: boolean): (value: any[]) => string {
- return (value: any[]): string => {
- let parameters;
- if (value && value.length) {
- parameters = value.filter(item => item.isExclude === isExclude).map(parameter => {
- return {
- [parameter.name]: parameter.value.replace(/\s/g, '+')
- };
- });
- }
- return parameters && parameters.length ? JSON.stringify(parameters) : '';
- }
- }
-
- readonly valueGetters = {
- to: this.getEndTime,
- from: this.getStartTime,
- sortType: value => value && value.type,
- sortBy: value => value && value.key,
- page: value => value == null ? value : value.toString(),
- includeQuery: this.getQuery(false),
- excludeQuery: this.getQuery(true)
- };
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
index ee0e1e7..47cb25d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
@@ -31,7 +31,8 @@ import {HostsService, hosts} from '@app/services/storage/hosts.service';
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {ListItem} from '@app/classes/list-item';
+import {NodeItem} from '@app/classes/models/node-item';
import {LogsContainerService} from './logs-container.service';
@@ -79,8 +80,7 @@ describe('LogsContainerService', () => {
{
provide: HttpClientService,
useValue: httpClient
- },
- FilteringService
+ }
]
});
});
@@ -88,4 +88,29 @@ describe('LogsContainerService', () => {
it('should create service', inject([LogsContainerService], (service: LogsContainerService) => {
expect(service).toBeTruthy();
}));
+
+ describe('#getListItemFromString()', () => {
+ it('should convert string to ListItem', inject([LogsContainerService], (service: LogsContainerService) => {
+ const getListItemFromString: (name: string) => ListItem = service['getListItemFromString'];
+ expect(getListItemFromString('customName')).toEqual({
+ label: 'customName',
+ value: 'customName'
+ });
+ }));
+ });
+
+ describe('#getListItemFromNode()', () => {
+ it('should convert NodeItem to ListItem', inject([LogsContainerService], (service: LogsContainerService) => {
+ const getListItemFromNode: (node: NodeItem) => ListItem = service['getListItemFromNode'];
+ expect(getListItemFromNode({
+ name: 'customName',
+ value: '1',
+ isParent: true,
+ isRoot: true
+ })).toEqual({
+ label: 'customName (1)',
+ value: 'customName'
+ });
+ }));
+ });
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
index e187b00..f45887b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
@@ -17,9 +17,14 @@
*/
import {Injectable} from '@angular/core';
+import {FormGroup, FormControl} from '@angular/forms';
import {Response} from '@angular/http';
+import {Subject} from 'rxjs/Subject';
+import {Observable} from 'rxjs/Observable';
+import 'rxjs/add/observable/timer';
+import 'rxjs/add/operator/takeUntil';
+import * as moment from 'moment-timezone';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
import {AuditLogsService} from '@app/services/storage/audit-logs.service';
import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.service';
import {ServiceLogsService} from '@app/services/storage/service-logs.service';
@@ -27,30 +32,411 @@ import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-field
import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service';
import {ServiceLogsTruncatedService} from '@app/services/storage/service-logs-truncated.service';
import {AppStateService} from '@app/services/storage/app-state.service';
+import {AppSettingsService} from '@app/services/storage/app-settings.service';
import {TabsService} from '@app/services/storage/tabs.service';
+import {ClustersService} from '@app/services/storage/clusters.service';
+import {ComponentsService} from '@app/services/storage/components.service';
+import {HostsService} from '@app/services/storage/hosts.service';
import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry';
+import {FilterCondition, TimeUnitListItem, SortingListItem} from '@app/classes/filtering';
+import {ListItem} from '@app/classes/list-item';
import {Tab} from '@app/classes/models/tab';
import {AuditLogField} from '@app/classes/models/audit-log-field';
import {ServiceLogField} from '@app/classes/models/service-log-field';
import {BarGraph} from '@app/classes/models/bar-graph';
+import {NodeItem} from '@app/classes/models/node-item';
@Injectable()
export class LogsContainerService {
- constructor(private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService, private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService, private tabsStorage: TabsService, private filtering: FilteringService) {
+ constructor(
+ private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService,
+ private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService,
+ private serviceLogsFieldsStorage: ServiceLogsFieldsService,
+ private serviceLogsHistogramStorage: ServiceLogsHistogramDataService,
+ private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService,
+ private appSettings: AppSettingsService, private tabsStorage: TabsService, private clustersStorage: ClustersService,
+ private componentsStorage: ComponentsService, private hostsStorage: HostsService
+ ) {
+ const formItems = Object.keys(this.filters).reduce((currentObject: any, key: string): {[key: string]: FormControl} => {
+ let formControl = new FormControl(),
+ item = {
+ [key]: formControl
+ };
+ formControl.setValue(this.filters[key].defaultSelection);
+ return Object.assign(currentObject, item);
+ }, {});
+ this.filtersForm = new FormGroup(formItems);
+ this.loadClusters();
+ this.loadComponents();
+ this.loadHosts();
appState.getParameter('activeLog').subscribe((value: ActiveServiceLogEntry | null) => this.activeLog = value);
- appState.getParameter('isServiceLogsFileView').subscribe((value: boolean): void => {
- const activeLog = this.activeLog,
- filtersForm = this.filtering.activeFiltersForm;
- if (value && activeLog) {
- filtersForm.controls.hosts.setValue(activeLog.host_name);
- filtersForm.controls.components.setValue(activeLog.component_name);
- }
- this.isServiceLogsFileView = value;
- });
+ appState.getParameter('isServiceLogsFileView').subscribe((value: boolean) => this.isServiceLogsFileView = value);
appState.getParameter('activeLogsType').subscribe((value: string) => this.activeLogsType = value);
+ appSettings.getParameter('timeZone').subscribe((value: string) => this.timeZone = value || this.defaultTimeZone);
+ tabsStorage.mapCollection((tab: Tab): Tab => {
+ let currentAppState = tab.appState || {};
+ const appState = Object.assign({}, currentAppState, {
+ activeFilters: this.getFiltersData(tab.type)
+ });
+ return Object.assign({}, tab, {
+ appState
+ });
+ });
+ appState.getParameter('activeFilters').subscribe((filters: object): void => {
+ this.filtersFormChange.next();
+ if (filters) {
+ const controls = this.filtersForm.controls;
+ Object.keys(controls).forEach((key: string): void => {
+ controls[key].setValue(filters.hasOwnProperty(key) ? filters[key] : null);
+ });
+ }
+ this.loadLogs();
+ this.filtersForm.valueChanges.takeUntil(this.filtersFormChange).subscribe((value: object): void => {
+ this.tabsStorage.mapCollection((tab: Tab): Tab => {
+ const currentAppState = tab.appState || {},
+ appState = Object.assign({}, currentAppState, tab.isActive ? {
+ activeFilters: value
+ } : null);
+ return Object.assign({}, tab, {
+ appState
+ });
+ });
+ this.loadLogs();
+ });
+ });
}
+ private readonly paginationOptions: string[] = ['10', '25', '50', '100'];
+
+ filters: {[key: string]: FilterCondition} = {
+ clusters: {
+ label: 'filter.clusters',
+ options: [],
+ defaultSelection: []
+ },
+ timeRange: {
+ options: [
+ [
+ {
+ label: 'filter.timeRange.7d',
+ value: {
+ type: 'LAST',
+ unit: 'd',
+ interval: 7
+ }
+ },
+ {
+ label: 'filter.timeRange.30d',
+ value: {
+ type: 'LAST',
+ unit: 'd',
+ interval: 30
+ }
+ },
+ {
+ label: 'filter.timeRange.60d',
+ value: {
+ type: 'LAST',
+ unit: 'd',
+ interval: 60
+ }
+ },
+ {
+ label: 'filter.timeRange.90d',
+ value: {
+ type: 'LAST',
+ unit: 'd',
+ interval: 90
+ }
+ },
+ {
+ label: 'filter.timeRange.6m',
+ value: {
+ type: 'LAST',
+ unit: 'M',
+ interval: 6
+ }
+ },
+ {
+ label: 'filter.timeRange.1y',
+ value: {
+ type: 'LAST',
+ unit: 'y',
+ interval: 1
+ }
+ },
+ {
+ label: 'filter.timeRange.2y',
+ value: {
+ type: 'LAST',
+ unit: 'y',
+ interval: 2
+ }
+ },
+ {
+ label: 'filter.timeRange.5y',
+ value: {
+ type: 'LAST',
+ unit: 'y',
+ interval: 5
+ }
+ }
+ ],
+ [
+ {
+ label: 'filter.timeRange.yesterday',
+ value: {
+ type: 'PAST',
+ unit: 'd'
+ }
+ },
+ // TODO implement time range calculation
+ /*
+ {
+ label: 'filter.timeRange.beforeYesterday',
+ value: {
+ type: 'PAST',
+ unit: 'd'
+ }
+ },
+ {
+ label: 'filter.timeRange.thisDayLastWeek',
+ value: {
+ type: 'PAST',
+ unit: 'd'
+ }
+ },
+ */
+ {
+ label: 'filter.timeRange.previousWeek',
+ value: {
+ type: 'PAST',
+ unit: 'w'
+ }
+ },
+ {
+ label: 'filter.timeRange.previousMonth',
+ value: {
+ type: 'PAST',
+ unit: 'M'
+ }
+ },
+ {
+ label: 'filter.timeRange.previousYear',
+ value: {
+ type: 'PAST',
+ unit: 'y'
+ }
+ }
+ ],
+ [
+ {
+ label: 'filter.timeRange.today',
+ value: {
+ type: 'CURRENT',
+ unit: 'd'
+ }
+ },
+ {
+ label: 'filter.timeRange.thisWeek',
+ value: {
+ type: 'CURRENT',
+ unit: 'w'
+ }
+ },
+ {
+ label: 'filter.timeRange.thisMonth',
+ value: {
+ type: 'CURRENT',
+ unit: 'M'
+ }
+ },
+ {
+ label: 'filter.timeRange.thisYear',
+ value: {
+ type: 'CURRENT',
+ unit: 'y'
+ }
+ }
+ ],
+ [
+ {
+ label: 'filter.timeRange.5min',
+ value: {
+ type: 'LAST',
+ unit: 'm',
+ interval: 5
+ }
+ },
+ {
+ label: 'filter.timeRange.15min',
+ value: {
+ type: 'LAST',
+ unit: 'm',
+ interval: 15
+ }
+ },
+ {
+ label: 'filter.timeRange.30min',
+ value: {
+ type: 'LAST',
+ unit: 'm',
+ interval: 30
+ }
+ },
+ {
+ label: 'filter.timeRange.1hr',
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 1
+ }
+ },
+ {
+ label: 'filter.timeRange.3hr',
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 3
+ }
+ },
+ {
+ label: 'filter.timeRange.6hr',
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 6
+ }
+ },
+ {
+ label: 'filter.timeRange.12hr',
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 12
+ }
+ },
+ {
+ label: 'filter.timeRange.24hr',
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 24
+ }
+ },
+ ]
+ ],
+ defaultSelection: {
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 1
+ },
+ label: 'filter.timeRange.1hr'
+ }
+ },
+ components: {
+ label: 'filter.components',
+ iconClass: 'fa fa-cubes',
+ options: [],
+ defaultSelection: []
+ },
+ levels: {
+ label: 'filter.levels',
+ iconClass: 'fa fa-sort-amount-asc',
+ options: [
+ {
+ label: 'levels.fatal',
+ value: 'FATAL'
+ },
+ {
+ label: 'levels.error',
+ value: 'ERROR'
+ },
+ {
+ label: 'levels.warn',
+ value: 'WARN'
+ },
+ {
+ label: 'levels.info',
+ value: 'INFO'
+ },
+ {
+ label: 'levels.debug',
+ value: 'DEBUG'
+ },
+ {
+ label: 'levels.trace',
+ value: 'TRACE'
+ },
+ {
+ label: 'levels.unknown',
+ value: 'UNKNOWN'
+ }
+ ],
+ defaultSelection: []
+ },
+ hosts: {
+ label: 'filter.hosts',
+ iconClass: 'fa fa-server',
+ options: [],
+ defaultSelection: []
+ },
+ sorting: {
+ label: 'sorting.title',
+ options: [
+ {
+ label: 'sorting.time.asc',
+ value: {
+ key: 'logtime',
+ type: 'asc'
+ }
+ },
+ {
+ label: 'sorting.time.desc',
+ value: {
+ key: 'logtime',
+ type: 'desc'
+ }
+ }
+ ],
+ defaultSelection: [
+ {
+ label: 'sorting.time.desc',
+ value: {
+ key: 'logtime',
+ type: 'desc'
+ }
+ }
+ ]
+ },
+ pageSize: {
+ label: 'pagination.title',
+ options: this.paginationOptions.map((option: string): ListItem => {
+ return {
+ label: option,
+ value: option
+ }
+ }),
+ defaultSelection: [
+ {
+ label: '10',
+ value: '10'
+ }
+ ]
+ },
+ page: {
+ defaultSelection: 0
+ },
+ query: {}
+ };
+
+ readonly filtersFormItemsMap: {[key: string]: string[]} = {
+ serviceLogs: ['clusters', 'timeRange', 'components', 'levels', 'hosts', 'sorting', 'pageSize', 'page', 'query'],
+ auditLogs: ['clusters', 'timeRange', 'sorting', 'pageSize', 'page', 'query'] // TODO add all the required fields
+ };
+
readonly colors = {
WARN: '#FF8916',
ERROR: '#E81D1D',
@@ -93,14 +479,71 @@ export class LogsContainerService {
}
};
+ private readonly defaultTimeZone = moment.tz.guess();
+
+ timeZone: string = this.defaultTimeZone;
+
totalCount: number = 0;
+ /**
+ * A configurable property to indicate the maximum capture time in milliseconds.
+ * @type {number}
+ * @default 600000 (10 minutes)
+ */
+ private readonly maximumCaptureTimeLimit: number = 600000;
+
isServiceLogsFileView: boolean = false;
+ filtersForm: FormGroup;
+
activeLog: ActiveServiceLogEntry | null = null;
activeLogsType: string;
+ private filtersFormChange: Subject<any> = new Subject();
+
+ /**
+ * Get instance for dropdown list from string
+ * @param name {string}
+ * @returns {ListItem}
+ */
+ private getListItemFromString(name: string): ListItem {
+ return {
+ label: name,
+ value: name
+ };
+ }
+
+ /**
+ * Get instance for dropdown list from NodeItem object
+ * @param node {NodeItem}
+ * @returns {ListItem}
+ */
+ private getListItemFromNode(node: NodeItem): ListItem {
+ return {
+ label: `${node.name} (${node.value})`,
+ value: node.name
+ };
+ }
+
+ queryParameterNameChange: Subject<any> = new Subject();
+
+ queryParameterAdd: Subject<any> = new Subject();
+
+ private stopTimer: Subject<any> = new Subject();
+
+ private stopAutoRefreshCountdown: Subject<any> = new Subject();
+
+ captureSeconds: number = 0;
+
+ private readonly autoRefreshInterval: number = 30000;
+
+ autoRefreshRemainingSeconds: number = 0;
+
+ private startCaptureTime: number;
+
+ private stopCaptureTime: number;
+
loadLogs = (logsType: string = this.activeLogsType): void => {
this.httpClient.get(logsType, this.getParams('listFilters')).subscribe((response: Response): void => {
const jsonResponse = response.json(),
@@ -128,7 +571,7 @@ export class LogsContainerService {
}
});
}
- }
+ };
loadLogContext(id: string, hostName: string, componentName: string, scrollType: 'before' | 'after' | '' = ''): void {
const params = {
@@ -161,22 +604,18 @@ export class LogsContainerService {
});
}
- private getParams(filtersMapName: string): any {
+ private getParams(filtersMapName: string): {[key: string]: string} {
let params = {};
Object.keys(this[filtersMapName]).forEach((key: string): void => {
- const inputValue = this.filtering.activeFiltersForm.getRawValue()[key],
+ const inputValue = this.filtersForm.getRawValue()[key],
paramNames = this[filtersMapName][key];
- paramNames.forEach(paramName => {
+ paramNames.forEach((paramName: string): void => {
let value;
- const valueGetter = this.filtering.valueGetters[paramName];
- if (valueGetter) {
- if (paramName === 'from') {
- value = valueGetter(inputValue, params['to']);
- } else {
- value = valueGetter(inputValue);
- }
+ const valueGetter = this.valueGetters[paramName] || this.defaultValueGetter;
+ if (paramName === 'from') {
+ value = valueGetter(inputValue, params['to']);
} else {
- value = inputValue;
+ value = valueGetter(inputValue);
}
if (value != null && value !== '') {
params[paramName] = value;
@@ -222,12 +661,197 @@ export class LogsContainerService {
return Object.keys(keysObject).map((key: string): {fieldClass} => new fieldClass(key));
}
+ private getStartTime = (selection: TimeUnitListItem, current: string): string => {
+ let time;
+ const value = selection && selection.value;
+ if (value) {
+ const endTime = moment(moment(current).valueOf());
+ switch (value.type) {
+ case 'LAST':
+ time = endTime.subtract(value.interval, value.unit);
+ break;
+ case 'CURRENT':
+ time = moment().tz(this.timeZone).startOf(value.unit);
+ break;
+ case 'PAST':
+ time = endTime.startOf(value.unit);
+ break;
+ case 'CUSTOM':
+ time = value.start;
+ break;
+ default:
+ break;
+ }
+ }
+ return time ? time.toISOString() : '';
+ };
+
+ private getEndTime = (selection: TimeUnitListItem): string => {
+ let time;
+ const value = selection && selection.value;
+ if (value) {
+ switch (value.type) {
+ case 'LAST':
+ time = moment();
+ break;
+ case 'CURRENT':
+ time = moment().tz(this.timeZone).endOf(value.unit);
+ break;
+ case 'PAST':
+ time = moment().tz(this.timeZone).startOf(value.unit).millisecond(-1);
+ break;
+ case 'CUSTOM':
+ time = value.end;
+ break;
+ default:
+ break;
+ }
+ }
+ return time ? time.toISOString() : '';
+ };
+
+ private getQuery(isExclude: boolean): (value: any[]) => string {
+ return (value: any[]): string => {
+ let parameters;
+ if (value && value.length) {
+ parameters = value.filter(item => item.isExclude === isExclude).map(parameter => {
+ return {
+ [parameter.name]: parameter.value.replace(/\s/g, '+')
+ };
+ });
+ }
+ return parameters && parameters.length ? JSON.stringify(parameters) : '';
+ }
+ }
+
+ private getSortType(selection: SortingListItem[] = []): 'asc' | 'desc' {
+ return selection[0] && selection[0].value ? selection[0].value.type : 'desc';
+ }
+
+ private getSortKey(selection: SortingListItem[] = []): string {
+ return selection[0] && selection[0].value ? selection[0].value.key : '';
+ }
+
+ private getPage(value: number | undefined): string | undefined {
+ return typeof value === 'undefined' ? value : value.toString();
+ }
+
+ private defaultValueGetter(selection: ListItem | ListItem[] | null): string {
+ if (Array.isArray(selection)) {
+ return selection.map((item: ListItem): any => item.value).join(',');
+ } else if (selection) {
+ return selection.value;
+ } else {
+ return '';
+ }
+ }
+
+ private readonly valueGetters = {
+ to: this.getEndTime,
+ from: this.getStartTime,
+ sortType: this.getSortType,
+ sortBy: this.getSortKey,
+ page: this.getPage,
+ includeQuery: this.getQuery(false),
+ excludeQuery: this.getQuery(true)
+ };
+
switchTab(activeTab: Tab): void {
+ this.tabsStorage.mapCollection((tab: Tab): Tab => {
+ return Object.assign({}, tab, {
+ isActive: tab.id === activeTab.id
+ });
+ });
this.appState.setParameters(activeTab.appState);
- this.tabsStorage.mapCollection((tab: Tab): Tab => Object.assign({}, tab, {
- isActive: tab.id === activeTab.id
- }));
- this.loadLogs();
+ }
+
+ startCaptureTimer(): void {
+ this.startCaptureTime = new Date().valueOf();
+ const maxCaptureTimeInSeconds = this.maximumCaptureTimeLimit / 1000;
+ Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe((seconds: number): void => {
+ this.captureSeconds = seconds;
+ if (this.captureSeconds >= maxCaptureTimeInSeconds) {
+ this.stopCaptureTimer();
+ }
+ });
+ }
+
+ stopCaptureTimer(): void {
+ const autoRefreshIntervalSeconds = this.autoRefreshInterval / 1000;
+ this.stopCaptureTime = new Date().valueOf();
+ this.captureSeconds = 0;
+ this.stopTimer.next();
+ this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
+ Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe((seconds: number): void => {
+ this.autoRefreshRemainingSeconds = autoRefreshIntervalSeconds - seconds;
+ if (!this.autoRefreshRemainingSeconds) {
+ this.stopAutoRefreshCountdown.next();
+ this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
+ }
+ });
+ }
+
+ loadClusters(): Observable<Response> {
+ const request = this.httpClient.get('clusters');
+ request.subscribe((response: Response): void => {
+ const clusterNames = response.json();
+ if (clusterNames) {
+ this.filters.clusters.options.push(...clusterNames.map(this.getListItemFromString));
+ this.clustersStorage.addInstances(clusterNames);
+ }
+ });
+ return request;
+ }
+
+ loadComponents(): Observable<Response> {
+ const request = this.httpClient.get('components');
+ request.subscribe((response: Response): void => {
+ const jsonResponse = response.json(),
+ components = jsonResponse && jsonResponse.vNodeList.map((item): NodeItem => Object.assign(item, {
+ value: item.logLevelCount.reduce((currentValue: number, currentItem): number => {
+ return currentValue + Number(currentItem.value);
+ }, 0)
+ }));
+ if (components) {
+ this.filters.components.options.push(...components.map(this.getListItemFromNode));
+ this.componentsStorage.addInstances(components);
+ }
+ });
+ return request;
+ }
+
+ loadHosts(): Observable<Response> {
+ const request = this.httpClient.get('hosts');
+ request.subscribe((response: Response): void => {
+ const jsonResponse = response.json(),
+ hosts = jsonResponse && jsonResponse.vNodeList;
+ if (hosts) {
+ this.filters.hosts.options.push(...hosts.map(this.getListItemFromNode));
+ this.hostsStorage.addInstances(hosts);
+ }
+ });
+ return request;
+ }
+
+ setCustomTimeRange(startTime: number, endTime: number): void {
+ this.filtersForm.controls.timeRange.setValue({
+ label: 'filter.timeRange.custom',
+ value: {
+ type: 'CUSTOM',
+ start: moment(startTime),
+ end: moment(endTime)
+ }
+ });
+ }
+
+ getFiltersData(listType: string): object {
+ const itemsList = this.filtersFormItemsMap[listType],
+ keys = Object.keys(this.filters).filter((key: string): boolean => itemsList.indexOf(key) > -1);
+ return keys.reduce((currentObject: object, key: string): object => {
+ return Object.assign(currentObject, {
+ [key]: this.filters[key].defaultSelection
+ });
+ }, {});
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
index a4a0cf8..23d3726 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
@@ -31,56 +31,273 @@ describe('UtilsService', () => {
expect(service).toBeTruthy();
}));
- describe('#updateMultiSelectValue()', () => {
+ describe('#isEqual()', () => {
const cases = [
{
- currentValue: '',
- value: 'v0',
- isChecked: true,
- result: 'v0',
- title: 'check; no checked items before'
+ valueA: 1,
+ valueB: 1,
+ result: true,
+ title: 'same numbers'
},
{
- currentValue: 'v1,v2',
- value: 'v3',
- isChecked: true,
- result: 'v1,v2,v3',
- title: 'check'
+ valueA: 1,
+ valueB: 2,
+ result: false,
+ title: 'different numbers'
},
{
- currentValue: 'v4,v5',
- value: 'v4',
- isChecked: false,
- result: 'v5',
- title: 'uncheck'
+ valueA: 'a',
+ valueB: 'a',
+ result: true,
+ title: 'same strings'
},
{
- currentValue: 'v6,v7',
- value: 'v6',
- isChecked: true,
- result: 'v6,v7',
- title: 'avoid repeating check action'
+ valueA: 'a',
+ valueB: 'b',
+ result: false,
+ title: 'different strings'
},
{
- currentValue: 'v8,v9',
- value: 'v10',
- isChecked: false,
- result: 'v8,v9',
- title: 'avoid repeating uncheck action'
+ valueA: '1',
+ valueB: 1,
+ result: false,
+ title: 'different types'
},
{
- currentValue: 'v11',
- value: 'v11',
- isChecked: false,
- result: '',
- title: 'uncheck last item'
+ valueA: true,
+ valueB: true,
+ result: true,
+ title: 'same booleans'
+ },
+ {
+ valueA: false,
+ valueB: true,
+ result: false,
+ title: 'different booleans'
+ },
+ {
+ valueA: {},
+ valueB: {},
+ result: true,
+ title: 'empty objects'
+ },
+ {
+ valueA: {
+ p0: 'v0'
+ },
+ valueB: {
+ p0: 'v0'
+ },
+ result: true,
+ title: 'same objects'
+ },
+ {
+ valueA: {
+ p0: 'v0'
+ },
+ valueB: {
+ p0: 'v1'
+ },
+ result: false,
+ title: 'different objects'
+ },
+ {
+ valueA: {
+ p0: {
+ p1: 'v1'
+ }
+ },
+ valueB: {
+ p0: {
+ p1: 'v1'
+ }
+ },
+ result: true,
+ title: 'same objects in depth'
+ },
+ {
+ valueA: {
+ p0: {
+ p1: 'v1'
+ }
+ },
+ valueB: {
+ p0: {
+ p1: 'v2'
+ }
+ },
+ result: false,
+ title: 'different objects in depth'
+ },
+ {
+ valueA: [],
+ valueB: [],
+ result: true,
+ title: 'empty arrays'
+ },
+ {
+ valueA: [1, 'a'],
+ valueB: [1, 'a'],
+ result: true,
+ title: 'same arrays'
+ },
+ {
+ valueA: [1, 'a'],
+ valueB: [1, 'b'],
+ result: false,
+ title: 'different arrays'
+ },
+ {
+ valueA: [1, 1],
+ valueB: [1, 1, 1],
+ result: false,
+ title: 'arrays of different length'
+ },
+ {
+ valueA: [{}],
+ valueB: [{}],
+ result: true,
+ title: 'arrays of empty objects'
+ },
+ {
+ valueA: [
+ {
+ p0: 'v0'
+ }
+ ],
+ valueB: [
+ {
+ p0: 'v0'
+ }
+ ],
+ result: true,
+ title: 'arrays of same objects'
+ },
+ {
+ valueA: [
+ {
+ p0: 'v0'
+ }
+ ],
+ valueB: [
+ {
+ p0: 'v1'
+ }
+ ],
+ result: false,
+ title: 'arrays of different objects'
+ },
+ {
+ valueA: function() {},
+ valueB: function() {},
+ result: true,
+ title: 'same functions'
+ },
+ {
+ valueA: function(a) {
+ return a;
+ },
+ valueB: function(b) {
+ return !b;
+ },
+ result: false,
+ title: 'different functions'
+ },
+ {
+ valueA: new Date(1),
+ valueB: new Date(1),
+ result: true,
+ title: 'same dates'
+ },
+ {
+ valueA: new Date(1),
+ valueB: new Date(2),
+ result: false,
+ title: 'different dates'
+ },
+ {
+ valueA: new RegExp('a'),
+ valueB: new RegExp('a'),
+ result: true,
+ title: 'same regexps'
+ },
+ {
+ valueA: new RegExp('a', 'i'),
+ valueB: new RegExp('a', 'g'),
+ result: false,
+ title: 'same regexps with different flags'
+ },
+ {
+ valueA: new RegExp('a'),
+ valueB: new RegExp('b'),
+ result: false,
+ title: 'different regexps'
+ },
+ {
+ valueA: new Number(1),
+ valueB: new Number(1),
+ result: true,
+ title: 'same number objects'
+ },
+ {
+ valueA: new Number(1),
+ valueB: new Number(2),
+ result: false,
+ title: 'different number objects'
+ },
+ {
+ valueA: new String('a'),
+ valueB: new String('a'),
+ result: true,
+ title: 'same string objects'
+ },
+ {
+ valueA: new String('a'),
+ valueB: new String('b'),
+ result: false,
+ title: 'different string objects'
+ },
+ {
+ valueA: new Boolean(true),
+ valueB: new Boolean(true),
+ result: true,
+ title: 'same boolean objects'
+ },
+ {
+ valueA: new Boolean(true),
+ valueB: new Boolean(false),
+ result: false,
+ title: 'different boolean objects'
+ },
+ {
+ valueA: null,
+ valueB: null,
+ result: true,
+ title: 'null values'
+ },
+ {
+ valueA: undefined,
+ valueB: undefined,
+ result: true,
+ title: 'undefined values'
+ },
+ {
+ valueA: undefined,
+ valueB: null,
+ result: false,
+ title: 'undefined vs null'
}
];
cases.forEach(test => {
- it(test.title, inject([UtilsService], (service: UtilsService) => {
- expect(service.updateMultiSelectValue(test.currentValue, test.value, test.isChecked)).toEqual(test.result);
- }));
+ describe(test.title, () => {
+ it('equality', inject([UtilsService], (service: UtilsService) => {
+ expect(service.isEqual(test.valueA, test.valueB)).toEqual(test.result);
+ }));
+ it('symmetry', inject([UtilsService], (service: UtilsService) => {
+ expect(service.isEqual(test.valueA, test.valueB)).toEqual(service.isEqual(test.valueB, test.valueA));
+ }));
+ });
});
});
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
index 3448dd4..175b585 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
@@ -22,27 +22,56 @@ import * as moment from 'moment-timezone';
@Injectable()
export class UtilsService {
- valueHasChanged(currentValue: any, newValue: any): boolean {
- if (newValue == null) {
+ /**
+ * Comparison of two instances of any data type be value instead of reference
+ * @param valueA
+ * @param valueB
+ * @returns {boolean}
+ */
+ isEqual = (valueA: any, valueB: any): boolean => {
+ if (valueA === valueB) {
+ return true;
+ }
+ if (valueA instanceof Date && valueB instanceof Date) {
+ return valueA.valueOf() === valueB.valueOf();
+ }
+ if ((typeof valueA === 'function' && typeof valueB === 'function') ||
+ (valueA instanceof RegExp && valueB instanceof RegExp) ||
+ (valueA instanceof String && valueB instanceof String) ||
+ (valueA instanceof Number && valueB instanceof Number) ||
+ (valueA instanceof Boolean && valueB instanceof Boolean)) {
+ return valueA.toString() === valueB.toString();
+ }
+ if (!(valueA instanceof Object) || !(valueB instanceof Object)) {
return false;
}
- if (typeof newValue === 'object') {
- return JSON.stringify(currentValue) !== JSON.stringify(newValue);
- } else {
- return currentValue !== newValue;
+ if (valueA.constructor !== valueB.constructor) {
+ return false;
}
- }
-
- updateMultiSelectValue(currentValue: string, value: string, isChecked: boolean): string {
- let valuesArray = currentValue ? currentValue.split(',') : [],
- valuePosition = valuesArray.indexOf(value);
- if (isChecked && valuePosition === -1) {
- valuesArray.push(value);
- } else if (!isChecked && valuePosition > -1) {
- valuesArray.splice(valuePosition, 1);
- }
- return valuesArray.join(',');
- }
+ if (valueA.isPrototypeOf(valueB) || valueB.isPrototypeOf(valueA)) {
+ return false;
+ }
+ for (const key in valueA) {
+ if (!valueA.hasOwnProperty(key)) {
+ continue;
+ }
+ if (!valueB.hasOwnProperty(key)) {
+ return false;
+ }
+ if (valueA[key] === valueB[key]) {
+ continue;
+ }
+ if (typeof valueA[key] !== 'object' || !this.isEqual(valueA[key], valueB[key])) {
+ return false;
+ }
+ }
+ for (const key in valueB) {
+ if (valueB.hasOwnProperty(key) && !valueA.hasOwnProperty(key)) {
+ return false;
+ }
+ }
+ return true;
+ };
isEnterPressed(event: KeyboardEvent): boolean {
return event.keyCode === 13;
[29/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC
integration [addendum - fix unit tests] (rlevas)
Posted by nc...@apache.org.
AMBARI-22293. Improve KDC integration [addendum - fix unit tests] (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/08d38265
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/08d38265
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/08d38265
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 08d382652052172aeb15082a919a18666de93eb7
Parents: 0f67d1c
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Nov 8 12:26:00 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Nov 8 12:26:00 2017 -0500
----------------------------------------------------------------------
.../KDCKerberosOperationHandlerTest.java | 22 +++++++++++++++++---
.../MITKerberosOperationHandlerTest.java | 6 +++---
2 files changed, 22 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/08d38265/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
index 271c787..095b92a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
@@ -19,7 +19,9 @@
package org.apache.ambari.server.serveraction.kerberos;
import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.getCurrentArguments;
import java.lang.reflect.Method;
import java.util.Map;
@@ -27,6 +29,7 @@ import java.util.Map;
import org.apache.ambari.server.utils.ShellCommandUtil;
import org.apache.commons.lang.StringUtils;
import org.easymock.EasyMock;
+import org.easymock.IAnswer;
import org.easymock.IArgumentMatcher;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -37,9 +40,12 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
static Method methodExecuteCommand;
+ static Method methodGetExecutable;
+
@BeforeClass
public static void beforeKDCKerberosOperationHandlerTest() throws Exception {
methodExecuteCommand = KDCKerberosOperationHandler.class.getDeclaredMethod("executeCommand", String[].class, Map.class, ShellCommandUtil.InteractiveHandler.class);
+ methodGetExecutable = KerberosOperationHandler.class.getDeclaredMethod("getExecutable", String.class);
}
@Test
@@ -66,7 +72,17 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
@Override
protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
- return createMockedHandler(methodExecuteCommand);
+ KDCKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand, methodGetExecutable);
+
+ expect(handler.getExecutable(anyString()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = getCurrentArguments();
+ return args[0].toString();
+ }
+ }).anyTimes();
+ return handler;
}
@Override
@@ -74,7 +90,7 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
expect(result.isSuccessful()).andReturn(true);
- expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ expect(handler.executeCommand(arrayContains("kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
.andReturn(result)
.anyTimes();
}
@@ -87,7 +103,7 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
expect(result.getStdout()).andReturn("STDOUT data").once();
expect(result.getStderr()).andReturn("STDERR data").once();
- expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ expect(handler.executeCommand(arrayContains("kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
.andReturn(result)
.anyTimes();
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/08d38265/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
index 848d479..f94adbe 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
@@ -275,7 +275,7 @@ public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandler
.andReturn("Authenticating as principal admin/admin with password.")
.anyTimes();
- expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "add_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ expect(handler.executeCommand(arrayContains(new String[]{"kadmin", "add_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
.andReturn(result)
.anyTimes();
}
@@ -292,7 +292,7 @@ public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandler
.andReturn("Authenticating as principal admin/admin with password.")
.anyTimes();
- expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ expect(handler.executeCommand(arrayContains(new String[]{"kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
.andReturn(result)
.anyTimes();
}
@@ -329,7 +329,7 @@ public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandler
"Policy: [none]", (service) ? "service/host" : "user"))
.anyTimes();
- expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ expect(handler.executeCommand(arrayContains(new String[]{"kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
.andReturn(result)
.anyTimes();
}
[26/51] [abbrv] ambari git commit: AMBARI-22372. DLM install failed
on an unsecure upgraded cluster, due to missing configs. (Jaimin via Ishan)
Posted by nc...@apache.org.
AMBARI-22372. DLM install failed on an unsecure upgraded cluster, due to missing configs. (Jaimin via Ishan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b8004df0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b8004df0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b8004df0
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: b8004df033be9b7ace43bf2d28820cf93e8bc4db
Parents: dd0421a
Author: Ishan Bhatt <is...@gmail.com>
Authored: Tue Nov 7 10:56:05 2017 -0800
Committer: Ishan Bhatt <is...@gmail.com>
Committed: Tue Nov 7 10:56:05 2017 -0800
----------------------------------------------------------------------
.../HIVE/0.12.0.2.0/configuration/hive-site.xml | 38 ++++++++++++++++++++
1 file changed, 38 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8004df0/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
index 762530b..5520c10 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
@@ -480,6 +480,12 @@ limitations under the License.
<value-attributes>
<empty-value-valid>true</empty-value-valid>
</value-attributes>
+ <depends-on>
+ <property>
+ <type>beacon-env</type>
+ <name>set_hive_configs</name>
+ </property>
+ </depends-on>
<on-ambari-upgrade add="false"/>
</property>
<property>
@@ -489,6 +495,12 @@ limitations under the License.
<value-attributes>
<empty-value-valid>true</empty-value-valid>
</value-attributes>
+ <depends-on>
+ <property>
+ <type>beacon-env</type>
+ <name>set_hive_configs</name>
+ </property>
+ </depends-on>
<on-ambari-upgrade add="false"/>
</property>
<property>
@@ -498,6 +510,12 @@ limitations under the License.
<value-attributes>
<empty-value-valid>true</empty-value-valid>
</value-attributes>
+ <depends-on>
+ <property>
+ <type>beacon-env</type>
+ <name>set_hive_configs</name>
+ </property>
+ </depends-on>
<on-ambari-upgrade add="false"/>
</property>
<property>
@@ -507,6 +525,16 @@ limitations under the License.
<value-attributes>
<empty-value-valid>true</empty-value-valid>
</value-attributes>
+ <depends-on>
+ <property>
+ <type>beacon-env</type>
+ <name>set_hive_configs</name>
+ </property>
+ <property>
+ <type>hive-site</type>
+ <name>hive.metastore.warehouse.dir</name>
+ </property>
+ </depends-on>
<on-ambari-upgrade add="false"/>
</property>
<property>
@@ -516,6 +544,16 @@ limitations under the License.
<value-attributes>
<empty-value-valid>true</empty-value-valid>
</value-attributes>
+ <depends-on>
+ <property>
+ <type>beacon-env</type>
+ <name>set_hive_configs</name>
+ </property>
+ <property>
+ <type>hive-site</type>
+ <name>hive.metastore.warehouse.dir</name>
+ </property>
+ </depends-on>
<on-ambari-upgrade add="false"/>
</property>
</configuration>
[19/51] [abbrv] ambari git commit: AMBARI-22374 Log Search UI: button
with caret doesn't toggle dropdown is some cases. (Istvan Tobias via
ababiichuk)
Posted by nc...@apache.org.
AMBARI-22374 Log Search UI: button with caret doesn't toggle dropdown is some cases. (Istvan Tobias via ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f74b2f87
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f74b2f87
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f74b2f87
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: f74b2f873b147e7c5639e2a342fc0627b8335f47
Parents: ec3f1e4
Author: Istvan Tobias <to...@gmail.com>
Authored: Tue Nov 7 15:27:38 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Tue Nov 7 15:27:38 2017 +0200
----------------------------------------------------------------------
.../menu-button/menu-button.component.html | 17 +--
.../menu-button/menu-button.component.less | 22 ++-
.../menu-button/menu-button.component.ts | 144 ++++++++++++++++---
3 files changed, 154 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f74b2f87/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
index ca70927..5e2b15f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
@@ -15,14 +15,15 @@
limitations under the License.
-->
-<div #dropdown [ngClass]="{'dropdown': hasSubItems, 'text-center': true}">
- <a [ngClass]="iconClass + ' icon'" (mousedown)="onMouseDown($event)" (mouseup)="onMouseUp($event)"
- (click)="$event.stopPropagation()"></a>
- <a #dropdownToggle class="dropdown-toggle caret" data-toggle="dropdown" *ngIf="hasCaret"></a>
- <br>
- <a *ngIf="label" (mousedown)="onMouseDown($event)" [ngClass]="labelClass" (mouseup)="onMouseUp($event)"
- (click)="$event.stopPropagation()">{{label}}</a>
- <ul data-component="dropdown-list" *ngIf="hasSubItems" [items]="subItems" (selectedItemChange)="updateValue($event)"
+<div #dropdown [ngClass]="{'dropdown': hasSubItems, 'text-center': true, 'open': dropdownIsOpen}">
+ <a class="dropdown-toggle" [ngClass]="(labelClass || '') + (hasCaret ? ' has-caret' : '')"
+ (click)="onMouseClick($event)"
+ (mousedown)="onMouseDown($event)">
+ <i *ngIf="iconClass" [ngClass]="['icon', iconClass]"></i>
+ <i *ngIf="hasCaret" [ngClass]="['fa ', caretClass ]"></i>
+ <span *ngIf="label" class="menu-button-label">{{label}}</span>
+ </a>
+ <ul data-component="dropdown-list" *ngIf="hasSubItems" [items]="subItems" (selectedItemChange)="onDropdownItemChange($event)"
[isMultipleChoice]="isMultipleChoice" [additionalLabelComponentSetter]="additionalLabelComponentSetter"
[ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}"></ul>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f74b2f87/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
index 615db24..0207561 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
@@ -21,14 +21,26 @@
cursor: pointer;
display: inline-block;
position: relative;
- a:hover, a:focus {
+ a {
+ text-align: center;
text-decoration: none;
+ i {
+ color: @link-color;
+ display: inline-block;
+ position: relative;
+ &.fa-caret-down {
+ padding: 0 .25em;
+ }
+ }
+ .menu-button-label {
+ display: block;
+ }
}
-
- .icon {
- padding: @icon-padding;
+ a:hover, a:focus {
+ i {
+ color: @link-hover-color;
+ }
}
-
.unstyled-link {
color: inherit;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f74b2f87/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
index 0aa7c7e..5932e1b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
@@ -19,7 +19,6 @@
import {Component, Input, ViewChild, ElementRef} from '@angular/core';
import {ListItem} from '@app/classes/list-item';
import {ComponentActionsService} from '@app/services/component-actions.service';
-import * as $ from 'jquery';
@Component({
selector: 'menu-button',
@@ -64,6 +63,37 @@ export class MenuButtonComponent {
@Input()
badge: string;
+ @Input()
+ caretClass: string = 'fa-caret-down';
+
+ /**
+ * The minimum time to handle a mousedown as a longclick. Default is 500 ms (0.5sec)
+ * @default 500
+ * @type {number}
+ */
+ @Input()
+ minLongClickDelay: number = 500;
+
+ /**
+ * The maximum milliseconds to wait for longclick ends. The default is 0 which means no upper limit.
+ * @default 0
+ * @type {number}
+ */
+ @Input()
+ maxLongClickDelay: number = 0;
+
+ /**
+ * This is a private property to indicate the mousedown timestamp, so that we can check it when teh click event
+ * has been triggered.
+ */
+ private mouseDownTimestamp: number;
+
+ /**
+ * Indicates if the dropdown list is open or not. So that we use internal state to display or hide the dropdown.
+ * @type {boolean}
+ */
+ private dropdownIsOpen: boolean = false;
+
get hasSubItems(): boolean {
return Boolean(this.subItems && this.subItems.length);
}
@@ -72,26 +102,108 @@ export class MenuButtonComponent {
return this.hasSubItems && !this.hideCaret;
}
- private clickStartTime: number;
-
- private readonly longClickInterval = 1000;
-
- onMouseDown(event: MouseEvent): void {
- if (this.action && event.button === 0) {
- this.clickStartTime = (new Date()).getTime();
+ /**
+ * Handling the click event on the component element.
+ * Two goal:
+ * - check if we have a 'longclick' event and open the dropdown (if any) when longclick event happened
+ * - trigger the action or the dropdown open depending on the target element (caret will open the dropdown otherwise
+ * trigger the action.
+ * @param {MouseEvent} event
+ */
+ onMouseClick(event: MouseEvent): void {
+ let el = <HTMLElement>event.target;
+ let now = Date.now();
+ let mdt = this.mouseDownTimestamp; // mousedown time
+ let isLongClick = mdt && mdt + this.minLongClickDelay <= now && (
+ !this.maxLongClickDelay || mdt + this.maxLongClickDelay >= now
+ );
+ let openDropdown = this.hasSubItems && (
+ el.classList.contains(this.caretClass) || isLongClick || !this.actions[this.action]
+ );
+ if (openDropdown && this.dropdown) {
+ if (this.toggleDropdown()) {
+ this.listenToClickOut();
+ }
+ } else if (this.action) {
+ this.actions[this.action]();
}
+ this.mouseDownTimestamp = 0;
+ event.preventDefault();
}
- onMouseUp(event: MouseEvent): void {
- if (event.button === 0) {
- const clickEndTime = (new Date()).getTime();
- if (this.hasSubItems && (!this.action || clickEndTime - this.clickStartTime >= this.longClickInterval)) {
- $(this.dropdown.nativeElement).toggleClass('open');
- } else if (this.action) {
- this.actions[this.action]();
+ /**
+ * Listening the click event on the document so that we can hide our dropdown list if the event source is not the
+ * component.
+ */
+ private listenToClickOut = (): void => {
+ this.dropdownIsOpen && document.addEventListener('click', this.onDocumentMouseClick);
+ };
+
+ /**
+ * Handling the click event on the document to hide the dropdown list if it needs.
+ * @param {MouseEvent} event
+ */
+ private onDocumentMouseClick = (event: MouseEvent): void => {
+ let el = <HTMLElement>event.target;
+ if (!this.dropdown.nativeElement.contains(el)) {
+ this.closeDropdown();
+ this.removeDocumentClickListener()
+ }
+ };
+
+ /**
+ * Handling the mousedown event, so that we can check the long clicks and open the dropdown if any.
+ * @param {MouseEvent} event
+ */
+ onMouseDown = (event: MouseEvent): void => {
+ if (this.hasSubItems) {
+ let el = <HTMLElement>event.target;
+ if (!el.classList.contains(this.caretClass)) {
+ this.mouseDownTimestamp = Date.now();
}
- event.stopPropagation();
}
+ };
+
+ /**
+ * The goal is to have one and only one place where we open the dropdown. So that later if we need to change the way
+ * how we do, it will be easier.
+ */
+ private openDropdown():void {
+ this.dropdownIsOpen = true;
+ }
+
+ /**
+ * The goal is to have one and only one place where we close the dropdown. So that later if we need to change the way
+ * how we do, it will be easier.
+ */
+ private closeDropdown():void {
+ this.dropdownIsOpen = false;
+ }
+
+ /**
+ * Just a simple helper method to make the dropdown toggle more easy.
+ * @returns {boolean} It will return the open state of the dropdown;
+ */
+ private toggleDropdown(): boolean {
+ this[this.dropdownIsOpen ? 'closeDropdown' : 'openDropdown']();
+ return this.dropdownIsOpen;
+ }
+
+ /**
+ * The goal is to simply remove the click event listeners from the document.
+ */
+ private removeDocumentClickListener(): void {
+ document.removeEventListener('click', this.onDocumentMouseClick);
+ }
+
+ /**
+ * The main goal if this function is tho handle the item change event on the child dropdown list.
+ * Should update the value and close the dropdown if it is not multiple choice type.
+ * @param {ListItem} options The selected item(s) from the dropdown list.
+ */
+ onDropdownItemChange(options: ListItem) {
+ this.updateValue(options);
+ !this.isMultipleChoice && this.closeDropdown();
}
updateValue(options: ListItem) {
[07/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement
new design for Admin View. (atkach)
Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf
new file mode 100644
index 0000000..305f0d5
Binary files /dev/null and b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf differ
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff
new file mode 100644
index 0000000..ac7452a
Binary files /dev/null and b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff differ
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index 52e41f6..e9983aa 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -44,53 +44,47 @@
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
-<div id="top-nav" ng-controller="MainCtrl">
- <header class="navbar navbar-static-top navbar-inverse">
- <div class="navbar-inner">
- <div class="container">
- <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="logo"><img src="/img/ambari-logo.png" alt="{{'common.apacheAmbari' | translate}}" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-logo"></a>
- <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="brand" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-title">{{'common.ambari' | translate}}</a>
- <ul class="nav navbar-nav navbar-right">
- <li>
- <div class="btn-group navbar-views-dropdown" dropdown is-open="viewsdropdown.isopen" ng-mouseover="viewsdropdown.isopen=true" ng-mouseout="viewsdropdown.isopen=false">
- <a href="{{fromSiteRoot('/#/main/views')}}" ng-click="gotoViewsDashboard()" class="dropdown-toggle"><i class="fa fa-th"></i></a>
- <ul class="dropdown-menu" role="menu">
- <li ng-repeat="instance in viewInstances"><a href="{{fromSiteRoot('/#/main/views/' + instance.viewUrl)}}" target="_blank">{{instance.label}}</a></li>
- <li ng-show="!viewInstances.length" class="disabled"><a>{{'common.noViews' | translate}}</a></li>
- </ul>
- </div>
- </li>
- <li>
- <div class="btn-group" dropdown is-open="status.isopen">
- <button type="button" class="btn btn-default dropdown-toggle navbar-btn" ng-disabled="disabled">
- <i class="fa fa-user"></i> {{currentUser}} <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu">
- <li><a href ng-click="about()">{{'common.about' | translate}}</a></li>
- <li class="divider"></li>
- <li><a href ng-click="signOut()">{{'common.signOut' | translate}}</a></li>
- </ul>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </header>
-</div>
+<div id="wrapper" ng-controller="AppCtrl">
+ <div ng-include="'views/sideNav.html'" ng-controller="SideNavCtrl"></div>
-<div class="container">
- <div class="row">
- <div class="col-sm-3">
- <div ng-include="'views/leftNavbar.html'" ng-controller="NavbarCtrl"></div>
+ <div id="main">
+ <div id="top-nav">
+ <nav class="navbar navbar-default navbar-static-top">
+ <div class="container">
+ <div class="navbar-header navbar-nav">
+ <ol class="breadcrumb">
+ <li ng-repeat="breadcrumb in breadcrumbs" ng-class="$last && 'active'">{{breadcrumb}}</li>
+ </ol>
+ </div>
+ <ul class="nav navbar-nav navbar-right">
+ <li>
+ <p class="navbar-text">{{cluster.Clusters.cluster_name}}</p>
+ </li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" ng-disabled="disabled">
+ <i class="fa fa-user"></i> {{currentUser}} <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu">
+ <li><a href ng-click="about()">{{'common.about' | translate}}</a></li>
+ <li role="separator" class="divider"></li>
+ <li><a href ng-click="signOut()">{{'common.signOut' | translate}}</a></li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </nav>
</div>
- <div class="col-sm-9">
- <ng-view></ng-view>
+ <div class="container main-container">
+ <div class="row">
+ <div class="col-sm-12">
+ <ng-view></ng-view>
+ </div>
+ </div>
</div>
</div>
</div>
-
<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
@@ -119,6 +113,7 @@
<script src="bower_components/bootstrap/js/scrollspy.js"></script>
<script src="bower_components/bootstrap/js/collapse.js"></script>
<script src="bower_components/bootstrap/js/tab.js"></script>
+<script src="scripts/theme/bootstrap-ambari.js"></script>
<!-- endbuild -->
@@ -127,7 +122,8 @@
<script src="scripts/routes.js"></script>
<script src="scripts/i18n.config.js"></script>
<script src="scripts/controllers/mainCtrl.js"></script>
-<script src="scripts/controllers/NavbarCtrl.js"></script>
+<script src="scripts/controllers/AppCtrl.js"></script>
+<script src="scripts/controllers/SideNavCtrl.js"></script>
<script src="scripts/controllers/authentication/AuthenticationMainCtrl.js"></script>
<script src="scripts/controllers/loginActivities/LoginActivitiesMainCtrl.js"></script>
<script src="scripts/controllers/loginActivities/LoginMessageMainCtrl.js"></script>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
new file mode 100644
index 0000000..4ac5b38
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
@@ -0,0 +1,177 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('AppCtrl',['$scope','$rootScope', '$route', '$window','Auth', 'Alert', '$modal', 'Cluster', '$translate', '$http', 'Settings', 'Utility', '$q', function($scope, $rootScope, $route, $window, Auth, Alert, $modal, Cluster, $translate, $http, Settings, Utility, $q) {
+ var $t = $translate.instant;
+ $scope.signOut = function () {
+ Auth.signout().finally(function () {
+ $window.location.pathname = Settings.siteRoot;
+ });
+ };
+
+ //todo replace with breadcrumb service
+ $scope.$watch(function () {
+ return $route.current;
+ }, function (value) {
+ var breadcrumbs = [$t('common.admin')];
+ if (value && value.$$route.label) {
+ breadcrumbs.push(value.$$route.label);
+ }
+ $scope.breadcrumbs = breadcrumbs;
+ });
+
+
+ $scope.ambariVersion = null;
+ $rootScope.supports = {};
+ $rootScope.authDataLoad = $q.defer();
+
+ Utility.getUserPref('user-pref-' + Auth.getCurrentUser() + '-supports').then(function (data) {
+ $rootScope.supports = data.data ? data.data : {};
+ });
+
+ $http.get(Settings.baseUrl + '/users/' + Auth.getCurrentUser() + '/authorizations?fields=*')
+ .then(function (data) {
+ var auth = !!data.data && !!data.data.items ? data.data.items.map(function (a) {
+ return a.AuthorizationInfo.authorization_id;
+ }) : [],
+ canPersistData = auth.indexOf('CLUSTER.MANAGE_USER_PERSISTED_DATA') > -1;
+ $rootScope.authDataLoad.resolve(canPersistData);
+ if (auth.indexOf('AMBARI.RENAME_CLUSTER') == -1) {
+ $window.location = $rootScope.fromSiteRoot("/#/main/dashboard");
+ }
+ });
+
+ $scope.about = function () {
+ var ambariVersion = $scope.ambariVersion;
+ var modalInstance = $modal.open({
+ templateUrl: 'views/modals/AboutModal.html',
+ controller: ['$scope', function ($scope) {
+ $scope.ok = function () {
+ modalInstance.close();
+ };
+ $scope.ambariVersion = ambariVersion;
+ }]
+ });
+ };
+
+ $scope.currentUser = Auth.getCurrentUser();
+
+ $scope.cluster = null;
+ $scope.isLoaded = null;
+
+ function loadAmbariVersion() {
+ Cluster.getAmbariVersion().then(function (version) {
+ $scope.ambariVersion = version;
+ });
+ }
+
+ function loadClusterData() {
+ Cluster.getStatus().then(function (cluster) {
+ $rootScope.cluster = cluster;
+ $scope.cluster = cluster;
+ $scope.isLoaded = true;
+ if (cluster && cluster.Clusters.provisioning_state === 'INIT') {
+ setTimeout(loadClusterData, 1000);
+ }
+ }).catch(function (data) {
+ Alert.error($t('common.alerts.cannotLoadClusterStatus'), data.statusText);
+ });
+ }
+
+ loadClusterData();
+ loadAmbariVersion();
+
+ $scope.startInactiveTimeoutMonitoring = function (timeout) {
+ var TIME_OUT = timeout;
+ var active = true;
+ var lastActiveTime = Date.now();
+
+ var keepActive = function () {
+ if (active) {
+ lastActiveTime = Date.now();
+ }
+ };
+
+ $(window).bind('mousemove', keepActive);
+ $(window).bind('keypress', keepActive);
+ $(window).bind('click', keepActive);
+
+ var checkActiveness = function () {
+ var remainTime = TIME_OUT - (Date.now() - lastActiveTime);
+ if (remainTime < 0) {
+ active = false;
+ $(window).unbind('mousemove', keepActive);
+ $(window).unbind('keypress', keepActive);
+ $(window).unbind('click', keepActive);
+ clearInterval($rootScope.userActivityTimeoutInterval);
+ $scope.signOut();
+ } else if (remainTime < 60000 && !$rootScope.timeoutModal) {
+ $rootScope.timeoutModal = $modal.open({
+ templateUrl: 'views/modals/TimeoutWarning.html',
+ backdrop: false,
+ controller: ['$scope', 'Auth', function ($scope, Auth) {
+ $scope.remainTime = 60;
+ $scope.title = $t('main.autoLogOut');
+ $scope.primaryText = $t('main.controls.remainLoggedIn');
+ $scope.secondaryText = $t('main.controls.logOut');
+ $scope.remain = function () {
+ $rootScope.timeoutModal.close();
+ delete $rootScope.timeoutModal;
+ };
+ $scope.logout = function () {
+ $rootScope.timeoutModal.close();
+ delete $rootScope.timeoutModal;
+ Auth.signout().finally(function () {
+ $window.location.pathname = Settings.siteRoot;
+ });
+ };
+ $scope.countDown = function () {
+ $scope.remainTime--;
+ $scope.$apply();
+ if ($scope.remainTime == 0) {
+ Auth.signout().finally(function () {
+ $window.location.pathname = Settings.siteRoot;
+ });
+ }
+ };
+ setInterval($scope.countDown, 1000);
+ }]
+ });
+ }
+ };
+ $rootScope.userActivityTimeoutInterval = window.setInterval(checkActiveness, 1000);
+ };
+
+ // Send noop requests every 10 seconds just to keep backend session alive
+ $scope.startNoopPolling = function () {
+ $rootScope.noopPollingInterval = setInterval(Cluster.getAmbariTimeout, 10000);
+ };
+
+ if (!$rootScope.userActivityTimeoutInterval) {
+ Cluster.getAmbariTimeout().then(function (timeout) {
+ $rootScope.userTimeout = Number(timeout) * 1000;
+ if ($rootScope.userTimeout > 0)
+ $scope.startInactiveTimeoutMonitoring($rootScope.userTimeout);
+ });
+ }
+ if (!$rootScope.noopPollingInterval) {
+ $scope.startNoopPolling();
+ }
+}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js
deleted file mode 100644
index cbf38e8..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-'use strict';
-
-angular.module('ambariAdminConsole')
-.controller('NavbarCtrl',['$scope', 'Cluster', '$location', 'Alert', 'ROUTES', 'ConfirmationModal', '$rootScope', 'Stack', '$translate', 'Settings', function($scope, Cluster, $location, Alert, ROUTES, ConfirmationModal, $rootScope, Stack, $translate, Settings) {
- var $t = $translate.instant;
- $scope.cluster = null;
- $scope.totalRepos = 0;
- $scope.editCluster = {
- name : '',
- editingName : false
- };
- $scope.settings = Settings;
-
- function loadClusterData() {
- Cluster.getStatus().then(function (cluster) {
- $scope.cluster = cluster;
- Stack.allRepos({version: '',
- cluster: {
- options: [],
- current: null
- }}, {}).then(function (repos) {
- $scope.totalRepos = repos.itemTotal;
- });
- if (cluster && cluster.Clusters.provisioning_state === 'INIT') {
- setTimeout(loadClusterData, 1000);
- }
- }).catch(function (data) {
- Alert.error($t('common.alerts.cannotLoadClusterStatus'), data.statusText);
- });
- }
- loadClusterData();
-
- $scope.toggleEditName = function($event) {
- if ($event && $event.keyCode !== 27) {
- // 27 = Escape key
- return false;
- }
-
- $scope.editCluster.name = $scope.cluster.Clusters.cluster_name;
- $scope.editCluster.editingName = !$scope.editCluster.editingName;
- };
-
- $scope.clusterDisplayName = function () {
- var name="";
- if($scope.cluster && $scope.cluster.Clusters)
- {
- name = $scope.cluster.Clusters.cluster_name;
- }
- return name.length > 13 ? name.substr(0, 13) + "..." : name;
- };
-
- $scope.confirmClusterNameChange = function() {
- ConfirmationModal.show(
- $t('common.clusterNameChangeConfirmation.title'),
- $t('common.clusterNameChangeConfirmation.message', {
- clusterName: $scope.editCluster.name
- })
- )
- .then(function() {
- $scope.saveClusterName();
- }).catch(function() {
- // user clicked cancel
- $scope.toggleEditName();
- });
- };
-
- $scope.saveClusterName = function() {
- var oldClusterName = $scope.cluster.Clusters.cluster_name,
- newClusterName = $scope.editCluster.name;
-
- Cluster.editName(oldClusterName, newClusterName).then(function(data) {
- $scope.cluster.Clusters.cluster_name = newClusterName;
- Alert.success($t('common.alerts.clusterRenamed', {clusterName: newClusterName}));
- }).catch(function(data) {
- Alert.error($t('common.alerts.cannotRenameCluster', {clusterName: newClusterName}), data.data.message);
- });
-
- $scope.toggleEditName();
- };
-
- $scope.isActive = function(path) {
- var route = ROUTES;
- angular.forEach(path.split('.'), function(routeObj) {
- route = route[routeObj];
- });
- var r = new RegExp( route.url.replace(/(:\w+)/, '\\w+'));
- return r.test($location.path());
- };
-}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
new file mode 100644
index 0000000..558d110
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('SideNavCtrl', ['$scope', '$location', 'ROUTES', '$rootScope', 'Stack', 'Settings', function($scope, $location, ROUTES, $rootScope, Stack, Settings) {
+ $scope.totalRepos = 0;
+ $scope.settings = Settings;
+
+ $scope.$watch(function() {
+ return $rootScope.cluster;
+ }, function() {
+ $scope.cluster = $rootScope.cluster;
+ }, true);
+
+ function loadRepos() {
+ Stack.allRepos({version: '',
+ cluster: {
+ options: [],
+ current: null
+ }}, {}).then(function (repos) {
+ $scope.totalRepos = repos.itemTotal;
+ });
+ }
+
+ function initNavigationBar () {
+ $('body').on('DOMNodeInserted', '.navigation-bar', function() {
+ $('.navigation-bar').navigationBar({
+ fitHeight: true,
+ collapseNavBarClass: 'fa-angle-double-left',
+ expandNavBarClass: 'fa-angle-double-right'
+ });
+ //initTooltips();
+ $('body').off('DOMNodeInserted', '.navigation-bar');
+ });
+ }
+
+ function initTooltips () {
+ $('[rel="tooltip"]').tooltip();
+ }
+
+ initNavigationBar();
+ loadRepos();
+
+ $scope.isActive = function(path) {
+ var route = ROUTES;
+ angular.forEach(path.split('.'), function(routeObj) {
+ route = route[routeObj];
+ });
+ var r = new RegExp( route.url.replace(/(:\w+)/, '\\w+'));
+ return r.test($location.path());
+ };
+}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
index c945644..30f7568 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
@@ -18,166 +18,10 @@
'use strict';
angular.module('ambariAdminConsole')
-.controller('MainCtrl',['$scope','$rootScope','$window','Auth', 'Alert', '$modal', 'Cluster', 'View', '$translate', '$http', 'Settings', 'Utility', '$q', function($scope, $rootScope, $window, Auth, Alert, $modal, Cluster, View, $translate, $http, Settings, Utility, $q) {
- var $t = $translate.instant;
- $scope.signOut = function() {
- Auth.signout().finally(function() {
- $window.location.pathname = Settings.siteRoot;
- });
- };
-
- $scope.ambariVersion = null;
- $rootScope.supports = {};
- $rootScope.authDataLoad = $q.defer();
-
- Utility.getUserPref('user-pref-' + Auth.getCurrentUser() + '-supports').then(function(data) {
- $rootScope.supports = data.data ? data.data : {};
- });
-
- $http.get(Settings.baseUrl + '/users/' + Auth.getCurrentUser() + '/authorizations?fields=*')
- .then(function(data) {
- var auth = !!data.data && !!data.data.items ? data.data.items.map(function (a) {
- return a.AuthorizationInfo.authorization_id;
- }) : [],
- canPersistData = auth.indexOf('CLUSTER.MANAGE_USER_PERSISTED_DATA') > -1;
- $rootScope.authDataLoad.resolve(canPersistData);
- if(auth.indexOf('AMBARI.RENAME_CLUSTER') == -1) {
- $window.location = $rootScope.fromSiteRoot("/#/main/dashboard");
- }
- });
-
- $scope.about = function() {
- var ambariVersion = $scope.ambariVersion;
- var modalInstance = $modal.open({
- templateUrl:'views/modals/AboutModal.html',
- controller: ['$scope', function($scope) {
- $scope.ok = function() {
- modalInstance.close();
- };
- $scope.ambariVersion = ambariVersion;
- }]
- });
- };
-
- $scope.currentUser = Auth.getCurrentUser();
-
- $scope.cluster = null;
- $scope.isLoaded = null;
-
- function loadAmbariVersion() {
- Cluster.getAmbariVersion().then(function(version){
- $scope.ambariVersion = version;
- });
- }
-
- function loadClusterData(){
- Cluster.getStatus().then(function(cluster) {
- $scope.cluster = cluster;
- $scope.isLoaded = true;
- if(cluster && cluster.Clusters.provisioning_state === 'INIT'){
- setTimeout(loadClusterData, 1000);
- }
- }).catch(function(data) {
- Alert.error($t('common.alerts.cannotLoadClusterStatus'), data.statusText);
- });
- }
- loadClusterData();
- loadAmbariVersion();
-
- $scope.viewInstances = [];
-
- $scope.updateInstances = function () {
- View.getAllVisibleInstance().then(function(instances) {
- $scope.viewInstances = instances.map(function(i) {
- i.viewUrl = i.view_name + '/' + i.version + '/' + i.instance_name;
- return i;
- });
- });
- };
-
- $scope.gotoViewsDashboard =function() {
- window.location = Settings.siteRoot + '#/main/views';
- };
-
- $scope.$root.$on('instancesUpdate', function (event, data) {
- $scope.updateInstances();
- });
-
- $scope.startInactiveTimeoutMonitoring = function(timeout) {
- var TIME_OUT = timeout;
- var active = true;
- var lastActiveTime = Date.now();
-
- var keepActive = function() {
- if (active) {
- lastActiveTime = Date.now();
- }
- };
-
- $(window).bind('mousemove', keepActive);
- $(window).bind('keypress', keepActive);
- $(window).bind('click', keepActive);
-
- var checkActiveness = function() {
- var remainTime = TIME_OUT - (Date.now() - lastActiveTime);
- if (remainTime < 0) {
- active = false;
- $(window).unbind('mousemove', keepActive);
- $(window).unbind('keypress', keepActive);
- $(window).unbind('click', keepActive);
- clearInterval($rootScope.userActivityTimeoutInterval);
- $scope.signOut();
- } else if (remainTime < 60000 && !$rootScope.timeoutModal) {
- $rootScope.timeoutModal = $modal.open({
- templateUrl: 'views/modals/TimeoutWarning.html',
- backdrop: false,
- controller: ['$scope', 'Auth', function($scope, Auth) {
- $scope.remainTime = 60;
- $scope.title = $t('main.autoLogOut');
- $scope.primaryText = $t('main.controls.remainLoggedIn');
- $scope.secondaryText = $t('main.controls.logOut');
- $scope.remain = function() {
- $rootScope.timeoutModal.close();
- delete $rootScope.timeoutModal;
- };
- $scope.logout = function() {
- $rootScope.timeoutModal.close();
- delete $rootScope.timeoutModal;
- Auth.signout().finally(function() {
- $window.location.pathname = Settings.siteRoot;
- });
- };
- $scope.countDown = function() {
- $scope.remainTime--;
- $scope.$apply();
- if ($scope.remainTime == 0) {
- Auth.signout().finally(function() {
- $window.location.pathname = Settings.siteRoot;
- });
- }
- };
- setInterval($scope.countDown, 1000);
- }]
- });
- }
- };
- $rootScope.userActivityTimeoutInterval = window.setInterval(checkActiveness, 1000);
- };
-
- // Send noop requests every 10 seconds just to keep backend session alive
- $scope.startNoopPolling = function() {
- $rootScope.noopPollingInterval = setInterval(Cluster.getAmbariTimeout, 10000);
- };
-
- if (!$rootScope.userActivityTimeoutInterval) {
- Cluster.getAmbariTimeout().then(function(timeout) {
- $rootScope.userTimeout = Number(timeout) * 1000;
- if ($rootScope.userTimeout > 0)
- $scope.startInactiveTimeoutMonitoring($rootScope.userTimeout);
- });
- }
- if (!$rootScope.noopPollingInterval) {
- $scope.startNoopPolling();
- }
- $scope.updateInstances();
+.controller('MainCtrl',['$scope','$rootScope', function($scope, $rootScope) {
+ $scope.$watch(function() {
+ return $rootScope.cluster;
+ }, function() {
+ $scope.cluster = $rootScope.cluster;
+ }, true);
}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
index 183a276..cb52df1 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
@@ -39,6 +39,7 @@ angular.module('ambariAdminConsole')
'common.versions': 'Versions',
'common.stack': 'Stack',
'common.details': 'Details',
+ 'common.dashboard': 'Dashboard',
'common.goToDashboard': 'Go to Dashboard',
'common.exportBlueprint': 'Export Blueprint',
'common.blueprint': 'Blueprint',
@@ -70,7 +71,6 @@ angular.module('ambariAdminConsole')
'common.renameCluster': 'Rename Cluster',
'common.renameClusterTip': 'Only alpha-numeric characters, up to 80 characters',
'common.clusterCreationInProgress': 'Cluster creation in progress...',
- 'common.userGroupManagement': 'User + Group Management',
'common.all': 'All',
'common.group': 'Group',
'common.user': 'User',
@@ -96,6 +96,10 @@ angular.module('ambariAdminConsole')
'common.undo': 'Undo',
'common.fromGroupMark': '(from group)',
'common.copy': '_Copy',
+ 'common.clusterInformation': 'Cluster Information',
+ 'common.clusterManagement': 'Cluster Management',
+ 'common.userManagement': 'User Management',
+ 'common.admin': 'Admin',
'common.clusterNameChangeConfirmation.title': 'Confirm Cluster Name Change',
'common.clusterNameChangeConfirmation.message': 'Are you sure you want to change the cluster name to {{clusterName}}?',
@@ -277,7 +281,7 @@ angular.module('ambariAdminConsole')
'clusters.alerts.cannotLoadClusterData': 'Cannot load cluster data',
- 'groups.createLocal': 'Create Local Group',
+ 'groups.createLocal': 'Add Groups',
'groups.name': 'Group name',
'groups.members': 'Members',
'groups.membersPlural': '{{n}} member{{n == 1 ? "" : "s"}}',
@@ -298,7 +302,7 @@ angular.module('ambariAdminConsole')
'users.yourPassword': 'Your Password',
'users.newPassword': 'New User Password',
'users.newPasswordConfirmation': 'New User Password Confirmation',
- 'users.create': 'Create Local User',
+ 'users.create': 'Add Users',
'users.active': 'Active',
'users.inactive': 'Inactive',
'users.status': 'Status',
@@ -369,6 +373,7 @@ angular.module('ambariAdminConsole')
'versions.installOn': 'Install on...',
'versions.register.title': 'Register Version',
+ 'versions.add.title': 'Add Version',
'versions.register.error.header': 'Unable to Register',
'versions.register.error.body': 'You are attempting to register a version with a Base URL that is already in use with an existing registered version. You *must* review your Base URLs and confirm they are unique for the version you are trying to register.',
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index a1ca59c..d2d8253 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -22,7 +22,8 @@ angular.module('ambariAdminConsole')
root: {
url: '/',
templateUrl: 'views/main.html',
- controller: 'MainCtrl'
+ controller: 'MainCtrl',
+ label: 'Welcome'
},
authentication: {
main: {
@@ -47,122 +48,144 @@ angular.module('ambariAdminConsole')
list: {
url: '/users',
templateUrl: 'views/users/list.html',
- controller: 'UsersListCtrl'
+ controller: 'UsersListCtrl',
+ label: 'Users'
},
edit: {
url: '/users/:id/edit',
templateUrl: 'views/users/create.html',
- controller: 'UsersCreateCtrl'
+ controller: 'UsersCreateCtrl',
+ label: 'Users'
},
create: {
url: '/users/new',
templateUrl: 'views/users/create.html',
- controller: 'UsersCreateCtrl'
+ controller: 'UsersCreateCtrl',
+ label: 'Users'
},
show: {
url: '/users/:id*',
templateUrl: 'views/users/show.html',
- controller: 'UsersShowCtrl'
+ controller: 'UsersShowCtrl',
+ label: 'Users'
}
},
groups: {
list: {
url: '/groups',
templateUrl: 'views/groups/list.html',
- controller: 'GroupsListCtrl'
+ controller: 'GroupsListCtrl',
+ label: 'Groups'
},
edit: {
url: '/groups/:id/edit',
templateUrl: 'views/groups/edit.html',
- controller: 'GroupsEditCtrl'
+ controller: 'GroupsEditCtrl',
+ label: 'Groups'
},
create: {
url: '/groups/new',
templateUrl: 'views/groups/create.html',
- controller: 'GroupsCreateCtrl'
+ controller: 'GroupsCreateCtrl',
+ label: 'Groups'
}
},
views: {
list: {
url: '/views',
templateUrl: 'views/ambariViews/listTable.html',
- controller: 'ViewsListCtrl'
+ controller: 'ViewsListCtrl',
+ label: 'Views'
},
listViewUrls: {
url: '/viewUrls',
templateUrl: 'views/ambariViews/listUrls.html',
- controller: 'ViewsListCtrl'
+ controller: 'ViewsListCtrl',
+ label: 'Views'
},
createViewUrl:{
url: '/urls/new',
templateUrl: 'views/urls/create.html',
- controller: 'ViewUrlCtrl'
+ controller: 'ViewUrlCtrl',
+ label: 'Views'
},
linkViewUrl:{
url: '/urls/link/:viewName/:viewVersion/:viewInstanceName',
templateUrl: 'views/urls/create.html',
- controller: 'ViewUrlCtrl'
+ controller: 'ViewUrlCtrl',
+ label: 'Views'
},
editViewUrl:{
url: '/urls/edit/:urlName',
templateUrl: 'views/urls/edit.html',
- controller: 'ViewUrlEditCtrl'
+ controller: 'ViewUrlEditCtrl',
+ label: 'Views'
},
clone: {
url: '/views/:viewId/versions/:version/instances/:instanceId/clone',
templateUrl: 'views/ambariViews/create.html',
- controller: 'CreateViewInstanceCtrl'
+ controller: 'CreateViewInstanceCtrl',
+ label: 'Views'
},
edit: {
url: '/views/:viewId/versions/:version/instances/:instanceId/edit',
templateUrl: 'views/ambariViews/edit.html',
- controller: 'ViewsEditCtrl'
+ controller: 'ViewsEditCtrl',
+ label: 'Views'
},
create: {
url: '/views/:viewId/new',
templateUrl: 'views/ambariViews/create.html',
- controller: 'CreateViewInstanceCtrl'
+ controller: 'CreateViewInstanceCtrl',
+ label: 'Views'
}
},
stackVersions: {
list: {
url: '/stackVersions',
templateUrl: 'views/stackVersions/list.html',
- controller: 'StackVersionsListCtrl'
+ controller: 'StackVersionsListCtrl',
+ label: 'Cluster Information'
},
create: {
url: '/stackVersions/create',
templateUrl: 'views/stackVersions/stackVersionPage.html',
- controller: 'StackVersionsCreateCtrl'
+ controller: 'StackVersionsCreateCtrl',
+ label: 'Cluster Information'
},
edit: {
url: '/stackVersions/:stackName/:versionId/edit',
templateUrl: 'views/stackVersions/stackVersionPage.html',
- controller: 'StackVersionsEditCtrl'
+ controller: 'StackVersionsEditCtrl',
+ label: 'Cluster Information'
}
},
remoteClusters: {
list: {
url: '/remoteClusters',
templateUrl: 'views/remoteClusters/list.html',
- controller: 'RemoteClustersListCtrl'
+ controller: 'RemoteClustersListCtrl',
+ label: 'Remote Clusters'
},
create: {
url: '/remoteClusters/create',
templateUrl: 'views/remoteClusters/remoteClusterPage.html',
- controller: 'RemoteClustersCreateCtrl'
+ controller: 'RemoteClustersCreateCtrl',
+ label: 'Remote Clusters'
},
edit: {
url: '/remoteClusters/:clusterName/edit',
templateUrl: 'views/remoteClusters/editRemoteClusterPage.html',
- controller: 'RemoteClustersEditCtrl'
+ controller: 'RemoteClustersEditCtrl',
+ label: 'Remote Clusters'
}
},
clusters: {
manageAccess: {
url: '/clusters/:id/manageAccess',
templateUrl: 'views/clusters/manageAccess.html',
- controller: 'ClustersManageAccessCtrl'
+ controller: 'ClustersManageAccessCtrl',
+ label: 'Roles'
},
userAccessList: {
url: '/clusters/:id/userAccessList',
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js
new file mode 100644
index 0000000..434d1e9
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js
@@ -0,0 +1,269 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+'use strict';
+
+$(document).ready(function () {
+ var $accordionToggler = $(this).find('[data-toggle="collapseAccordion"]');
+ $accordionToggler.off('click').on('click', function (event) {
+ var $this = $(this);
+ $this.siblings('.panel-body').slideToggle(500);
+ $this.children().children('.panel-toggle').toggleClass('fa-angle-down fa-angle-up');
+ event.stopPropagation();
+ return false;
+ });
+});
+'use strict';
+
+(function ($) {
+
+ /**
+ * jQuery plugin for navigation bars
+ * Usage:
+ * <pre>
+ * $('.navigation-bar').navigationBar();
+ * </pre>
+ *
+ * @param {object} options see <code>$.fn.navigationBar.defaults</code>
+ * @returns {$}
+ */
+
+ $.fn.navigationBar = function (options) {
+
+ var settings = $.extend({}, $.fn.navigationBar.defaults, options);
+
+ return this.each(function () {
+ var _this = this;
+
+ var containerSelector = '.navigation-bar-container';
+ var $navigationContainer = $(this).find(containerSelector);
+ var $sideNavToggler = $(this).find('[data-toggle=' + settings.navBarToggleDataAttr + ']');
+ var $subMenuToggler = $(this).find('[data-toggle=' + settings.subMenuNavToggleDataAttr + ']');
+ var firstLvlMenuItemsSelector = '.side-nav-menu>li';
+ var secondLvlMenuItemsSelector = '.side-nav-menu>li>ul>li';
+ var $moreActions = $(this).find('.more-actions');
+ var $dropdownMenu = $moreActions.children('.dropdown-menu');
+
+ $subMenuToggler.each(function (index, toggler) {
+ return $(toggler).parent().addClass('has-sub-menu');
+ });
+
+ if (settings.fitHeight) {
+ $(this).addClass('navigation-bar-fit-height');
+
+ // make scrolling effect on side nav ONLY, i.e. not effected on ambari main contents
+ $(this).find('.side-nav-menu').on('DOMMouseScroll mousewheel', function (ev) {
+ var $this = $(this),
+ scrollTop = this.scrollTop,
+ scrollHeight = this.scrollHeight,
+ height = $this.innerHeight(),
+ delta = ev.originalEvent.wheelDelta,
+ up = delta > 0;
+ var prevent = function prevent() {
+ ev.stopPropagation();
+ ev.preventDefault();
+ ev.returnValue = false;
+ return false;
+ };
+
+ if (!up && -delta > scrollHeight - height - scrollTop) {
+ // Scrolling down, but this will take us past the bottom.
+ $this.scrollTop(scrollHeight);
+ return prevent();
+ } else if (up && delta > scrollTop) {
+ // Scrolling up, but this will take us past the top.
+ $this.scrollTop(0);
+ return prevent();
+ }
+ });
+ }
+
+ //set main content left margin based on the width of side-nav
+ var containerWidth = $navigationContainer.width();
+ if (settings.moveLeftContent) {
+ $(settings.content).css('margin-left', containerWidth);
+ }
+ if (settings.moveLeftFooter) {
+ $(settings.footer).css('margin-left', containerWidth);
+ }
+
+ function popStateHandler() {
+ var path = window.location.pathname + window.location.hash;
+ $navigationContainer.find('li a').each(function (index, link) {
+ var $link = $(link);
+ var href = $link.attr('data-href') || $link.attr('href');
+ if (path.indexOf(href) !== -1 && ['', '#'].indexOf(href) === -1) {
+ $link.parent().addClass('active');
+ } else {
+ $link.parent().removeClass('active');
+ }
+ });
+ }
+
+ if (settings.handlePopState) {
+ popStateHandler();
+ $(window).bind('popstate', popStateHandler);
+ }
+
+ function clickHandler(el) {
+ var $li = $(el).parent();
+ var activeClass = settings.activeClass;
+
+ var activeMenuItems = firstLvlMenuItemsSelector + '.' + activeClass;
+ var activeSubMenuItems = secondLvlMenuItemsSelector + '.' + activeClass;
+ $navigationContainer.find(activeMenuItems).removeClass(activeClass);
+ $navigationContainer.find(activeSubMenuItems).removeClass(activeClass);
+ $li.addClass(activeClass);
+ }
+
+ /**
+ * Click on menu item
+ */
+ $(firstLvlMenuItemsSelector + '>a').on('click', function () {
+ clickHandler(this);
+ });
+
+ /**
+ * Click on sub menu item
+ */
+ $(secondLvlMenuItemsSelector + '>a').on('click', function () {
+ clickHandler(this);
+ $(this).parent().parent().parent().addClass(settings.activeClass);
+ });
+
+ /**
+ * Slider for sub menu
+ */
+ $subMenuToggler.off('click').on('click', function (event) {
+ // ignore click if navigation-bar is collapsed
+ if ($navigationContainer.hasClass('collapsed')) {
+ return false;
+ }
+ var $this = $(this);
+ $this.siblings('.sub-menu').slideToggle(600, function () {
+ var $topMenuItem = $this.parent();
+ var $subMenu = $topMenuItem.find('ul');
+ return $subMenu.is(':visible') ? $topMenuItem.removeClass('collapsed') : $topMenuItem.addClass('collapsed');
+ });
+ $this.children('.toggle-icon').toggleClass(settings.menuLeftClass + ' ' + settings.menuDownClass);
+ event.stopPropagation();
+ return false;
+ });
+
+ if (settings.fitHeight) {
+ $moreActions.on('click', function () {
+ // set actions submenu position
+ var $moreIcon = $(this);
+ var $header = $('.side-nav-header');
+ $dropdownMenu.css({
+ top: $moreIcon.offset().top - $header.offset().top + 20 + 'px',
+ left: $moreIcon.offset().left + 'px'
+ });
+ });
+ }
+ $dropdownMenu.on('click', function () {
+ // some action was triggered, should hide this icon
+ var moreIcon = $(this).parent();
+ setTimeout(function () {
+ moreIcon.hide();
+ }, 1000);
+ });
+ $navigationContainer.children('.side-nav-menu').scroll(function () {
+ $moreActions.removeClass('open');
+ });
+
+ /**
+ * Expand/collapse navigation bar
+ */
+ $sideNavToggler.click(function () {
+
+ $navigationContainer.toggleClass('collapsed').promise().done(function () {
+ var subMenuSelector = 'ul.sub-menu';
+ var $subMenus = $navigationContainer.find(subMenuSelector);
+ var $subMenuItems = $navigationContainer.find('.side-nav-menu>li');
+ if ($navigationContainer.hasClass('collapsed')) {
+ // set sub menu invisible when collapsed
+ $subMenus.hide();
+ $moreActions.hide();
+ // set the hover effect when collapsed, should show sub-menu on hovering
+ $subMenuItems.hover(function () {
+ $(this).find(subMenuSelector).show();
+ // set sub-menu position
+ var $parent = $(this);
+ var $header = $('.side-nav-header');
+ if (settings.fitHeight) {
+ $(this).find(subMenuSelector).css({
+ position: 'fixed',
+ top: $parent.offset().top - $header.offset().top + 'px',
+ left: 50 + 'px'
+ });
+ }
+ }, function () {
+ $(this).find(subMenuSelector).hide();
+ });
+ } else {
+ // keep showing all sub menu
+ $subMenus.show().each(function (index, item) {
+ return $(item).parent().removeClass('collapsed');
+ });
+ $subMenuItems.unbind('mouseenter mouseleave');
+ $navigationContainer.find('.toggle-icon').removeClass(settings.menuLeftClass).addClass(settings.menuDownClass);
+ $moreActions.show();
+ // set sub-menu position
+ if (settings.fitHeight) {
+ $(_this).find(subMenuSelector).css({
+ position: 'relative',
+ top: 0,
+ left: 0
+ });
+ }
+ }
+
+ $navigationContainer.on('transitionend', function () {
+ //set main content left margin based on the width of side-nav
+ var containerWidth = $navigationContainer.width();
+ if (settings.moveLeftContent) {
+ $(settings.content).css('margin-left', containerWidth);
+ }
+ if (settings.moveLeftFooter) {
+ $(settings.footer).css('margin-left', containerWidth);
+ }
+ });
+ $sideNavToggler.find('span').toggleClass(settings.collapseNavBarClass + ' ' + settings.expandNavBarClass);
+ });
+ return false;
+ });
+ });
+ };
+
+ $.fn.navigationBar.defaults = {
+ handlePopState: true,
+ fitHeight: false,
+ content: '#main',
+ footer: 'footer',
+ moveLeftContent: true,
+ moveLeftFooter: true,
+ menuLeftClass: 'glyphicon-menu-right',
+ menuDownClass: 'glyphicon-menu-down',
+ collapseNavBarClass: 'fa-angle-double-left',
+ expandNavBarClass: 'fa-angle-double-right',
+ activeClass: 'active',
+ navBarToggleDataAttr: 'collapse-side-nav',
+ subMenuNavToggleDataAttr: 'collapse-sub-menu'
+ };
+})(jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index 946007d..66f23af 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -415,79 +415,6 @@ a.gotoinstance{
background-color: #da4f49;
color: white;
}
-/*
- Style topnav menu
-*/
-.navbar-views-dropdown > a{
- color: #c3c3c3;
- font-size: 1.3em;
- padding: 10px 25px 18px;
- display: block;
- box-shadow: none!important;
- background: none!important;
- text-decoration: none;
-}
-.navbar-views-dropdown > a:hover{
- color: #fff;
-}
-.navbar-views-dropdown > a > i{
- display: block;
- margin-top: 1px;
- margin-bottom: -12px;
-}
-.navbar-views-dropdown .dropdown-menu, .verison-label-row .dropdown-menu {
- margin-top: -2px;
-}
-
-.navbar-views-dropdown .dropdown-menu a:hover{
- background: #666;
- color: #fff;
-}
-.navbar-views-dropdown .dropdown-menu .disabled a:hover{
- background: none;
- color: #999;
-}
-#top-nav .navbar.navbar-static-top{
- min-height: 40px;
-}
-#top-nav .navbar-inverse{
- background: none;
- border: none;
-}
-#top-nav .navbar.navbar-static-top .navbar-inner {
- background-color: #313d54;
- -webkit-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);
- -moz-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);
- box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);
- max-height: 40px;
- height: 40px;
-}
-#top-nav .dropdown-toggle.navbar-btn{
- margin: 4px 0 0 0;
-}
-#top-nav .navbar.navbar-static-top .logo {
- float: left;
- padding-top: 2px;
-}
-#top-nav .navbar.navbar-static-top .logo img {
- height: 32px;
-}
-#top-nav .navbar.navbar-static-top .brand {
- color: #ffffff;
- font-size: 16px;
- font-weight: normal;
- line-height: 32px;
- margin-left: 0;
- padding: 2px 5px 0 10px;
- text-shadow: 0 1px 0 #555555;
- display: block;
- float: left;
- text-decoration: none;
-
-}
-#top-nav .navbar.navbar-static-top .brand.cluster-name{
- margin-left: 10px;
-}
.create-view-form, .register-version-form, .edit-version-form {
padding-bottom: 50px;
@@ -579,24 +506,6 @@ a.gotoinstance{
border: 0;
}
-.container{
- padding-left: 0;
- width: 940px;
-}
-
-
-@media (min-width: 1200px) {
- .container, .navbar-static-top .container, .navbar-fixed-top .container, .navbar-fixed-bottom .container{
- width: 1130px;
- }
- .container{
- width: 1170px;
- }
- .mainpage .panel-body #main-operations-boxes .col-sm-5 {
- width: 44%;
- }
-}
-
ul.nav li > a{
cursor: pointer;
}
@@ -701,318 +610,6 @@ table.no-border tr td{
/*.login-message-pane .well {height: 74px;}
.login-message-pane input {margin-left: 3px;}*/
-
-.btn {
- display: inline-block;
- *display: inline;
- padding: 4px 14px;
- margin-bottom: 0;
- *margin-left: .3em;
- font-size: 14px;
- line-height: 20px;
- *line-height: 20px;
- color: #333333;
- text-align: center;
- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
- vertical-align: middle;
- cursor: pointer;
- background-color: #f5f5f5;
- *background-color: #e6e6e6;
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
- background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
- background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
- background-repeat: repeat-x;
- border: 1px solid #bbbbbb;
- *border: 0;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- border-color: #e6e6e6 #e6e6e6 #bfbfbf;
- border-bottom-color: #a2a2a2;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
- *zoom: 1;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn:hover,
-.btn:active,
-.btn.active,
-.btn.disabled,
-.btn[disabled] {
- color: #333333;
- background-color: #e6e6e6;
- *background-color: #d9d9d9;
-}
-
-.btn:active,
-.btn.active {
- background-color: #cccccc \9;
-}
-
-.btn:first-child {
- *margin-left: 0;
-}
-
-.btn:hover {
- color: #333333;
- text-decoration: none;
- background-color: #e6e6e6;
- *background-color: #d9d9d9;
- /* Buttons in IE7 don't get borders, so darken on hover */
-
- background-position: 0 -15px;
- -webkit-transition: background-position 0.1s linear;
- -moz-transition: background-position 0.1s linear;
- -o-transition: background-position 0.1s linear;
- transition: background-position 0.1s linear;
-}
-
-.btn:focus {
- outline: thin dotted #333;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
-}
-
-.btn.active,
-.btn:active {
- background-color: #e6e6e6;
- background-color: #d9d9d9 \9;
- background-image: none;
- outline: 0;
- -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn.disabled,
-.btn[disabled] {
- cursor: default;
- background-color: #e6e6e6;
- background-image: none;
- opacity: 0.65;
- filter: alpha(opacity=65);
- -webkit-box-shadow: none;
- -moz-box-shadow: none;
- box-shadow: none;
-}
-
-
-
-.btn-primary.active,
-.btn-warning.active,
-.btn-danger.active,
-.btn-success.active,
-.btn-info.active,
-.btn-inverse.active {
- color: rgba(255, 255, 255, 0.75);
-}
-
-.btn {
- border-color: #c5c5c5;
- border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
-}
-
-.btn-primary {
- color: #ffffff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- background-color: #006dcc;
- *background-color: #0044cc;
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
- background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
- background-image: -o-linear-gradient(top, #0088cc, #0044cc);
- background-image: linear-gradient(to bottom, #0088cc, #0044cc);
- background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
- background-repeat: repeat-x;
- border-color: #0044cc #0044cc #002a80;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-primary:hover,
-.btn-primary:active,
-.btn-primary.active,
-.btn-primary.disabled,
-.btn-primary[disabled],
-.btn-primary.disabled:hover,
-.btn-primary[disabled]:hover
- {
- color: #ffffff;
- background-color: #0044cc;
- *background-color: #003bb3;
-}
-
-.btn-primary:active,
-.btn-primary.active {
- background-color: #003399 \9;
-}
-
-.btn-warning {
- color: #ffffff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- background-color: #faa732;
- *background-color: #f89406;
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
- background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
- background-image: -o-linear-gradient(top, #fbb450, #f89406);
- background-image: linear-gradient(to bottom, #fbb450, #f89406);
- background-image: -moz-linear-gradient(top, #fbb450, #f89406);
- background-repeat: repeat-x;
- border-color: #f89406 #f89406 #ad6704;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-warning:hover,
-.btn-warning:active,
-.btn-warning.active,
-.btn-warning.disabled,
-.btn-warning[disabled] {
- color: #ffffff;
- background-color: #f89406;
- *background-color: #df8505;
-}
-
-.btn-warning:active,
-.btn-warning.active {
- background-color: #c67605 \9;
-}
-
-.btn-danger {
- color: #ffffff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- background-color: #da4f49;
- *background-color: #bd362f;
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));
- background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f);
- background-image: -o-linear-gradient(top, #ee5f5b, #bd362f);
- background-image: linear-gradient(to bottom, #ee5f5b, #bd362f);
- background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f);
- background-repeat: repeat-x;
- border-color: #bd362f #bd362f #802420;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-danger:hover,
-.btn-danger:active,
-.btn-danger.active,
-.btn-danger.disabled,
-.btn-danger[disabled] {
- color: #ffffff;
- background-color: #bd362f;
- *background-color: #a9302a;
-}
-
-.btn-danger:active,
-.btn-danger.active {
- background-color: #942a25 \9;
-}
-
-.btn-success {
- color: #ffffff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- background-color: #5bb75b;
- *background-color: #51a351;
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));
- background-image: -webkit-linear-gradient(top, #62c462, #51a351);
- background-image: -o-linear-gradient(top, #62c462, #51a351);
- background-image: linear-gradient(to bottom, #62c462, #51a351);
- background-image: -moz-linear-gradient(top, #62c462, #51a351);
- background-repeat: repeat-x;
- border-color: #51a351 #51a351 #387038;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-success:hover,
-.btn-success:active,
-.btn-success.active,
-.btn-success.disabled,
-.btn-success[disabled] {
- color: #ffffff;
- background-color: #51a351;
- *background-color: #499249;
-}
-
-.btn-success:active,
-.btn-success.active {
- background-color: #408140 \9;
-}
-
-.btn-info {
- color: #ffffff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- background-color: #49afcd;
- *background-color: #2f96b4;
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));
- background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4);
- background-image: -o-linear-gradient(top, #5bc0de, #2f96b4);
- background-image: linear-gradient(to bottom, #5bc0de, #2f96b4);
- background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4);
- background-repeat: repeat-x;
- border-color: #2f96b4 #2f96b4 #1f6377;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-info:hover,
-.btn-info:active,
-.btn-info.active,
-.btn-info.disabled,
-.btn-info[disabled] {
- color: #ffffff;
- background-color: #2f96b4;
- *background-color: #2a85a0;
-}
-
-.btn-info:active,
-.btn-info.active {
- background-color: #24748c \9;
-}
-
-.btn-inverse {
- color: #ffffff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- background-color: #363636;
- *background-color: #222222;
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));
- background-image: -webkit-linear-gradient(top, #444444, #222222);
- background-image: -o-linear-gradient(top, #444444, #222222);
- background-image: linear-gradient(to bottom, #444444, #222222);
- background-image: -moz-linear-gradient(top, #444444, #222222);
- background-repeat: repeat-x;
- border-color: #222222 #222222 #000000;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-inverse:hover,
-.btn-inverse:active,
-.btn-inverse.active,
-.btn-inverse.disabled,
-.btn-inverse[disabled] {
- color: #ffffff;
- background-color: #222222;
- *background-color: #151515;
-}
-
-.btn-inverse:active,
-.btn-inverse.active {
- background-color: #080808 \9;
-}
-
button.btn,
input[type="submit"].btn {
*padding-top: 3px;
@@ -1050,6 +647,10 @@ button.btn.btn-xs{
border-radius: 3px;
}
+a.btn-primary {
+ color: #fff;
+}
+
.clusterDisplayName {
display:inline-block;
width:90%;
@@ -1872,4 +1473,28 @@ legend {
.ellipsis-overflow {
overflow: hidden;
text-overflow: ellipsis;
-}
\ No newline at end of file
+}
+
+.pull-right {
+ float: right;
+}
+
+body {
+ height: 100%;
+ background-color: #f0f0f0;
+}
+
+#main {
+ transition: .5s ease;
+ overflow: visible;
+ min-width: 980px;
+}
+
+#side-nav .ambari-header-link:hover {
+ text-decoration: none;
+}
+
+.main-container {
+ background-color: #fff;
+ padding: 15px;
+}
[50/51] [abbrv] ambari git commit: AMBARI-22387. Create a Pre-Upgrade
Check Warning About LZO. Fix import (dlysnichenko)
Posted by nc...@apache.org.
AMBARI-22387. Create a Pre-Upgrade Check Warning About LZO. Fix import (dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6e706d42
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6e706d42
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6e706d42
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 6e706d427f1f9bcfc61f986ea1a1d5f5a28d500f
Parents: 76349ac
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Mon Nov 13 16:35:23 2017 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Mon Nov 13 16:35:23 2017 +0200
----------------------------------------------------------------------
.../src/main/java/org/apache/ambari/server/checks/LZOCheck.java | 1 -
1 file changed, 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6e706d42/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
index 3000b79..9c0286b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
@@ -19,7 +19,6 @@ package org.apache.ambari.server.checks;
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.PrereqCheckRequest;
[48/51] [abbrv] ambari git commit: AMBARI-22417. Ambari checks fail
with FIPS mode is activated on the OS (rlevas)
Posted by nc...@apache.org.
AMBARI-22417. Ambari checks fail with FIPS mode is activated on the OS (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5122671d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5122671d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5122671d
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 5122671d0076612f4b39f4ae51c2ad627544d768
Parents: 7c4a7e4
Author: Robert Levas <rl...@hortonworks.com>
Authored: Mon Nov 13 05:20:25 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Mon Nov 13 05:20:25 2017 -0500
----------------------------------------------------------------------
.../libraries/functions/curl_krb_request.py | 22 +++++++-------------
1 file changed, 7 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/5122671d/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py b/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
index 95e8625..55395ce 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
@@ -21,28 +21,20 @@ Ambari Agent
"""
__all__ = ["curl_krb_request"]
+import hashlib
import logging
import os
+
import time
+from get_kinit_path import get_kinit_path
+from get_klist_path import get_klist_path
from resource_management.core import global_lock
from resource_management.core import shell
from resource_management.core.exceptions import Fail
-from get_kinit_path import get_kinit_path
-from get_klist_path import get_klist_path
from resource_management.libraries.functions.get_user_call_output import get_user_call_output
-# hashlib is supplied as of Python 2.5 as the replacement interface for md5
-# and other secure hashes. In 2.6, md5 is deprecated. Import hashlib if
-# available, avoiding a deprecation warning under 2.6. Import md5 otherwise,
-# preserving 2.4 compatibility.
-try:
- import hashlib
- _md5 = hashlib.md5
-except ImportError:
- import md5
- _md5 = md5.new
-
+HASH_ALGORITHM = hashlib.sha224
CONNECTION_TIMEOUT_DEFAULT = 10
MAX_TIMEOUT_DEFAULT = CONNECTION_TIMEOUT_DEFAULT + 2
@@ -103,10 +95,10 @@ def curl_krb_request(tmp_dir, keytab, principal, url, cache_file_prefix,
is_kinit_required = False
# Create the kerberos credentials cache (ccache) file and set it in the environment to use
- # when executing curl. Use the md5 hash of the combination of the principal and keytab file
+ # when executing curl. Use a hash of the combination of the principal and keytab file
# to generate a (relatively) unique cache filename so that we can use it as needed. Scope
# this file by user in order to prevent sharing of cache files by multiple users.
- ccache_file_name = _md5("{0}|{1}".format(principal, keytab)).hexdigest()
+ ccache_file_name = HASH_ALGORITHM("{0}|{1}".format(principal, keytab)).hexdigest()
curl_krb_cache_path = os.path.join(tmp_dir, "curl_krb_cache")
if not os.path.exists(curl_krb_cache_path):
[47/51] [abbrv] ambari git commit: AMBARI-22416 Log Search UI: fixes
for filtering form. (ababiichuk)
Posted by nc...@apache.org.
AMBARI-22416 Log Search UI: fixes for filtering form. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7c4a7e4c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7c4a7e4c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7c4a7e4c
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 7c4a7e4c52e00282e5b8b901cef14c143fd3da2b
Parents: 068d82f
Author: ababiichuk <ab...@hortonworks.com>
Authored: Fri Nov 10 18:16:45 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Fri Nov 10 23:53:24 2017 +0200
----------------------------------------------------------------------
.../ambari-logsearch-web/src/app/app.module.ts | 2 -
.../src/app/classes/filtering.ts | 355 +---------
.../src/app/classes/models/app-state.ts | 6 +-
.../src/app/classes/models/node-item.ts | 30 +
.../src/app/classes/models/node.ts | 30 -
.../src/app/classes/models/store.ts | 6 +-
.../src/app/classes/models/tab.ts | 12 +-
.../src/app/components/app.component.ts | 6 +-
.../dropdown-button.component.html | 4 +-
.../dropdown-button.component.spec.ts | 2 -
.../dropdown-button.component.ts | 55 +-
.../dropdown-list/dropdown-list.component.html | 2 +-
.../dropdown-list.component.spec.ts | 6 +-
.../filter-button.component.spec.ts | 2 -
.../filter-button/filter-button.component.ts | 35 +-
.../filter-dropdown.component.spec.ts | 14 +-
.../filter-dropdown.component.ts | 22 +-
.../filters-panel/filters-panel.component.html | 6 +-
.../filters-panel.component.spec.ts | 6 +-
.../filters-panel/filters-panel.component.ts | 18 +-
.../log-context/log-context.component.spec.ts | 4 +-
.../logs-container.component.spec.ts | 2 -
.../logs-container/logs-container.component.ts | 26 +-
.../logs-list/logs-list.component.html | 3 +-
.../logs-list/logs-list.component.spec.ts | 21 +-
.../components/logs-list/logs-list.component.ts | 10 +-
.../menu-button/menu-button.component.spec.ts | 2 -
.../menu-button/menu-button.component.ts | 4 +-
.../pagination-controls.component.ts | 7 +-
.../pagination/pagination.component.html | 2 +-
.../pagination/pagination.component.spec.ts | 9 +-
.../pagination/pagination.component.ts | 10 +-
.../search-box/search-box.component.ts | 12 +-
.../time-range-picker.component.html | 3 +-
.../time-range-picker.component.spec.ts | 29 +-
.../time-range-picker.component.ts | 47 +-
.../timezone-picker.component.spec.ts | 2 -
.../services/component-actions.service.spec.ts | 2 -
.../app/services/component-actions.service.ts | 24 +-
.../component-generator.service.spec.ts | 2 -
.../src/app/services/filtering.service.spec.ts | 97 ---
.../src/app/services/filtering.service.ts | 253 -------
.../app/services/logs-container.service.spec.ts | 31 +-
.../src/app/services/logs-container.service.ts | 678 ++++++++++++++++++-
.../src/app/services/utils.service.spec.ts | 285 +++++++-
.../src/app/services/utils.service.ts | 65 +-
46 files changed, 1257 insertions(+), 992 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index 56562df..37f3a49 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -34,7 +34,6 @@ import {environment} from '@envs/environment';
import {mockApiDataService} from '@app/services/mock-api-data.service'
import {HttpClientService} from '@app/services/http-client.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {ComponentGeneratorService} from '@app/services/component-generator.service';
@@ -164,7 +163,6 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
providers: [
HttpClientService,
ComponentActionsService,
- FilteringService,
UtilsService,
LogsContainerService,
ComponentGeneratorService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
index dde144b..2a7205f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
@@ -16,354 +16,37 @@
* limitations under the License.
*/
-import {FormGroup, FormControl} from '@angular/forms';
+import {Moment, unitOfTime} from 'moment';
import {ListItem} from '@app/classes/list-item';
export interface TimeUnit {
type: 'CURRENT' | 'LAST' | 'PAST';
- unit: 'ms' | 's' | 'm' | 'h' | 'd' | 'w' | 'M' | 'Y';
+ unit: unitOfTime.DurationConstructor;
interval?: number;
}
+export interface CustomTimeRange {
+ type: 'CUSTOM';
+ start?: Moment;
+ end?: Moment;
+}
+
+export interface SortingConditions {
+ key: string;
+ type: 'asc' | 'desc';
+}
+
export interface TimeUnitListItem extends ListItem {
- value: TimeUnit;
+ value: TimeUnit | CustomTimeRange;
+}
+
+export interface SortingListItem extends ListItem {
+ value: SortingConditions;
}
export interface FilterCondition {
label?: string;
options?: (ListItem | TimeUnitListItem[])[];
- defaultValue?: string | number | {[key: string]: any};
- defaultLabel?: string;
+ defaultSelection?: ListItem | ListItem[] | number;
iconClass?: string;
}
-
-const paginationOptions: string[] = ['10', '25', '50', '100'];
-
-export const filters: {[key: string]: FilterCondition} = {
- clusters: {
- label: 'filter.clusters',
- options: [],
- defaultValue: ''
- },
- timeRange: {
- options: [
- [
- {
- label: 'filter.timeRange.7d',
- value: {
- type: 'LAST',
- unit: 'd',
- interval: 7
- }
- },
- {
- label: 'filter.timeRange.30d',
- value: {
- type: 'LAST',
- unit: 'd',
- interval: 30
- }
- },
- {
- label: 'filter.timeRange.60d',
- value: {
- type: 'LAST',
- unit: 'd',
- interval: 60
- }
- },
- {
- label: 'filter.timeRange.90d',
- value: {
- type: 'LAST',
- unit: 'd',
- interval: 90
- }
- },
- {
- label: 'filter.timeRange.6m',
- value: {
- type: 'LAST',
- unit: 'M',
- interval: 6
- }
- },
- {
- label: 'filter.timeRange.1y',
- value: {
- type: 'LAST',
- unit: 'Y',
- interval: 1
- }
- },
- {
- label: 'filter.timeRange.2y',
- value: {
- type: 'LAST',
- unit: 'Y',
- interval: 2
- }
- },
- {
- label: 'filter.timeRange.5y',
- value: {
- type: 'LAST',
- unit: 'Y',
- interval: 5
- }
- }
- ],
- [
- {
- label: 'filter.timeRange.yesterday',
- value: {
- type: 'PAST',
- unit: 'd'
- }
- },
- // TODO implement time range calculation
- /*
- {
- label: 'filter.timeRange.beforeYesterday',
- value: {
- type: 'PAST',
- unit: 'd'
- }
- },
- {
- label: 'filter.timeRange.thisDayLastWeek',
- value: {
- type: 'PAST',
- unit: 'd'
- }
- },
- */
- {
- label: 'filter.timeRange.previousWeek',
- value: {
- type: 'PAST',
- unit: 'w'
- }
- },
- {
- label: 'filter.timeRange.previousMonth',
- value: {
- type: 'PAST',
- unit: 'M'
- }
- },
- {
- label: 'filter.timeRange.previousYear',
- value: {
- type: 'PAST',
- unit: 'Y'
- }
- }
- ],
- [
- {
- label: 'filter.timeRange.today',
- value: {
- type: 'CURRENT',
- unit: 'd'
- }
- },
- {
- label: 'filter.timeRange.thisWeek',
- value: {
- type: 'CURRENT',
- unit: 'w'
- }
- },
- {
- label: 'filter.timeRange.thisMonth',
- value: {
- type: 'CURRENT',
- unit: 'M'
- }
- },
- {
- label: 'filter.timeRange.thisYear',
- value: {
- type: 'CURRENT',
- unit: 'Y'
- }
- }
- ],
- [
- {
- label: 'filter.timeRange.5min',
- value: {
- type: 'LAST',
- unit: 'm',
- interval: 5
- }
- },
- {
- label: 'filter.timeRange.15min',
- value: {
- type: 'LAST',
- unit: 'm',
- interval: 15
- }
- },
- {
- label: 'filter.timeRange.30min',
- value: {
- type: 'LAST',
- unit: 'm',
- interval: 30
- }
- },
- {
- label: 'filter.timeRange.1hr',
- value: {
- type: 'LAST',
- unit: 'h',
- interval: 1
- }
- },
- {
- label: 'filter.timeRange.3hr',
- value: {
- type: 'LAST',
- unit: 'h',
- interval: 3
- }
- },
- {
- label: 'filter.timeRange.6hr',
- value: {
- type: 'LAST',
- unit: 'h',
- interval: 6
- }
- },
- {
- label: 'filter.timeRange.12hr',
- value: {
- type: 'LAST',
- unit: 'h',
- interval: 12
- }
- },
- {
- label: 'filter.timeRange.24hr',
- value: {
- type: 'LAST',
- unit: 'h',
- interval: 24
- }
- },
- ]
- ],
- defaultValue: {
- type: 'LAST',
- unit: 'h',
- interval: 1
- },
- defaultLabel: 'filter.timeRange.1hr'
- },
- components: {
- label: 'filter.components',
- iconClass: 'fa fa-cubes',
- options: [],
- defaultValue: ''
- },
- levels: {
- label: 'filter.levels',
- iconClass: 'fa fa-sort-amount-asc',
- options: [
- {
- label: 'levels.fatal',
- value: 'FATAL'
- },
- {
- label: 'levels.error',
- value: 'ERROR'
- },
- {
- label: 'levels.warn',
- value: 'WARN'
- },
- {
- label: 'levels.info',
- value: 'INFO'
- },
- {
- label: 'levels.debug',
- value: 'DEBUG'
- },
- {
- label: 'levels.trace',
- value: 'TRACE'
- },
- {
- label: 'levels.unknown',
- value: 'UNKNOWN'
- }
- ],
- defaultValue: ''
- },
- hosts: {
- label: 'filter.hosts',
- iconClass: 'fa fa-server',
- options: [],
- defaultValue: ''
- },
- sorting: {
- label: 'sorting.title',
- options: [
- {
- label: 'sorting.time.asc',
- value: {
- key: 'logtime',
- type: 'asc'
- }
- },
- {
- label: 'sorting.time.desc',
- value: {
- key: 'logtime',
- type: 'desc'
- }
- }
- ],
- defaultValue: '',
- defaultLabel: ''
- },
- pageSize: {
- label: 'pagination.title',
- options: paginationOptions.map((option: string): ListItem => {
- return {
- label: option,
- value: option
- }
- }),
- defaultValue: '10',
- defaultLabel: '10'
- },
- page: {
- defaultValue: 0
- },
- query: {}
-};
-
-export const filtersFormItemsMap: {[key: string]: string[]} = {
- serviceLogs: ['clusters', 'timeRange', 'components', 'levels', 'hosts', 'sorting', 'pageSize', 'page', 'query'],
- auditLogs: ['clusters', 'timeRange', 'sorting', 'pageSize', 'page', 'query'] // TODO add all the required fields
-};
-
-export const getFiltersForm = (listType: string): FormGroup => {
- const itemsList = filtersFormItemsMap[listType],
- keys = Object.keys(filters).filter((key: string): boolean => itemsList.indexOf(key) > -1),
- items = keys.reduce((currentObject: any, key: string): any => {
- let formControl = new FormControl(),
- item = {
- [key]: formControl
- };
- formControl.setValue(filters[key].defaultValue);
- return Object.assign(currentObject, item);
- }, {});
- return new FormGroup(items);
-};
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
index 2c5c083..afed497 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
@@ -16,9 +16,7 @@
* limitations under the License.
*/
-import {FormGroup} from '@angular/forms';
import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry';
-import {Tab, initialTabs} from '@app/classes/models/tab';
export interface AppState {
isAuthorized: boolean;
@@ -28,7 +26,7 @@ export interface AppState {
isServiceLogsFileView: boolean;
isServiceLogContextView: boolean;
activeLog: ActiveServiceLogEntry | null;
- activeFiltersForm: FormGroup;
+ activeFilters: object;
}
export const initialState: AppState = {
@@ -39,5 +37,5 @@ export const initialState: AppState = {
isServiceLogsFileView: false,
isServiceLogContextView: false,
activeLog: null,
- activeFiltersForm: initialTabs.find((tab: Tab): boolean => tab.isActive).appState.activeFiltersForm
+ activeFilters: null
};
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
new file mode 100644
index 0000000..ef5f772
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import {CommonEntry} from '@app/classes/models/common-entry';
+
+export interface NodeItem {
+ name: string;
+ type?: string;
+ value: string;
+ isParent: boolean;
+ isRoot: boolean;
+ childs?: NodeItem[];
+ logLevelCount?: CommonEntry[];
+ vNodeList?: CommonEntry[];
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
deleted file mode 100644
index a14e51a..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import {CommonEntry} from '@app/classes/models/common-entry';
-
-export interface Node {
- name: string;
- type?: string;
- value: string;
- isParent: boolean;
- isRoot: boolean;
- childs?: Node[];
- logLevelCount?: CommonEntry[];
- vNodeList?: CommonEntry[];
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
index d912b35..f996d92 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
@@ -24,7 +24,7 @@ import {AuditLog} from '@app/classes/models/audit-log';
import {ServiceLog} from '@app/classes/models/service-log';
import {BarGraph} from '@app/classes/models/bar-graph';
import {Graph} from '@app/classes/models/graph';
-import {Node} from '@app/classes/models/node';
+import {NodeItem} from '@app/classes/models/node-item';
import {UserConfig} from '@app/classes/models/user-config';
import {Filter} from '@app/classes/models/filter';
import {AuditLogField} from '@app/classes/models/audit-log-field';
@@ -50,11 +50,11 @@ export interface AppStore {
serviceLogsHistogramData: BarGraph[];
serviceLogsTruncated: ServiceLog[];
graphs: Graph[];
- hosts: Node[];
+ hosts: NodeItem[];
userConfigs: UserConfig[];
filters: Filter[];
clusters: string[];
- components: Node[];
+ components: NodeItem[];
serviceLogsFields: ServiceLogField[];
auditLogsFields: AuditLogField[];
tabs: Tab[];
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
index bb8028a..05ea59d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
@@ -16,15 +16,13 @@
* limitations under the License.
*/
-import {getFiltersForm} from '@app/classes/filtering';
-
export interface Tab {
id: string;
type: string;
- isActive: boolean;
+ isActive?: boolean;
isCloseable?: boolean;
label: string;
- appState: any;
+ appState?: object;
}
export const initialTabs: Tab[] = [
@@ -35,8 +33,7 @@ export const initialTabs: Tab[] = [
label: 'common.serviceLogs',
appState: {
activeLogsType: 'serviceLogs',
- isServiceLogsFileView: false,
- activeFiltersForm: getFiltersForm('serviceLogs')
+ isServiceLogsFileView: false
}
},
{
@@ -46,8 +43,7 @@ export const initialTabs: Tab[] = [
label: 'common.auditLogs',
appState: {
activeLogsType: 'auditLogs',
- isServiceLogsFileView: false,
- activeFiltersForm: getFiltersForm('auditLogs')
+ isServiceLogsFileView: false
}
}
];
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
index 4de47ea..038dd2a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
@@ -30,12 +30,12 @@ import {HttpClientService} from '@app/services/http-client.service';
export class AppComponent {
constructor(private httpClient: HttpClientService, private translate: TranslateService, private appState: AppStateService) {
- appState.getParameter('isAuthorized').subscribe(value => this.isAuthorized = value);
+ appState.getParameter('isAuthorized').subscribe((value: boolean) => this.isAuthorized = value);
appState.setParameter('isInitialLoading', true);
- this.httpClient.get('status').subscribe(() => this.appState.setParameters({
+ httpClient.get('status').subscribe(() => appState.setParameters({
isAuthorized: true,
isInitialLoading: false
- }), () => this.appState.setParameter('isInitialLoading', false));
+ }), () => appState.setParameter('isInitialLoading', false));
translate.setDefaultLang('en');
translate.use('en');
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
index 798a609..b5f1e56 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
@@ -22,10 +22,10 @@
<span *ngIf="iconClass" [ngClass]="iconClass"></span>
<span *ngIf="label">{{label | translate}}</span>
</span>
- <span *ngIf="showSelectedValue && !isMultipleChoice">{{selectedLabel | translate}}</span>
+ <span *ngIf="showSelectedValue && !isMultipleChoice && selection.length">{{selection[0].label | translate}}</span>
<span *ngIf="!hideCaret" class="caret"></span>
</button>
<ul data-component="dropdown-list" [ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}"
- [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateValue($event)"
+ [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateSelection($event)"
[actionArguments]="additionalArgs"></ul>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
index f11ca09..bd41c04 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {HttpClientService} from '@app/services/http-client.service';
@@ -85,7 +84,6 @@ describe('DropdownButtonComponent', () => {
ServiceLogsHistogramDataService,
ServiceLogsTruncatedService,
TabsService,
- FilteringService,
UtilsService,
ComponentActionsService,
{
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
index 0bf4422..148e1b4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-import {Component, OnInit, Input} from '@angular/core';
+import {Component, Input} from '@angular/core';
import {ListItem} from '@app/classes/list-item';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {UtilsService} from '@app/services/utils.service';
@@ -26,14 +26,10 @@ import {UtilsService} from '@app/services/utils.service';
templateUrl: './dropdown-button.component.html',
styleUrls: ['./dropdown-button.component.less']
})
-export class DropdownButtonComponent implements OnInit {
+export class DropdownButtonComponent {
constructor(protected actions: ComponentActionsService, protected utils: UtilsService) {
}
-
- ngOnInit() {
- this.selectedLabel = this.defaultLabel;
- }
@Input()
label?: string;
@@ -48,13 +44,7 @@ export class DropdownButtonComponent implements OnInit {
showSelectedValue: boolean = true;
@Input()
- options?: ListItem[];
-
- @Input()
- defaultValue?: string;
-
- @Input()
- defaultLabel?: string;
+ options: ListItem[] = [];
@Input()
action?: string;
@@ -71,36 +61,33 @@ export class DropdownButtonComponent implements OnInit {
@Input()
isDropup: boolean = false;
- protected selectedValue?: any;
-
- selectedLabel: string;
+ protected selectedItems?: ListItem[] = [];
- get value(): any {
- return this.selectedValue;
+ get selection(): ListItem[] {
+ return this.selectedItems;
}
- set value(value: any) {
- this.selectedValue = value;
+ set selection(items: ListItem[]) {
+ this.selectedItems = items;
}
- updateValue(eventOptions: ListItem): void {
- const value = eventOptions && eventOptions.value,
- action = this.action && this.actions[this.action];
+ updateSelection(item: ListItem): void {
+ const action = this.action && this.actions[this.action];
if (this.isMultipleChoice) {
- this.value = this.utils.updateMultiSelectValue(this.value, value, eventOptions.isChecked);
- this.options.find(item => item.value === value).isChecked = eventOptions.isChecked;
+ this.options.find((option: ListItem): boolean => {
+ return this.utils.isEqual(option.value, item.value);
+ }).isChecked = item.isChecked;
+ const checkedItems = this.options.filter((option: ListItem): boolean => option.isChecked);
+ this.selection = checkedItems;
if (action) {
- action(this.options.filter(item => item.isChecked).map(item => item.value), ...this.additionalArgs);
+ action(checkedItems.map((option: ListItem): any => option.value), ...this.additionalArgs);
}
- } else {
- if (this.utils.valueHasChanged(this.value, value)) {
- this.value = value;
- this.selectedLabel = eventOptions.label;
- if (action) {
- action(this.value, ...this.additionalArgs);
- }
+ } else if (!this.utils.isEqual(this.selection[0], item)) {
+ this.selection = [item];
+ if (action) {
+ action(item.value, ...this.additionalArgs);
}
}
}
-
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
index 5de78ad..df564e5 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
@@ -17,7 +17,7 @@
<li *ngFor="let item of items">
<label class="list-item-label" *ngIf="isMultipleChoice">
- <input type="checkbox" [attr.id]="item.id || item.value" [attr.checked]="item.isChecked ? 'checked' : null"
+ <input type="checkbox" [attr.id]="item.id || item.value" [(ngModel)]="item.isChecked"
(change)="changeSelectedItem({value: item.value, isChecked: $event.currentTarget.checked})">
<label [attr.for]="item.id || item.value" class="label-container">
<span *ngIf="item.iconClass" [ngClass]="item.iconClass"></span>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
index 5455e67..ac2fa84 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
@@ -17,6 +17,7 @@
*/
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {FormsModule} from '@angular/forms';
import {StoreModule} from '@ngrx/store';
import {TranslationModules} from '@app/test-config.spec';
import {HostsService, hosts} from '@app/services/storage/hosts.service';
@@ -34,7 +35,6 @@ import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {ComponentGeneratorService} from '@app/services/component-generator.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {DropdownListComponent} from './dropdown-list.component';
@@ -69,7 +69,8 @@ describe('DropdownListComponent', () => {
components,
serviceLogsTruncated,
tabs
- })
+ }),
+ FormsModule
],
providers: [
ComponentGeneratorService,
@@ -78,7 +79,6 @@ describe('DropdownListComponent', () => {
provide: HttpClientService,
useValue: httpClient
},
- FilteringService,
ComponentActionsService,
HostsService,
AuditLogsService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
index 3e40455..f9ae154 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
@@ -33,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
import {HttpClientService} from '@app/services/http-client.service';
import {LogsContainerService} from '@app/services/logs-container.service';
@@ -86,7 +85,6 @@ describe('FilterButtonComponent', () => {
ServiceLogsTruncatedService,
TabsService,
ComponentActionsService,
- FilteringService,
UtilsService,
{
provide: HttpClientService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
index 2c8ecd7..2dcecd1 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
@@ -41,34 +41,35 @@ export class FilterButtonComponent extends MenuButtonComponent implements Contro
super(actions);
}
- @Input()
- defaultValue?: string;
-
- private selectedValue: any;
+ private selectedItems: ListItem[] = [];
private onChange: (fn: any) => void;
- get value(): any {
- return this.selectedValue;
+ get selection(): ListItem[] {
+ return this.selectedItems;
}
- set value(newValue: any) {
- this.selectedValue = newValue;
- this.onChange(newValue);
+ set selection(items: ListItem[]) {
+ this.selectedItems = items;
+ if (this.onChange) {
+ this.onChange(items);
+ }
}
- updateValue(options: ListItem): void {
- const value = options && options.value;
+ updateSelection(item: ListItem): void {
if (this.isMultipleChoice) {
- this.value = this.utils.updateMultiSelectValue(this.value, value, options.isChecked);
- } else {
- if (this.utils.valueHasChanged(this.selectedValue, value)) {
- this.value = value;
- }
+ this.subItems.find((option: ListItem): boolean => {
+ return this.utils.isEqual(option.value, item.value);
+ }).isChecked = item.isChecked;
+ const checkedItems = this.subItems.filter((option: ListItem): boolean => option.isChecked);
+ this.selection = checkedItems;
+ } else if (!this.utils.isEqual(this.selection[0], item)) {
+ this.selection = [item];
}
}
- writeValue() {
+ writeValue(items: ListItem[]) {
+ this.selection = items;
}
registerOnChange(callback: any): void {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
index c294e8e..f9192f4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
@@ -28,7 +28,9 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {ClustersService, clusters} from '@app/services/storage/clusters.service';
+import {ComponentsService, components} from '@app/services/storage/components.service';
+import {HostsService, hosts} from '@app/services/storage/hosts.service';
import {UtilsService} from '@app/services/utils.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {LogsContainerService} from '@app/services/logs-container.service';
@@ -77,7 +79,10 @@ describe('FilterDropdownComponent', () => {
serviceLogsFields,
serviceLogsHistogramData,
serviceLogsTruncated,
- tabs
+ tabs,
+ clusters,
+ components,
+ hosts
}),
...TranslationModules
],
@@ -91,8 +96,11 @@ describe('FilterDropdownComponent', () => {
ServiceLogsHistogramDataService,
ServiceLogsTruncatedService,
TabsService,
+ ClustersService,
+ ComponentsService,
+ HostsService,
{
- provide: FilteringService,
+ provide: LogsContainerService,
useValue: filtering
},
UtilsService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
index 9e5a6f1..d677d81 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
@@ -20,6 +20,7 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {UtilsService} from '@app/services/utils.service';
import {DropdownButtonComponent} from '@app/components/dropdown-button/dropdown-button.component';
+import {ListItem} from '@app/classes/list-item';
@Component({
selector: 'filter-dropdown',
@@ -41,16 +42,25 @@ export class FilterDropdownComponent extends DropdownButtonComponent implements
private onChange: (fn: any) => void;
- get value(): any {
- return this.selectedValue;
+ get selection(): ListItem[] {
+ return this.selectedItems;
}
- set value(newValue: any) {
- this.selectedValue = newValue;
- this.onChange(newValue);
+ set selection(items: ListItem[]) {
+ this.selectedItems = items;
+ if (this.isMultipleChoice) {
+ this.options.forEach((option: ListItem): void => {
+ const selectionItem = items.find((item: ListItem): boolean => this.utils.isEqual(item.value, option.value));
+ option.isChecked = Boolean(selectionItem);
+ });
+ }
+ if (this.onChange) {
+ this.onChange(items);
+ }
}
- writeValue() {
+ writeValue(items: ListItem[]) {
+ this.selection = items;
}
registerOnChange(callback: any): void {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
index fa739a4..2d327a6 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
@@ -17,13 +17,13 @@
<form [formGroup]="filtersForm">
<div class="form-inline filter-input-container col-md-8">
- <filter-dropdown [label]="filters.clusters.label" formControlName="clusters" [options]="filters.clusters.options"
- [defaultLabel]="filters.clusters.defaultLabel" [isMultipleChoice]="true"
+ <filter-dropdown *ngIf="isFilterConditionDisplayed('clusters')" [label]="filters.clusters.label"
+ formControlName="clusters" [options]="filters.clusters.options" [isMultipleChoice]="true"
class="filter-input"></filter-dropdown>
<search-box formControlName="query" [items]="searchBoxItemsTranslated" class="filter-input"
[parameterNameChangeSubject]="queryParameterNameChange"
[parameterAddSubject]="queryParameterAdd"></search-box>
- <time-range-picker formControlName="timeRange" [defaultLabel]="filters.timeRange.defaultLabel"
+ <time-range-picker *ngIf="isFilterConditionDisplayed('timeRange')" formControlName="timeRange"
class="filter-input"></time-range-picker>
<timezone-picker class="filter-input"></timezone-picker>
<!--button class="btn btn-success" type="button">
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
index 0bb0204..1f7e8db 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
@@ -18,6 +18,7 @@
import {NO_ERRORS_SCHEMA} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {FormGroup, FormControl} from '@angular/forms';
import {TranslationModules} from '@app/test-config.spec';
import {StoreModule} from '@ngrx/store';
import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
@@ -32,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
import {AppStateService, appState} from '@app/services/storage/app-state.service';
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
import {UtilsService} from '@app/services/utils.service';
import {LogsContainerService} from '@app/services/logs-container.service';
@@ -88,7 +88,6 @@ describe('FiltersPanelComponent', () => {
AppStateService,
ServiceLogsTruncatedService,
TabsService,
- FilteringService,
LogsContainerService,
{
provide: HttpClientService,
@@ -104,6 +103,9 @@ describe('FiltersPanelComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(FiltersPanelComponent);
component = fixture.componentInstance;
+ component.filtersForm = new FormGroup({
+ control: new FormControl()
+ });
fixture.detectChanges();
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
index 9601a0e..3314252 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
@@ -21,10 +21,8 @@ import {FormGroup} from '@angular/forms';
import {Subject} from 'rxjs/Subject';
import {TranslateService} from '@ngx-translate/core';
import {ListItem} from '@app/classes/list-item';
-import {filtersFormItemsMap} from '@app/classes/filtering';
import {CommonEntry} from '@app/classes/models/common-entry';
import {LogField} from '@app/classes/models/log-field';
-import {FilteringService} from '@app/services/filtering.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {AppStateService} from '@app/services/storage/app-state.service';
@@ -35,7 +33,10 @@ import {AppStateService} from '@app/services/storage/app-state.service';
})
export class FiltersPanelComponent {
- constructor(private translate: TranslateService, private filtering: FilteringService, private logsContainer: LogsContainerService, private appState: AppStateService) {
+ constructor(
+ private translate: TranslateService, private logsContainer: LogsContainerService,
+ private appState: AppStateService
+ ) {
appState.getParameter('activeLogsType').subscribe(value => {
this.logsType = value;
logsContainer.logsTypeMap[value].fieldsModel.getAll().subscribe((fields: LogField[]): void => {
@@ -80,23 +81,24 @@ export class FiltersPanelComponent {
searchBoxItemsTranslated: CommonEntry[] = [];
get filters(): any {
- return this.filtering.filters;
+ return this.logsContainer.filters;
}
get queryParameterNameChange(): Subject<any> {
- return this.filtering.queryParameterNameChange;
+ return this.logsContainer.queryParameterNameChange;
}
get queryParameterAdd(): Subject<any> {
- return this.filtering.queryParameterAdd;
+ return this.logsContainer.queryParameterAdd;
}
get captureSeconds(): number {
- return this.filtering.captureSeconds;
+ return this.logsContainer.captureSeconds;
}
isFilterConditionDisplayed(key: string): boolean {
- return filtersFormItemsMap[this.logsType].indexOf(key) > -1;
+ return this.logsContainer.filtersFormItemsMap[this.logsType].indexOf(key) > -1
+ && Boolean(this.filtersForm.controls[key]);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
index 4e9bdc9..7bd87ad 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
@@ -34,7 +34,6 @@ import {TranslationModules} from '@app/test-config.spec';
import {ModalComponent} from '@app/components/modal/modal.component';
import {LogsContainerService} from '@app/services/logs-container.service';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
import {LogContextComponent} from './log-context.component';
@@ -90,8 +89,7 @@ describe('LogContextComponent', () => {
{
provide: HttpClientService,
useValue: httpClient
- },
- FilteringService
+ }
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
index 0a9418f..2bb8731 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
@@ -33,7 +33,6 @@ import {HostsService, hosts} from '@app/services/storage/hosts.service';
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {TabsComponent} from '@app/components/tabs/tabs.component';
@@ -92,7 +91,6 @@ describe('LogsContainerComponent', () => {
HostsService,
ServiceLogsTruncatedService,
TabsService,
- FilteringService,
UtilsService,
LogsContainerService
],
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
index 21949f1..f8acd50 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
@@ -22,7 +22,6 @@ import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/takeUntil';
-import {FilteringService} from '@app/services/filtering.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service';
import {AppStateService} from '@app/services/storage/app-state.service';
@@ -43,9 +42,11 @@ import {ListItem} from '@app/classes/list-item';
})
export class LogsContainerComponent {
- constructor(private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private appState: AppStateService, private tabsStorage: TabsService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
+ constructor(
+ private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private appState: AppStateService,
+ private tabsStorage: TabsService, private logsContainer: LogsContainerService
+ ) {
this.logsContainer.loadColumnsNames();
- this.logsTypeChange.first().subscribe(() => this.logsContainer.loadLogs());
appState.getParameter('activeLogsType').subscribe((value: string): void => {
this.logsType = value;
this.logsTypeChange.next();
@@ -75,11 +76,6 @@ export class LogsContainerComponent {
this.displayedColumns = columns.filter((column: LogField): boolean => column.isAvailable && column.isDisplayed);
});
});
- appState.getParameter('activeFiltersForm').subscribe((form: FormGroup): void => {
- this.filtersFormChange.next();
- form.valueChanges.takeUntil(this.filtersFormChange).subscribe(() => this.logsContainer.loadLogs());
- this.filtersForm = form;
- });
serviceLogsHistogramStorage.getAll().subscribe((data: BarGraph[]): void => {
this.histogramData = this.logsContainer.getHistogramData(data);
});
@@ -88,12 +84,12 @@ export class LogsContainerComponent {
tabs: Observable<Tab[]> = this.tabsStorage.getAll();
- filtersForm: FormGroup;
+ get filtersForm(): FormGroup {
+ return this.logsContainer.filtersForm;
+ };
private logsType: string;
- private filtersFormChange: Subject<any> = new Subject();
-
private logsTypeChange: Subject<any> = new Subject();
get logsTypeMapObject(): any {
@@ -117,10 +113,10 @@ export class LogsContainerComponent {
};
get autoRefreshRemainingSeconds(): number {
- return this.filtering.autoRefreshRemainingSeconds;
+ return this.logsContainer.autoRefreshRemainingSeconds;
}
- get autoRefreshMessageParams(): any {
+ get autoRefreshMessageParams(): object {
return {
remainingSeconds: this.autoRefreshRemainingSeconds
};
@@ -133,7 +129,7 @@ export class LogsContainerComponent {
get totalEventsFoundMessageParams(): object {
return {
totalCount: this.totalCount
- }
+ };
}
isServiceLogContextView: boolean = false;
@@ -147,7 +143,7 @@ export class LogsContainerComponent {
}
setCustomTimeRange(startTime: number, endTime: number): void {
- this.filtering.setCustomTimeRange(startTime, endTime);
+ this.logsContainer.setCustomTimeRange(startTime, endTime);
}
onSwitchTab(activeTab: Tab): void {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
index 10f4af1..7de0b96 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
@@ -17,8 +17,7 @@
<form *ngIf="logs && logs.length" [formGroup]="filtersForm" class="row pull-right">
<filter-dropdown [label]="filters.sorting.label" formControlName="sorting" [options]="filters.sorting.options"
- [defaultLabel]="filters.sorting.defaultLabel" [isRightAlign]="true"
- class="col-md-12"></filter-dropdown>
+ [isRightAlign]="true" class="col-md-12"></filter-dropdown>
</form>
<div class="panel panel-default">
<div class="panel-body">
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
index 8ee4ca3..21c4f02 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
@@ -28,8 +28,13 @@ import {AppStateService, appState} from '@app/services/storage/app-state.service
import {ClustersService, clusters} from '@app/services/storage/clusters.service';
import {ComponentsService, components} from '@app/services/storage/components.service';
import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service';
+import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
+import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
+import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
import {UtilsService} from '@app/services/utils.service';
import {LogsListComponent} from './logs-list.component';
@@ -57,7 +62,12 @@ describe('LogsListComponent', () => {
appState,
clusters,
components,
- hosts
+ hosts,
+ auditLogsFields,
+ serviceLogsFields,
+ serviceLogsHistogramData,
+ serviceLogsTruncated,
+ tabs
}),
MomentModule,
MomentTimezoneModule,
@@ -75,7 +85,12 @@ describe('LogsListComponent', () => {
ClustersService,
ComponentsService,
HostsService,
- FilteringService,
+ AuditLogsFieldsService,
+ ServiceLogsFieldsService,
+ ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
+ TabsService,
+ LogsContainerService,
UtilsService
],
schemas: [NO_ERRORS_SCHEMA]
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
index 017bc82..3a56fca 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
@@ -18,7 +18,7 @@
import {Component, AfterViewInit, Input, ViewChild, ElementRef} from '@angular/core';
import {FormGroup} from '@angular/forms';
import 'rxjs/add/operator/map';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
import {UtilsService} from '@app/services/utils.service';
import {AuditLog} from '@app/classes/models/audit-log';
import {ServiceLog} from '@app/classes/models/service-log';
@@ -31,7 +31,7 @@ import {LogField} from '@app/classes/models/log-field';
})
export class LogsListComponent implements AfterViewInit {
- constructor(private filtering: FilteringService, private utils: UtilsService) {
+ constructor(private logsContainer: LogsContainerService, private utils: UtilsService) {
}
ngAfterViewInit() {
@@ -104,11 +104,11 @@ export class LogsListComponent implements AfterViewInit {
readonly timeFormat: string = 'h:mm:ss A';
get timeZone(): string {
- return this.filtering.timeZone;
+ return this.logsContainer.timeZone;
}
get filters(): any {
- return this.filtering.filters;
+ return this.logsContainer.filters;
}
isDifferentDates(dateA, dateB): boolean {
@@ -135,7 +135,7 @@ export class LogsListComponent implements AfterViewInit {
}
updateQuery(event: any) {
- this.filtering.queryParameterAdd.next({
+ this.logsContainer.queryParameterAdd.next({
name: this.messageFilterParameterName,
value: this.selectedText,
isExclude: event.value
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
index 261e213..71bbf67 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
@@ -33,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
import {LogsContainerService} from '@app/services/logs-container.service';
@@ -85,7 +84,6 @@ describe('MenuButtonComponent', () => {
ServiceLogsTruncatedService,
TabsService,
ComponentActionsService,
- FilteringService,
{
provide: HttpClientService,
useValue: httpClient
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
index 5932e1b..ca89935 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
@@ -202,11 +202,11 @@ export class MenuButtonComponent {
* @param {ListItem} options The selected item(s) from the dropdown list.
*/
onDropdownItemChange(options: ListItem) {
- this.updateValue(options);
+ this.updateSelection(options);
!this.isMultipleChoice && this.closeDropdown();
}
- updateValue(options: ListItem) {
+ updateSelection(options: ListItem) {
// TODO implement value change behaviour
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
index 81676a9..5f85da7 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
@@ -54,7 +54,9 @@ export class PaginationControlsComponent implements ControlValueAccessor {
if (this.isValidValue(newValue)) { // this is the last validation check
this.currentPage = newValue;
this.currentPageChange.emit(newValue);
- this.onChange(newValue);
+ if (this.onChange) {
+ this.onChange(newValue);
+ }
} else {
throw new Error(`Invalid value ${newValue}. The currentPage should be between 0 and ${this.pagesCount}.`);
}
@@ -121,7 +123,8 @@ export class PaginationControlsComponent implements ControlValueAccessor {
return this.pagesCount > 0 && this.value > 0;
}
- writeValue() {
+ writeValue(value: number) {
+ this.value = value;
}
registerOnChange(callback: any): void {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
index 679a7e5..4be0a47 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
@@ -17,7 +17,7 @@
<form class="pagination-form" [formGroup]="filtersForm">
<filter-dropdown [label]="filterInstance.label" formControlName="pageSize" [options]="filterInstance.options"
- [defaultLabel]="filterInstance.defaultLabel" [isRightAlign]="true" isDropup="true"></filter-dropdown>
+ [isRightAlign]="true" [isDropup]="true"></filter-dropdown>
<span>{{'pagination.numbers' | translate: numbersTranslateParams}}</span>
<pagination-controls formControlName="page" [totalCount]="totalCount" [pagesCount]="pagesCount"
(currentPageChange)="setCurrentPage($event)"></pagination-controls>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
index ff8675d..c820027 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
@@ -39,7 +39,14 @@ describe('PaginationComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(PaginationComponent);
component = fixture.componentInstance;
- component.filterInstance = {};
+ component.filterInstance = {
+ defaultSelection: [
+ {
+ label: '10',
+ value: '10'
+ }
+ ]
+ };
component.filtersForm = new FormGroup({
pageSize: new FormControl()
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
index cc5589f..890c2ee 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
@@ -18,6 +18,8 @@
import {Component, OnInit, Input} from '@angular/core';
import {FormGroup} from '@angular/forms';
+import {ListItem} from '@app/classes/list-item';
+import {FilterCondition} from '@app/classes/filtering';
@Component({
selector: 'pagination',
@@ -27,9 +29,9 @@ import {FormGroup} from '@angular/forms';
export class PaginationComponent implements OnInit {
ngOnInit() {
- this.setPageSizeFromString(this.filterInstance.defaultValue);
- this.filtersForm.controls.pageSize.valueChanges.subscribe((value: string): void => {
- this.setPageSizeFromString(value);
+ this.setPageSizeFromString(this.filterInstance.defaultSelection[0].value);
+ this.filtersForm.controls.pageSize.valueChanges.subscribe((selection: ListItem): void => {
+ this.setPageSizeFromString(selection[0].value);
});
}
@@ -37,7 +39,7 @@ export class PaginationComponent implements OnInit {
filtersForm: FormGroup;
@Input()
- filterInstance: any;
+ filterInstance: FilterCondition;
@Input()
currentCount?: number;
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
index 5520310..18ff715 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
@@ -159,7 +159,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
this.isValueInput = true;
this.currentValue = '';
setTimeout(() => this.valueInput.focus(), 0);
- }
+ };
onParameterValueChange(event: KeyboardEvent): void {
if (this.utils.isEnterPressed(event) && this.currentValue) {
@@ -187,7 +187,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
isExclude: options.isExclude
});
this.updateValue();
- }
+ };
removeParameter(event: MouseEvent, id: number): void {
this.parameters = this.parameters.filter(parameter => parameter.id !== id);
@@ -196,10 +196,14 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
}
updateValue() {
- this.onChange(this.parameters);
+ if (this.onChange) {
+ this.onChange(this.parameters);
+ }
}
- writeValue() {
+ writeValue(parameters: any [] = []) {
+ this.parameters = parameters;
+ this.updateValue();
}
registerOnChange(callback: any): void {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
index 973db61..621f995 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
@@ -16,7 +16,8 @@
-->
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown">
- {{selectedLabel | translate}} <span class="caret"></span>
+ <span *ngIf="selection">{{selection.label | translate}}</span>
+ <span class="caret"></span>
</button>
<div class="dropdown-menu row col-md-12">
<div class="col-md-4" (click)="$event.stopPropagation()">
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
index 7612cc3..43e4bd5 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
@@ -25,8 +25,15 @@ import {AppStateService, appState} from '@app/services/storage/app-state.service
import {ClustersService, clusters} from '@app/services/storage/clusters.service';
import {ComponentsService, components} from '@app/services/storage/components.service';
import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {AuditLogsService, auditLogs} from '@app/services/storage/audit-logs.service';
+import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service';
+import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-logs.service';
+import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
+import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
+import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
import {TimeRangePickerComponent} from './time-range-picker.component';
@@ -51,7 +58,14 @@ describe('TimeRangePickerComponent', () => {
appState,
clusters,
components,
- hosts
+ hosts,
+ auditLogs,
+ auditLogsFields,
+ serviceLogs,
+ serviceLogsFields,
+ serviceLogsHistogramData,
+ serviceLogsTruncated,
+ tabs
}),
...TranslationModules
],
@@ -60,12 +74,19 @@ describe('TimeRangePickerComponent', () => {
provide: HttpClientService,
useValue: httpClient
},
- FilteringService,
+ LogsContainerService,
AppSettingsService,
AppStateService,
ClustersService,
ComponentsService,
- HostsService
+ HostsService,
+ AuditLogsService,
+ AuditLogsFieldsService,
+ ServiceLogsService,
+ ServiceLogsFieldsService,
+ ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
+ TabsService
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
index af4933a..cacabc3 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
@@ -16,10 +16,10 @@
* limitations under the License.
*/
-import {Component, OnInit, Input, forwardRef} from '@angular/core';
+import {Component, forwardRef} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {Moment} from 'moment';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
import {ListItem} from '@app/classes/list-item';
import {TimeUnitListItem} from '@app/classes/filtering';
@@ -35,20 +35,11 @@ import {TimeUnitListItem} from '@app/classes/filtering';
}
]
})
-export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
+export class TimeRangePickerComponent implements ControlValueAccessor {
- constructor(private filtering: FilteringService) {
+ constructor(private logsContainer: LogsContainerService) {
}
- ngOnInit() {
- this.selectedLabel = this.defaultLabel;
- }
-
- @Input()
- defaultLabel?: string;
-
- selectedLabel: string;
-
startTime: Moment;
endTime: Moment;
@@ -56,18 +47,20 @@ export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
private onChange: (fn: any) => void;
get quickRanges(): (ListItem | TimeUnitListItem[])[] {
- return this.filtering.filters.timeRange.options;
+ return this.logsContainer.filters.timeRange.options;
}
- private timeRange?: any;
+ private timeRange?: TimeUnitListItem;
- get value(): any {
+ get selection(): TimeUnitListItem {
return this.timeRange;
}
- set value(newValue: any) {
+ set selection(newValue: TimeUnitListItem) {
this.timeRange = newValue;
- this.onChange(newValue);
+ if (this.onChange) {
+ this.onChange(newValue);
+ }
}
setStartTime(timeObject: Moment): void {
@@ -79,20 +72,22 @@ export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
}
setTimeRange(value: any, label: string) {
- this.value = value;
- this.selectedLabel = label;
+ this.selection = {label, value};
}
setCustomTimeRange() {
- this.value = {
- type: 'CUSTOM',
- start: this.startTime,
- end: this.endTime
+ this.selection = {
+ label: 'filter.timeRange.custom',
+ value: {
+ type: 'CUSTOM',
+ start: this.startTime,
+ end: this.endTime
+ }
};
- this.selectedLabel = 'filter.timeRange.custom';
}
- writeValue() {
+ writeValue(selection: TimeUnitListItem) {
+ this.selection = selection;
}
registerOnChange(callback: any): void {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
index 53afc47..0e4c8a8 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {TimeZoneAbbrPipe} from '@app/pipes/timezone-abbr.pipe';
@@ -90,7 +89,6 @@ describe('TimeZonePickerComponent', () => {
ServiceLogsTruncatedService,
TabsService,
ComponentActionsService,
- FilteringService,
{
provide: HttpClientService,
useValue: httpClient
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
index e6a02c0..6f54e65 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
@@ -30,7 +30,6 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
import {LogsContainerService} from '@app/services/logs-container.service';
@@ -78,7 +77,6 @@ describe('ComponentActionsService', () => {
ServiceLogsHistogramDataService,
ServiceLogsTruncatedService,
TabsService,
- FilteringService,
{
provide: HttpClientService,
useValue: httpClient
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
index c483cd8..73fc94c 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
@@ -20,15 +20,17 @@ import {Injectable} from '@angular/core';
import {AppSettingsService} from '@app/services/storage/app-settings.service';
import {TabsService} from '@app/services/storage/tabs.service';
import {CollectionModelService} from '@app/classes/models/store';
-import {FilteringService} from '@app/services/filtering.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {ServiceLog} from '@app/classes/models/service-log';
-import {getFiltersForm} from '@app/classes/filtering';
+import {ListItem} from '@app/classes/list-item';
@Injectable()
export class ComponentActionsService {
- constructor(private appSettings: AppSettingsService, private tabsStorage: TabsService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
+ constructor(
+ private appSettings: AppSettingsService, private tabsStorage: TabsService,
+ private logsContainer: LogsContainerService
+ ) {
}
//TODO implement actions
@@ -81,7 +83,6 @@ export class ComponentActionsService {
const tab = {
id: log.id,
type: 'serviceLogs',
- isActive: true,
isCloseable: true,
label: `${log.host} >> ${log.type}`,
appState: {
@@ -92,7 +93,14 @@ export class ComponentActionsService {
host_name: log.host,
component_name: log.type
},
- activeFiltersForm: getFiltersForm('serviceLogs')
+ activeFilters: Object.assign(this.logsContainer.getFiltersData('serviceLogs'), {
+ components: this.logsContainer.filters.components.options.find((option: ListItem): boolean => {
+ return option.value === log.type;
+ }),
+ hosts: this.logsContainer.filters.hosts.options.find((option: ListItem): boolean => {
+ return option.value === log.host;
+ })
+ })
}
};
this.tabsStorage.addInstance(tab);
@@ -104,11 +112,11 @@ export class ComponentActionsService {
}
startCapture(): void {
- this.filtering.startCaptureTimer();
+ this.logsContainer.startCaptureTimer();
}
stopCapture(): void {
- this.filtering.stopCaptureTimer();
+ this.logsContainer.stopCaptureTimer();
}
setTimeZone(timeZone: string): void {
@@ -121,7 +129,7 @@ export class ComponentActionsService {
}));
}
- proceedWithExclude = (item: string): void => this.filtering.queryParameterNameChange.next({
+ proceedWithExclude = (item: string): void => this.logsContainer.queryParameterNameChange.next({
item: item,
isExclude: true
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
index 5dc38b4..a161190 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/s
import {TabsService, tabs} from '@app/services/storage/tabs.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
import {ComponentGeneratorService} from './component-generator.service';
@@ -70,7 +69,6 @@ describe('ComponentGeneratorService', () => {
provide: HttpClientService,
useValue: httpClient
},
- FilteringService,
HostsService,
AuditLogsService,
ServiceLogsService,
[35/51] [abbrv] ambari git commit: AMBARI-22389. Exclude test scope
jars from Log Search / Log Feeder rpm/deb packages (oleewere)
Posted by nc...@apache.org.
AMBARI-22389. Exclude test scope jars from Log Search / Log Feeder rpm/deb packages (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/444718a1
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/444718a1
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/444718a1
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 444718a10479c02dc6251ab8dc56eae70723f7bb
Parents: 38476f7
Author: Oliver Szabo <ol...@gmail.com>
Authored: Thu Nov 9 14:18:46 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Thu Nov 9 14:19:17 2017 +0100
----------------------------------------------------------------------
ambari-logsearch/ambari-logsearch-logfeeder/pom.xml | 2 +-
ambari-logsearch/ambari-logsearch-server/pom.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/444718a1/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
index 6b7d94f..01710bf 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
@@ -240,12 +240,12 @@
</goals>
<configuration>
- <artifactItems>*</artifactItems>
<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
<outputDirectory>${basedir}/target/libs</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
+ <includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
http://git-wip-us.apache.org/repos/asf/ambari/blob/444718a1/ambari-logsearch/ambari-logsearch-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/pom.xml b/ambari-logsearch/ambari-logsearch-server/pom.xml
index 2ad35f5..5444b00 100755
--- a/ambari-logsearch/ambari-logsearch-server/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-server/pom.xml
@@ -118,13 +118,13 @@
<goal>copy-dependencies</goal>
</goals>
<configuration>
- <artifactItems>*</artifactItems>
<excludeArtifactIds>ambari-logsearch-web</excludeArtifactIds>
<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
<outputDirectory>${basedir}/target/libs</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
+ <includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
[39/51] [abbrv] ambari git commit: AMBARI-22338 : Review Request for
new HDP StackFeatures entry(mradhakrishnan on behalf of ydavis)
Posted by nc...@apache.org.
AMBARI-22338 : Review Request for new HDP StackFeatures entry(mradhakrishnan on behalf of ydavis)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c693de36
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c693de36
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c693de36
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: c693de3650d9b115a3da7639dbd97931c6ebb61b
Parents: 430dcbf
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Authored: Thu Nov 9 11:09:32 2017 -0800
Committer: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Committed: Thu Nov 9 11:09:32 2017 -0800
----------------------------------------------------------------------
.../resources/stacks/HDP/2.0.6/properties/stack_features.json | 5 +++++
1 file changed, 5 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c693de36/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
index 86de20d..702fb13 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
@@ -427,6 +427,11 @@
"name": "hadoop_custom_extensions",
"description": "Support hadoop custom extensions",
"min_version": "2.6.0.0"
+ },
+ {
+ "name": "sam_storage_core_in_registry",
+ "description": "Storage core module moved to registry",
+ "min_version": "2.6.0.0"
}
]
}
[45/51] [abbrv] ambari git commit: AMBARI-22411. Restart all required
services failed when running cluster with several patch upgrades applied
(ncole)
Posted by nc...@apache.org.
AMBARI-22411. Restart all required services failed when running cluster with several patch upgrades applied (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/068d82f7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/068d82f7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/068d82f7
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 068d82f700432cf5cfa75d20924443e998d8fe87
Parents: ec02a14
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Nov 10 11:23:13 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Nov 10 12:00:14 2017 -0500
----------------------------------------------------------------------
.../AmbariCustomCommandExecutionHelper.java | 23 ++++----
.../AmbariManagementControllerImpl.java | 60 +++-----------------
.../internal/UpgradeResourceProvider.java | 8 +--
.../HDP/2.0.6/properties/stack_packages.json | 3 +-
.../AmbariManagementControllerImplTest.java | 2 +-
5 files changed, 25 insertions(+), 71 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index e8febbb..dc6bbb7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -1425,27 +1425,23 @@ public class AmbariCustomCommandExecutionHelper {
*
* @param actionExecContext the context
* @param cluster the cluster for the command
+ * @param stackId the stack id used to load service metainfo.
*
* @return a wrapper of the important JSON structures to add to a stage
*/
public ExecuteCommandJson getCommandJson(ActionExecutionContext actionExecContext,
- Cluster cluster, RepositoryVersionEntity repositoryVersion, String requestContext) throws AmbariException {
+ Cluster cluster, StackId stackId, String requestContext) throws AmbariException {
Map<String, String> commandParamsStage = StageUtils.getCommandParamsStage(actionExecContext, requestContext);
Map<String, String> hostParamsStage = new HashMap<>();
Map<String, Set<String>> clusterHostInfo;
String clusterHostInfoJson = "{}";
- StackId stackId = null;
- if (null != repositoryVersion) {
- stackId = repositoryVersion.getStackId();
- }
-
if (null != cluster) {
clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
// Important, because this runs during Stack Uprade, it needs to use the effective Stack Id.
- hostParamsStage = createDefaultHostParams(cluster, repositoryVersion);
+ hostParamsStage = createDefaultHostParams(cluster, stackId);
String componentName = null;
String serviceName = null;
@@ -1454,7 +1450,7 @@ public class AmbariCustomCommandExecutionHelper {
serviceName = actionExecContext.getOperationLevel().getServiceName();
}
- if (serviceName != null && componentName != null && null != stackId) {
+ if (serviceName != null && componentName != null) {
Service service = cluster.getService(serviceName);
ServiceComponent component = service.getServiceComponent(componentName);
stackId = component.getDesiredStackId();
@@ -1473,6 +1469,10 @@ public class AmbariCustomCommandExecutionHelper {
clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);
+ if (null == stackId && null != cluster) {
+ stackId = cluster.getDesiredStackVersion();
+ }
+
//Propogate HCFS service type info to command params
if (null != stackId) {
Map<String, ServiceInfo> serviceInfos = ambariMetaInfo.getServices(stackId.getStackName(),
@@ -1497,11 +1497,10 @@ public class AmbariCustomCommandExecutionHelper {
hostParamsStageJson);
}
- Map<String, String> createDefaultHostParams(Cluster cluster, RepositoryVersionEntity repositoryVersion) throws AmbariException {
- return createDefaultHostParams(cluster, repositoryVersion.getStackId());
- }
-
Map<String, String> createDefaultHostParams(Cluster cluster, StackId stackId) throws AmbariException {
+ if (null == stackId) {
+ stackId = cluster.getDesiredStackVersion();
+ }
TreeMap<String, String> hostLevelParams = new TreeMap<>();
StageUtils.useStackJdkIfExists(hostLevelParams, configs);
http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 380e1b4..4c00f1f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -68,6 +68,8 @@ import java.util.concurrent.TimeUnit;
import javax.persistence.RollbackException;
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterNotFoundException;
import org.apache.ambari.server.DuplicateResourceException;
@@ -2838,7 +2840,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
if (StringUtils.isBlank(stage.getHostParamsStage())) {
RepositoryVersionEntity repositoryVersion = serviceComponent.getDesiredRepositoryVersion();
stage.setHostParamsStage(StageUtils.getGson().toJson(
- customCommandExecutionHelper.createDefaultHostParams(cluster, repositoryVersion)));
+ customCommandExecutionHelper.createDefaultHostParams(cluster, repositoryVersion.getStackId())));
}
@@ -3186,7 +3188,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
Map<String, String> hostParamsCmd = customCommandExecutionHelper.createDefaultHostParams(
- cluster, scHost.getServiceComponent().getDesiredRepositoryVersion());
+ cluster, scHost.getServiceComponent().getDesiredStackId());
Stage stage = createNewStage(0, cluster, 1, "", clusterHostInfoJson, "{}", "");
@@ -4154,56 +4156,10 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
actionManager,
actionRequest);
- RepositoryVersionEntity desiredRepositoryVersion = null;
-
- RequestOperationLevel operationLevel = actionExecContext.getOperationLevel();
- if (null != operationLevel && StringUtils.isNotBlank(operationLevel.getServiceName())) {
- Service service = cluster.getService(operationLevel.getServiceName());
- if (null != service) {
- desiredRepositoryVersion = service.getDesiredRepositoryVersion();
- }
- }
-
- if (null == desiredRepositoryVersion && CollectionUtils.isNotEmpty(actionExecContext.getResourceFilters())) {
- Set<RepositoryVersionEntity> versions = new HashSet<>();
-
- for (RequestResourceFilter filter : actionExecContext.getResourceFilters()) {
- RepositoryVersionEntity repoVersion = null;
-
- if (StringUtils.isNotBlank(filter.getServiceName())) {
- Service service = cluster.getService(filter.getServiceName());
-
- if (StringUtils.isNotBlank(filter.getComponentName())) {
- ServiceComponent serviceComponent = service.getServiceComponent(filter.getComponentName());
-
- repoVersion = serviceComponent.getDesiredRepositoryVersion();
- }
-
- if (null == repoVersion) {
- repoVersion = service.getDesiredRepositoryVersion();
- }
- }
-
- if (null != repoVersion) {
- versions.add(repoVersion);
- }
- }
-
- if (1 == versions.size()) {
- desiredRepositoryVersion = versions.iterator().next();
- } else if (versions.size() > 1) {
- Set<String> errors = new HashSet<>();
- for (RepositoryVersionEntity version : versions) {
- errors.add(String.format("%s/%s", version.getStackId(), version.getVersion()));
- }
- throw new IllegalArgumentException(String.format("More than one repository is resolved with this Action: %s",
- StringUtils.join(errors, ';')));
- }
- }
-
-
- ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext,
- cluster, desiredRepositoryVersion, requestContext);
+ @Experimental(feature=ExperimentalFeature.MULTI_SERVICE,
+ comment = "This must change with Multi-Service since the cluster won't have a desired stack version")
+ ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext, cluster,
+ null == cluster ? null : cluster.getDesiredStackVersion(), requestContext);
String commandParamsForStage = jsons.getCommandParamsForStage();
http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index 14b1b86..d4111d6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -1073,7 +1073,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster, effectiveRepositoryVersion, null);
+ cluster, effectiveRepositoryVersion.getStackId(), null);
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getCommandParamsForStage(),
@@ -1155,7 +1155,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
actionContext.setMaintenanceModeHostExcluded(true);
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster, effectiveRepositoryVersion, null);
+ cluster, effectiveRepositoryVersion.getStackId(), null);
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getCommandParamsForStage(),
@@ -1220,7 +1220,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
actionContext.setMaintenanceModeHostExcluded(true);
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster, effectiveRepositoryVersion, null);
+ cluster, effectiveRepositoryVersion.getStackId(), null);
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getCommandParamsForStage(),
@@ -1361,7 +1361,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
actionContext.setMaintenanceModeHostExcluded(true);
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster, context.getRepositoryVersion(), null);
+ cluster, context.getRepositoryVersion().getStackId(), null);
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), stageText, jsons.getCommandParamsForStage(),
http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
index 23c6d32..68e6bf8 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
@@ -1277,8 +1277,7 @@
}
},
"upgrade-dependencies" : {
- "YARN": ["TEZ"],
- "TEZ": ["YARN"],
+ "HIVE": ["TEZ"],
"MAHOUT": ["MAPREDUCE2"]
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
index 9547271..94c5ebe 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
@@ -2138,7 +2138,7 @@ public class AmbariManagementControllerImplTest {
f.setAccessible(true);
f.set(helper, gson);
- Map<String, String> defaultHostParams = helper.createDefaultHostParams(cluster, repositoryVersionEntity);
+ Map<String, String> defaultHostParams = helper.createDefaultHostParams(cluster, repositoryVersionEntity.getStackId());
assertEquals(15, defaultHostParams.size());
assertEquals(MYSQL_JAR, defaultHostParams.get(DB_DRIVER_FILENAME));
[31/51] [abbrv] ambari git commit: AMBARI-22383. Remove
Auto-Installation of LZO Libraries (ncole)
Posted by nc...@apache.org.
AMBARI-22383. Remove Auto-Installation of LZO Libraries (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5adcea78
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5adcea78
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5adcea78
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 5adcea78792cf227f15e7c08f5bb3fe2c48883d3
Parents: b04e142
Author: Nate Cole <nc...@hortonworks.com>
Authored: Wed Nov 8 14:28:59 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Nov 8 14:51:48 2017 -0500
----------------------------------------------------------------------
.../libraries/functions/__init__.py | 1 -
.../libraries/functions/get_lzo_packages.py | 50 --------------------
.../libraries/functions/package_conditions.py | 8 +---
.../DRUID/0.10.1/package/scripts/druid.py | 3 +-
.../DRUID/0.10.1/package/scripts/params.py | 3 +-
.../common-services/HDFS/2.1.0.2.0/metainfo.xml | 30 ------------
.../HDFS/2.1.0.2.0/package/scripts/datanode.py | 1 -
.../HDFS/2.1.0.2.0/package/scripts/hdfs.py | 7 ---
.../2.1.0.2.0/package/scripts/hdfs_client.py | 1 -
.../2.1.0.2.0/package/scripts/install_params.py | 1 +
.../2.1.0.2.0/package/scripts/journalnode.py | 1 -
.../HDFS/2.1.0.2.0/package/scripts/namenode.py | 1 -
.../common-services/HDFS/3.0.0.3.0/metainfo.xml | 30 ------------
.../HDFS/3.0.0.3.0/package/scripts/hdfs.py | 7 ---
.../OOZIE/4.0.0.2.0/package/scripts/oozie.py | 6 +--
.../package/scripts/oozie_server_upgrade.py | 7 ++-
.../4.0.0.2.0/package/scripts/params_linux.py | 1 +
.../OOZIE/4.2.0.3.0/package/scripts/oozie.py | 4 --
.../package/scripts/oozie_server_upgrade.py | 5 ++
.../TEZ/0.4.0.2.1/package/scripts/tez_client.py | 32 -------------
.../TEZ/0.9.0.3.0/package/scripts/tez_client.py | 26 ----------
.../custom_actions/scripts/remove_bits.py | 2 +-
.../BIGTOP/0.8/services/HDFS/metainfo.xml | 16 -------
.../0.8/services/HDFS/package/scripts/params.py | 6 +--
.../stacks/HDP/2.2/services/HDFS/metainfo.xml | 35 --------------
.../2.3.GlusterFS/services/HDFS/metainfo.xml | 10 ----
.../stacks/HDP/2.3/services/HDFS/metainfo.xml | 30 ------------
.../stacks/HDP/3.0/services/HDFS/metainfo.xml | 30 ------------
.../python/custom_actions/TestRemoveBits.py | 5 +-
29 files changed, 20 insertions(+), 339 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py b/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
index f144b2d..1e388ac 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
@@ -39,7 +39,6 @@ from resource_management.libraries.functions.version import *
from resource_management.libraries.functions.format_jvm_option import *
from resource_management.libraries.functions.constants import *
from resource_management.libraries.functions.get_stack_version import *
-from resource_management.libraries.functions.get_lzo_packages import *
from resource_management.libraries.functions.setup_ranger_plugin import *
from resource_management.libraries.functions.curl_krb_request import *
from resource_management.libraries.functions.get_bare_principal import *
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py b/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py
deleted file mode 100644
index cfbb7d8..0000000
--- a/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-"""
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you 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.
-
-Ambari Agent
-
-"""
-__all__ = ["get_lzo_packages"]
-
-from ambari_commons.os_check import OSCheck
-from resource_management.libraries.functions.stack_features import check_stack_feature
-from resource_management.libraries.functions import StackFeature
-from resource_management.libraries.script.script import Script
-
-# TODO: Make list of lzo packages stack driven
-def get_lzo_packages(stack_version_unformatted):
- lzo_packages = []
- script_instance = Script.get_instance()
- if OSCheck.is_suse_family() and int(OSCheck.get_os_major_version()) >= 12:
- lzo_packages += ["liblzo2-2", "hadoop-lzo-native"]
- elif OSCheck.is_redhat_family() or OSCheck.is_suse_family():
- lzo_packages += ["lzo", "hadoop-lzo-native"]
- elif OSCheck.is_ubuntu_family():
- lzo_packages += ["liblzo2-2"]
-
- if stack_version_unformatted and check_stack_feature(StackFeature.ROLLING_UPGRADE, stack_version_unformatted):
- if OSCheck.is_ubuntu_family():
- lzo_packages += [script_instance.format_package_name("hadooplzo-${stack_version}") ,
- script_instance.format_package_name("hadooplzo-${stack_version}-native")]
- else:
- lzo_packages += [script_instance.format_package_name("hadooplzo_${stack_version}"),
- script_instance.format_package_name("hadooplzo_${stack_version}-native")]
- else:
- lzo_packages += ["hadoop-lzo"]
-
- return lzo_packages
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
index 31e78b9..ded63cf 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
@@ -19,7 +19,7 @@ limitations under the License.
Ambari Agent
"""
-__all__ = ["is_lzo_enabled", "should_install_phoenix", "should_install_ams_collector", "should_install_ams_grafana",
+__all__ = ["should_install_phoenix", "should_install_ams_collector", "should_install_ams_grafana",
"should_install_mysql", "should_install_ranger_tagsync"]
import os
@@ -44,12 +44,6 @@ def _has_local_components(config, components, indicator_function = any):
def _has_applicable_local_component(config, components):
return _has_local_components(config, components, any)
-def should_install_lzo():
- config = Script.get_config()
- io_compression_codecs = default("/configurations/core-site/io.compression.codecs", None)
- lzo_enabled = io_compression_codecs is not None and "com.hadoop.compression.lzo" in io_compression_codecs.lower()
- return lzo_enabled
-
def should_install_phoenix():
phoenix_hosts = default('/clusterHostInfo/phoenix_query_server_hosts', [])
phoenix_enabled = default('/configurations/hbase-env/phoenix_sql_enabled', False)
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
index ec98c3c..bb872b9 100644
--- a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
+++ b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
@@ -115,8 +115,7 @@ def druid(upgrade_type=None, nodeType=None):
)
Logger.info(format("Created druid-{node_type_lowercase} jvm.config"))
# Handling hadoop Lzo jars if enable and node type is hadoop related eg Overlords and MMs
- if ['middleManager', 'overlord'].__contains__(node_type_lowercase) and params.lzo_enabled and len(
- params.lzo_packages) > 0:
+ if ['middleManager', 'overlord'].__contains__(node_type_lowercase) and params.lzo_enabled:
try:
Logger.info(
format(
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
index fd1cde6..141250d 100644
--- a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
@@ -18,7 +18,6 @@ limitations under the License.
"""
from ambari_commons import OSCheck
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
from resource_management.libraries.functions import conf_select
from resource_management.libraries.functions import stack_select
from resource_management.libraries.resources.hdfs_resource import HdfsResource
@@ -196,5 +195,5 @@ if has_metric_collector:
stack_version_unformatted = str(config['hostLevelParams']['stack_version'])
io_compression_codecs = default("/configurations/core-site/io.compression.codecs", None)
lzo_enabled = io_compression_codecs is not None and "com.hadoop.compression.lzo" in io_compression_codecs.lower()
-lzo_packages = get_lzo_packages(stack_version_unformatted)
+
hadoop_lib_home = stack_root + '/' + stack_version + '/hadoop/lib'
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
index 9979de4..6bbb583 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
@@ -244,11 +244,6 @@
<package>
<name>hadoop</name>
</package>
- <package>
- <name>hadoop-lzo</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
</packages>
</osSpecific>
@@ -265,16 +260,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>lzo</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadoop-lzo-native</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop-libhdfs</name>
</package>
<package>
@@ -296,16 +281,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadoop-lzo-native</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop-libhdfs</name>
</package>
</packages>
@@ -324,11 +299,6 @@
<name>libsnappy-dev</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop-hdfs</name>
</package>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
index c0abb15..a8b0f48 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
@@ -165,7 +165,6 @@ class DataNodeDefault(DataNode):
@OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
class DataNodeWindows(DataNode):
def install(self, env):
- import install_params
self.install_packages(env)
if __name__ == "__main__":
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
index 4022986..1d7fe53 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
@@ -26,7 +26,6 @@ from resource_management.core.source import Template
from resource_management.core.resources.service import ServiceConfig
from resource_management.libraries.resources.xml_config import XmlConfig
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
from resource_management.core.exceptions import Fail
from resource_management.core.logger import Logger
from resource_management.libraries.functions.format import format
@@ -143,12 +142,6 @@ def hdfs(name=None):
content=Template("slaves.j2")
)
- if params.lzo_enabled:
- lzo_packages = get_lzo_packages(params.stack_version_unformatted)
- Package(lzo_packages,
- retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
- retry_count=params.agent_stack_retry_count)
-
def install_snappy():
import params
Directory([params.so_target_dir_x86, params.so_target_dir_x64],
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
index f2e96c3..a802e08 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
@@ -70,7 +70,6 @@ class HdfsClientDefault(HdfsClient):
@OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
class HdfsClientWindows(HdfsClient):
def install(self, env):
- import install_params
self.install_packages(env)
self.configure(env)
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
index 235f231..72850b3 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
@@ -18,6 +18,7 @@ limitations under the License.
"""
from ambari_commons import OSCheck
+exclude_packages = []
# These parameters are supposed to be referenced at installation time, before the Hadoop environment variables have been set
if OSCheck.is_windows_family():
exclude_packages = []
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
index 75b2eeb..eaa21e9 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
@@ -116,7 +116,6 @@ class JournalNodeDefault(JournalNode):
@OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
class JournalNodeWindows(JournalNode):
def install(self, env):
- import install_params
self.install_packages(env)
def start(self, env):
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
index 291da05..5f4152d 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
@@ -327,7 +327,6 @@ class NameNodeDefault(NameNode):
@OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
class NameNodeWindows(NameNode):
def install(self, env):
- import install_params
self.install_packages(env)
#TODO we need this for HA because of manual steps
self.configure(env)
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
index e6d1166..0c629f3 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
@@ -270,11 +270,6 @@
<package>
<name>hadoop</name>
</package>
- <package>
- <name>hadoop-lzo</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
</packages>
</osSpecific>
@@ -291,16 +286,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>lzo</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadoop-lzo-native</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop-libhdfs</name>
</package>
</packages>
@@ -319,16 +304,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadoop-lzo-native</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop-libhdfs</name>
</package>
</packages>
@@ -347,11 +322,6 @@
<name>libsnappy-dev</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop-hdfs</name>
</package>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
index 4022986..89f9a1c 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
@@ -26,7 +26,6 @@ from resource_management.core.source import Template
from resource_management.core.resources.service import ServiceConfig
from resource_management.libraries.resources.xml_config import XmlConfig
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
from resource_management.core.exceptions import Fail
from resource_management.core.logger import Logger
from resource_management.libraries.functions.format import format
@@ -142,12 +141,6 @@ def hdfs(name=None):
owner=tc_owner,
content=Template("slaves.j2")
)
-
- if params.lzo_enabled:
- lzo_packages = get_lzo_packages(params.stack_version_unformatted)
- Package(lzo_packages,
- retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
- retry_count=params.agent_stack_retry_count)
def install_snappy():
import params
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
index f215a1e..cd94244 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
@@ -37,7 +37,6 @@ from resource_management.libraries.functions.copy_tarball import get_current_ver
from resource_management.libraries.resources.xml_config import XmlConfig
from resource_management.libraries.script.script import Script
from resource_management.libraries.functions.security_commons import update_credential_provider_path
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
from resource_management.core.resources.packaging import Package
from resource_management.core.shell import as_user, as_sudo, call, checked_call
from resource_management.core.exceptions import Fail
@@ -306,11 +305,8 @@ def oozie_server_specific(upgrade_type):
Execute(format('{sudo} chown {oozie_user}:{user_group} {oozie_libext_dir}/falcon-oozie-el-extension-*.jar'),
not_if = no_op_test)
+ # just copying files is ok - we're not making assumptions about installing LZO here
if params.lzo_enabled:
- all_lzo_packages = get_lzo_packages(params.stack_version_unformatted)
- Package(all_lzo_packages,
- retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
- retry_count=params.agent_stack_retry_count)
Execute(format('{sudo} cp {hadoop_lib_home}/hadoop-lzo*.jar {oozie_lib_dir}'),
not_if = no_op_test,
)
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
index 23b39ef..c9c07d1 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
@@ -61,10 +61,15 @@ class OozieUpgrade(Script):
# <stack-selector-tool> set hadoop-client has not run yet, therefore we cannot use
# <stack-root>/current/hadoop-client ; we must use params.version directly
# however, this only works when upgrading beyond 2.2.0.0; don't do this
- # for downgrade to 2.2.0.0 since hadoop-lzo will not be present
+ # for downgrade to 2.2.0.0 since hadoop-lzo will not be present.
+ #
# This can also be called during a Downgrade.
+ #
# When a version is Installed, it is responsible for downloading the hadoop-lzo packages
# if lzo is enabled.
+ #
+ # This block is just copying around files - there is no assumption about installation
+ #
if params.lzo_enabled and (params.upgrade_direction == Direction.UPGRADE or target_version_needs_compression_libraries):
hadoop_lzo_pattern = 'hadoop-lzo*.jar'
hadoop_client_new_lib_dir = format("{stack_root}/{version}/hadoop/lib")
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
index a0f0672..40901b6 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
@@ -387,3 +387,4 @@ is_webhdfs_enabled = config['configurations']['hdfs-site']['dfs.webhdfs.enabled'
# The logic for LZO also exists in HDFS' params.py
io_compression_codecs = default("/configurations/core-site/io.compression.codecs", None)
lzo_enabled = io_compression_codecs is not None and "com.hadoop.compression.lzo" in io_compression_codecs.lower()
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
index 0771e93..19912fd 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
@@ -276,10 +276,6 @@ def oozie_server_specific():
not_if = no_op_test)
if params.lzo_enabled:
- all_lzo_packages = get_lzo_packages(params.stack_version_unformatted)
- Package(all_lzo_packages,
- retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
- retry_count=params.agent_stack_retry_count)
Execute(format('{sudo} cp {hadoop_lib_home}/hadoop-lzo*.jar {oozie_lib_dir}'),
not_if = no_op_test,
)
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
index 402c7cb..4fc1a42 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
@@ -62,9 +62,14 @@ class OozieUpgrade(Script):
# <stack-root>/current/hadoop-client ; we must use params.version directly
# however, this only works when upgrading beyond 2.2.0.0; don't do this
# for downgrade to 2.2.0.0 since hadoop-lzo will not be present
+ #
# This can also be called during a Downgrade.
+ #
# When a version is Installed, it is responsible for downloading the hadoop-lzo packages
# if lzo is enabled.
+ #
+ # This block is just copying around files - there is no assumption about installation
+ #
if params.lzo_enabled and (params.upgrade_direction == Direction.UPGRADE or target_version_needs_compression_libraries):
hadoop_lzo_pattern = 'hadoop-lzo*.jar'
hadoop_client_new_lib_dir = format("{stack_root}/{version}/hadoop/lib")
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
index ed3f5fd..dcf3e24 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
@@ -19,22 +19,15 @@ Ambari Agent
"""
import os
-import urlparse
from ambari_commons import OSConst
-from ambari_commons.inet_utils import download_file
from ambari_commons.os_family_impl import OsFamilyImpl
-from ambari_commons.os_utils import copy_file, extract_path_component
from resource_management.core.exceptions import ClientComponentHasNoStatus
-from resource_management.core.source import InlineTemplate
from resource_management.libraries.functions import stack_select
from resource_management.libraries.functions import StackFeature
from resource_management.libraries.functions.stack_features import check_stack_feature
-from resource_management.libraries.functions.get_stack_version import get_stack_version
from resource_management.libraries.script.script import Script
-from resource_management.libraries.functions.default import default
-from resource_management.core.logger import Logger
from tez import tez
@@ -96,33 +89,8 @@ class TezClientWindows(TezClient):
self.install_packages(env)
params.refresh_tez_state_dependent_params()
env.set_params(params)
- self._install_lzo_support_if_needed(params)
self.configure(env, config_dir=params.tez_conf_dir)
- def _install_lzo_support_if_needed(self, params):
- hadoop_classpath_prefix = self._expand_hadoop_classpath_prefix(params.hadoop_classpath_prefix_template, params.config['configurations']['tez-site'])
-
- hadoop_lzo_dest_path = extract_path_component(hadoop_classpath_prefix, "hadoop-lzo-")
- if hadoop_lzo_dest_path:
- hadoop_lzo_file = os.path.split(hadoop_lzo_dest_path)[1]
-
- config = Script.get_config()
- file_url = urlparse.urljoin(config['hostLevelParams']['jdk_location'], hadoop_lzo_file)
- hadoop_lzo_dl_path = os.path.join(config["hostLevelParams"]["agentCacheDir"], hadoop_lzo_file)
- download_file(file_url, hadoop_lzo_dl_path)
- #This is for protection against configuration changes. It will infect every new destination with the lzo jar,
- # but since the classpath points to the jar directly we're getting away with it.
- if not os.path.exists(hadoop_lzo_dest_path):
- copy_file(hadoop_lzo_dl_path, hadoop_lzo_dest_path)
-
- def _expand_hadoop_classpath_prefix(self, hadoop_classpath_prefix_template, configurations):
- import resource_management
-
- hadoop_classpath_prefix_obj = InlineTemplate(hadoop_classpath_prefix_template, configurations_dict=configurations,
- extra_imports=[resource_management, resource_management.core,
- resource_management.core.source])
- hadoop_classpath_prefix = hadoop_classpath_prefix_obj.get_content()
- return hadoop_classpath_prefix
if __name__ == "__main__":
TezClient().execute()
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
index b42d14e..0dfab4f 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
@@ -98,33 +98,7 @@ class TezClientWindows(TezClient):
self.install_packages(env)
params.refresh_tez_state_dependent_params()
env.set_params(params)
- self._install_lzo_support_if_needed(params)
self.configure(env, config_dir=params.tez_conf_dir)
- def _install_lzo_support_if_needed(self, params):
- hadoop_classpath_prefix = self._expand_hadoop_classpath_prefix(params.hadoop_classpath_prefix_template, params.config['configurations']['tez-site'])
-
- hadoop_lzo_dest_path = extract_path_component(hadoop_classpath_prefix, "hadoop-lzo-")
- if hadoop_lzo_dest_path:
- hadoop_lzo_file = os.path.split(hadoop_lzo_dest_path)[1]
-
- config = Script.get_config()
- file_url = urlparse.urljoin(config['hostLevelParams']['jdk_location'], hadoop_lzo_file)
- hadoop_lzo_dl_path = os.path.join(config["hostLevelParams"]["agentCacheDir"], hadoop_lzo_file)
- download_file(file_url, hadoop_lzo_dl_path)
- #This is for protection against configuration changes. It will infect every new destination with the lzo jar,
- # but since the classpath points to the jar directly we're getting away with it.
- if not os.path.exists(hadoop_lzo_dest_path):
- copy_file(hadoop_lzo_dl_path, hadoop_lzo_dest_path)
-
- def _expand_hadoop_classpath_prefix(self, hadoop_classpath_prefix_template, configurations):
- import resource_management
-
- hadoop_classpath_prefix_obj = InlineTemplate(hadoop_classpath_prefix_template, configurations_dict=configurations,
- extra_imports=[resource_management, resource_management.core,
- resource_management.core.source])
- hadoop_classpath_prefix = hadoop_classpath_prefix_obj.get_content()
- return hadoop_classpath_prefix
-
if __name__ == "__main__":
TezClient().execute()
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py b/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
index 0be9a34..078cf32 100644
--- a/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
+++ b/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
@@ -43,7 +43,7 @@ class RemoveBits(Script):
Logger.info("Attempting to remove bits for HDP 2.1")
config = Script.get_config()
- packages_to_remove = ["zookeeper", "hadoop", "hadoop-lzo", "hadoop-hdfs", "hadoop-libhdfs", "hadoop-yarn", "hadoop-client", "hadoop-mapreduce", "hive", "hive-hcatalog", "hive-jdbc", "hive-webhcat", "hcatalog", "webhcat-tar-hive", "webhcat-tar-pig", "oozie", "oozie-client", "pig", "sqoop", "tez" "falcon", "storm", "flume", "hbase", "phoenix"]
+ packages_to_remove = ["zookeeper", "hadoop", "hadoop-hdfs", "hadoop-libhdfs", "hadoop-yarn", "hadoop-client", "hadoop-mapreduce", "hive", "hive-hcatalog", "hive-jdbc", "hive-webhcat", "hcatalog", "webhcat-tar-hive", "webhcat-tar-pig", "oozie", "oozie-client", "pig", "sqoop", "tez" "falcon", "storm", "flume", "hbase", "phoenix"]
packages_to_remove.reverse()
Logger.info("Packages to remove: {0}".format(" ".join(packages_to_remove)))
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
index 8500839..f473598 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
@@ -180,10 +180,6 @@
<package>
<name>hadoop</name>
</package>
- <package>
- <name>hadoop-lzo</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
</packages>
</osSpecific>
@@ -197,14 +193,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>lzo</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
- <package>
- <name>hadoop-lzo-native</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
- <package>
<name>hadoop-libhdfs</name>
</package>
</packages>
@@ -220,10 +208,6 @@
<name>libsnappy-dev</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
- <package>
<name>hadoop-hdfs</name>
</package>
<package>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
index 3a711c7..f16242c 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
@@ -209,11 +209,7 @@ HdfsDirectory = functools.partial(
bin_dir = hadoop_bin_dir
)
-io_compression_codecs = config['configurations']['core-site']['io.compression.codecs']
-if not "com.hadoop.compression.lzo" in io_compression_codecs:
- exclude_packages = ["lzo", "hadoop-lzo", "hadoop-lzo-native", "liblzo2-2"]
-else:
- exclude_packages = []
+exclude_packages = []
name_node_params = default("/commandParams/namenode", None)
#hadoop params
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
index 8c2ec8b..d7221b9 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
@@ -40,19 +40,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>lzo</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}-native</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop_${stack_version}-libhdfs</name>
</package>
<package>
@@ -77,19 +64,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}-native</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop_${stack_version}-libhdfs</name>
</package>
</packages>
@@ -123,15 +97,6 @@
<name>libsnappy-dev</name>
</package>
<package>
- <name>hadooplzo-${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>libhdfs0-${stack_version}</name>
</package>
</packages>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
index 15fe931..6a9fab61 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
@@ -36,13 +36,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>lzo</name>
- <skipUpgrade>true</skipUpgrade>
- </package>
- <package>
- <name>hadooplzo_2_3_*</name>
- </package>
- <package>
<name>hadoop_2_3_*-libhdfs</name>
</package>
</packages>
@@ -76,9 +69,6 @@
<name>libsnappy-dev</name>
</package>
<package>
- <name>hadooplzo-2-3-.*</name>
- </package>
- <package>
<name>libhdfs0-2-3-.*</name>
</package>
</packages>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
index ccf9a4e..86531cc 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
@@ -72,19 +72,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>lzo</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}-native</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop_${stack_version}-libhdfs</name>
</package>
<package>
@@ -109,19 +96,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}-native</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop_${stack_version}-libhdfs</name>
</package>
</packages>
@@ -155,10 +129,6 @@
<name>libsnappy-dev</name>
</package>
<package>
- <name>hadooplzo-${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>libhdfs0-${stack_version}</name>
</package>
</packages>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
index 95a5f84..775508e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
@@ -50,19 +50,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>lzo</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}-native</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop_${stack_version}-libhdfs</name>
</package>
</packages>
@@ -84,19 +71,6 @@
<name>snappy-devel</name>
</package>
<package>
- <name>liblzo2-2</name>
- <skipUpgrade>true</skipUpgrade>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
- <name>hadooplzo_${stack_version}-native</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>hadoop_${stack_version}-libhdfs</name>
</package>
</packages>
@@ -130,10 +104,6 @@
<name>libsnappy-dev</name>
</package>
<package>
- <name>hadooplzo-${stack_version}</name>
- <condition>should_install_lzo</condition>
- </package>
- <package>
<name>libhdfs0-${stack_version}</name>
</package>
</packages>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/custom_actions/TestRemoveBits.py b/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
index 6537152..8217ca0 100644
--- a/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
+++ b/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
@@ -105,13 +105,10 @@ class TestRemoveBits(RMFTestCase):
self.assertResourceCalled('Package', 'hadoop-hdfs',
action = ['remove'],
)
- self.assertResourceCalled('Package', 'hadoop-lzo',
- action = ['remove'],
- )
self.assertResourceCalled('Package', 'hadoop',
action = ['remove'],
)
self.assertResourceCalled('Package', 'zookeeper',
action = ['remove'],
)
- self.assertNoMoreResources()
\ No newline at end of file
+ self.assertNoMoreResources()
[13/51] [abbrv] ambari git commit: AMBARI-22362 - Specify the Correct
HIVE_BIN In Hive Scripts (jonathanhurley)
Posted by nc...@apache.org.
AMBARI-22362 - Specify the Correct HIVE_BIN In Hive Scripts (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/afb9a66e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/afb9a66e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/afb9a66e
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: afb9a66e24d718a17be87af412a44d4def7273a3
Parents: 65ea560
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Nov 3 10:07:54 2017 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Nov 3 14:25:36 2017 -0400
----------------------------------------------------------------------
.../0.12.0.2.0/package/files/startMetastore.sh | 4 ++--
.../0.12.0.2.0/package/scripts/hive_service.py | 10 ++--------
.../0.12.0.2.0/package/scripts/params_linux.py | 3 +--
.../0.12.0.2.0/package/scripts/service_check.py | 6 ++----
.../2.1.0.3.0/package/files/startMetastore.sh | 4 ++--
.../2.1.0.3.0/package/scripts/hive_service.py | 8 +-------
.../2.1.0.3.0/package/scripts/params_linux.py | 3 +--
.../2.1.0.3.0/package/scripts/service_check.py | 6 ++----
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 8 +++-----
.../python/stacks/2.0.6/HIVE/test_hive_server.py | 18 ++++++------------
.../stacks/2.0.6/HIVE/test_hive_service_check.py | 2 +-
.../python/stacks/2.1/HIVE/test_hive_metastore.py | 9 +++------
12 files changed, 26 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
index 86541f0..5a556b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
@@ -19,7 +19,7 @@
# under the License.
#
#
-HIVE_BIN=${HIVE_BIN:-"hive"}
+HIVE_CMD=${HIVE_CMD:-"hive"}
-HIVE_CONF_DIR=$4 $HIVE_BIN --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
+HIVE_CONF_DIR=$4 $HIVE_CMD --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
echo $!|cat>$3
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
index 2412bf9..05aedc1 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
@@ -76,8 +76,6 @@ def hive_service(name, action='start', upgrade_type=None):
check_fs_root(params.hive_server_conf_dir, params.execute_path)
daemon_cmd = cmd
- hadoop_home = params.hadoop_home
- hive_bin = "hive"
# upgrading hiveserver2 (rolling_restart) means that there is an existing,
# de-registering hiveserver2; the pid will still exist, but the new
@@ -85,13 +83,9 @@ def hive_service(name, action='start', upgrade_type=None):
if upgrade_type == UPGRADE_TYPE_ROLLING:
process_id_exists_command = None
- if params.version and params.stack_root:
- hadoop_home = format("{stack_root}/{version}/hadoop")
- hive_bin = os.path.join(params.hive_bin, hive_bin)
-
- Execute(daemon_cmd,
+ Execute(daemon_cmd,
user = params.hive_user,
- environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_bin },
+ environment = { 'JAVA_HOME': params.java64_home, 'HIVE_CMD': params.hive_cmd },
path = params.execute_path,
not_if = process_id_exists_command)
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
index 16e1a71..ea8beaf 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
@@ -112,6 +112,7 @@ component_directory_interactive = status_params.component_directory_interactive
hadoop_home = stack_select.get_hadoop_dir("home")
hive_bin = format('{stack_root}/current/{component_directory}/bin')
+hive_cmd = os.path.join(hive_bin, "hive")
hive_schematool_ver_bin = format('{stack_root}/{version}/hive/bin')
hive_schematool_bin = format('{stack_root}/current/{component_directory}/bin')
hive_lib = format('{stack_root}/current/{component_directory}/lib')
@@ -186,8 +187,6 @@ hive_server_conf_dir = status_params.hive_server_conf_dir
hcat_conf_dir = '/etc/hive-hcatalog/conf'
config_dir = '/etc/hive-webhcat/conf'
-hcat_lib = '/usr/lib/hive-hcatalog/share/hcatalog'
-webhcat_bin_dir = '/usr/lib/hive-hcatalog/sbin'
# there are no client versions of these, use server versions directly
hcat_lib = format('{stack_root}/current/hive-webhcat/share/hcatalog')
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
index 271fff9..852d7bf 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
@@ -171,10 +171,8 @@ class HiveServiceCheckDefault(HiveServiceCheck):
if kinit_cmd:
beeline_url.append('principal={key}')
- exec_path = params.execute_path
- if params.version:
- upgrade_hive_bin = format("{stack_root}/{version}/hive2/bin")
- exec_path = os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + upgrade_hive_bin
+ hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin")
+ exec_path = os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + hive_interactive_bin
# beeline path
llap_cmd = "! beeline -u '%s'" % format(";".join(beeline_url))
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
index 86541f0..5a556b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
@@ -19,7 +19,7 @@
# under the License.
#
#
-HIVE_BIN=${HIVE_BIN:-"hive"}
+HIVE_CMD=${HIVE_CMD:-"hive"}
-HIVE_CONF_DIR=$4 $HIVE_BIN --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
+HIVE_CONF_DIR=$4 $HIVE_CMD --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
echo $!|cat>$3
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
index 1f2b644..80471ea 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
@@ -76,8 +76,6 @@ def hive_service(name, action='start', upgrade_type=None):
check_fs_root(params.hive_server_conf_dir, params.execute_path)
daemon_cmd = cmd
- hadoop_home = params.hadoop_home
- hive_bin = "hive"
# upgrading hiveserver2 (rolling_restart) means that there is an existing,
# de-registering hiveserver2; the pid will still exist, but the new
@@ -85,13 +83,9 @@ def hive_service(name, action='start', upgrade_type=None):
if upgrade_type == UPGRADE_TYPE_ROLLING:
process_id_exists_command = None
- if params.version and params.stack_root:
- hadoop_home = format("{stack_root}/{version}/hadoop")
- hive_bin = os.path.join(params.hive_bin, hive_bin)
-
Execute(daemon_cmd,
user = params.hive_user,
- environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_bin },
+ environment = { 'JAVA_HOME': params.java64_home, 'HIVE_CMD': params.hive_cmd },
path = params.execute_path,
not_if = process_id_exists_command)
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
index fb2c84a..1bd6a1a 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
@@ -109,6 +109,7 @@ component_directory_interactive = status_params.component_directory_interactive
hadoop_home = format('{stack_root}/current/hadoop-client')
hive_bin = format('{stack_root}/current/{component_directory}/bin')
+hive_cmd = os.path.join(hive_bin, "hive")
hive_schematool_ver_bin = format('{stack_root}/{version}/hive/bin')
hive_schematool_bin = format('{stack_root}/current/{component_directory}/bin')
hive_lib = format('{stack_root}/current/{component_directory}/lib')
@@ -183,8 +184,6 @@ hive_server_conf_dir = status_params.hive_server_conf_dir
hcat_conf_dir = '/etc/hive-hcatalog/conf'
config_dir = '/etc/hive-webhcat/conf'
-hcat_lib = '/usr/lib/hive-hcatalog/share/hcatalog'
-webhcat_bin_dir = '/usr/lib/hive-hcatalog/sbin'
# there are no client versions of these, use server versions directly
hcat_lib = format('{stack_root}/current/hive-webhcat/share/hcatalog')
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
index d144c34..ce434b6 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
@@ -170,10 +170,8 @@ class HiveServiceCheckDefault(HiveServiceCheck):
if kinit_cmd:
beeline_url.append('principal={key}')
- exec_path = params.execute_path
- if params.version:
- upgrade_hive_bin = format("{stack_root}/{version}/hive2/bin")
- exec_path = os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + upgrade_hive_bin
+ hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin")
+ exec_path = os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + hive_interactive_bin
# beeline path
llap_cmd = "! beeline -u '%s'" % format(";".join(beeline_url))
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
index 1baed03..bacfe3c 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
@@ -62,8 +62,7 @@ class TestHiveMetastore(RMFTestCase):
self.assert_configure_default()
self.assert_init_schema()
self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
- 'HIVE_BIN': 'hive',
+ environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -123,8 +122,7 @@ class TestHiveMetastore(RMFTestCase):
self.assert_configure_secured()
self.assert_init_schema()
self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': '/usr/hdp/2.1.0.0-1234/hadoop',
- 'HIVE_BIN': 'hive',
+ environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -552,7 +550,7 @@ class TestHiveMetastore(RMFTestCase):
user = 'hive')
self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': '/usr/hdp/2.3.0.0-1234/hadoop', 'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45', 'HIVE_BIN': '/usr/hdp/current/hive-server2/bin/hive'},
+ environment = {'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45', 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive'},
not_if = None,
user = 'hive',
path = ['/bin:/usr/hdp/current/hive-server2/bin:/usr/hdp/2.3.0.0-1234/hadoop/bin'])
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
index c1fb5a2..87467ac 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
@@ -93,8 +93,7 @@ class TestHiveServer(RMFTestCase):
user='hive'
)
self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': 'mock_hadoop_dir',
- 'HIVE_BIN': 'hive',
+ environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -124,8 +123,7 @@ class TestHiveServer(RMFTestCase):
self.assert_configure_default(default_fs_default='hcfs://c6401.ambari.apache.org:8020')
self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': 'mock_hadoop_dir',
- 'HIVE_BIN': 'hive',
+ environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -155,8 +153,7 @@ class TestHiveServer(RMFTestCase):
user = 'hive',
)
self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': 'mock_hadoop_dir',
- 'HIVE_BIN': 'hive',
+ environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -186,8 +183,7 @@ class TestHiveServer(RMFTestCase):
user = 'hive',
)
self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': 'mock_hadoop_dir',
- 'HIVE_BIN': 'hive',
+ environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -217,8 +213,7 @@ class TestHiveServer(RMFTestCase):
user = 'hive',
)
self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': 'mock_hadoop_dir',
- 'HIVE_BIN': 'hive',
+ environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -290,8 +285,7 @@ class TestHiveServer(RMFTestCase):
self.assert_configure_secured()
self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': 'mock_hadoop_dir',
- 'HIVE_BIN': 'hive',
+ environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
index 7efb5fd..157b25c 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
@@ -340,7 +340,7 @@ class TestServiceCheck(RMFTestCase):
# LLAP call
self.assertResourceCalled('Execute',
"! beeline -u 'jdbc:hive2://c6402.ambari.apache.org:10500/;transportMode=binary' --hiveconf \"hiveLlapServiceCheck=\" -f /usr/hdp/current/hive-server2-hive2/scripts/llap/sql/serviceCheckScript.sql -e '' 2>&1| awk '{print}'|grep -i -e 'Invalid status\|Invalid URL\|command not found\|Connection refused'",
- path = ['/usr/sbin', '/usr/local/bin', '/bin', '/usr/bin', '/bin:/usr/hdp/2.3.0.0-1234/hadoop/bin:/usr/hdp/2.3.0.0-1234/hive2/bin'],
+ path = ['/usr/sbin', '/usr/local/bin', '/bin', '/usr/bin', '/bin:/usr/hdp/2.3.0.0-1234/hadoop/bin:/usr/hdp/current/hive-server2-hive2/bin'],
tries = 1,
stderr = -1,
wait_for_finish = True,
http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py b/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
index db4e2a1..d91bcf4 100644
--- a/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
+++ b/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
@@ -70,8 +70,7 @@ class TestHiveMetastore(RMFTestCase):
self.assert_init_schema('aaa')
self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2067/hadoop',
- 'HIVE_BIN': 'hive',
+ environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -101,8 +100,7 @@ class TestHiveMetastore(RMFTestCase):
self.assert_init_schema('aaa')
self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2067/hadoop',
- 'HIVE_BIN': 'hive',
+ environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
@@ -164,8 +162,7 @@ class TestHiveMetastore(RMFTestCase):
self.assert_configure_secured()
self.assert_init_schema('asd')
self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
- environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
- 'HIVE_BIN': 'hive',
+ environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user = 'hive',
[08/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement
new design for Admin View. (atkach)
Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg
new file mode 100644
index 0000000..06824bf
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg
@@ -0,0 +1,7606 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="robotoregular" horiz-adv-x="1164" >
+<font-face units-per-em="2048" ascent="1638" descent="-410" />
+<missing-glyph horiz-adv-x="509" />
+<glyph unicode="fi" horiz-adv-x="1140" d="M28 936v146h170v117q0 182 106.5 282t295.5 100q67 0 132 -15.5t153 -45.5l-34 -160q-53 21 -113 36t-123 15q-117 0 -168.5 -52t-51.5 -160v-117h215v-146h-215v-936h-197v936h-170zM783 0v1082h198v-1082h-198z" />
+<glyph unicode=" " horiz-adv-x="509" />
+<glyph unicode="	" horiz-adv-x="509" />
+<glyph unicode=" " horiz-adv-x="509" />
+<glyph unicode="!" horiz-adv-x="539" d="M171 0v204h198v-204h-198zM171 478v978h197v-978h-197z" />
+<glyph unicode=""" horiz-adv-x="668" d="M80 1040l1 240v280h197v-270l-101 -250h-97zM389 1040l1 248v272h197v-270l-101 -250h-97z" />
+<glyph unicode="#" horiz-adv-x="1276" d="M70 410v140h264l68 348h-256v142h284l82 416h151l-82 -416h255l82 416h151l-82 -416h199v-142h-226l-68 -348h219v-140h-247l-80 -410h-152l80 410h-255l-80 -410h-151l80 410h-236zM485 550h255l68 348h-255z" />
+<glyph unicode="$" horiz-adv-x="1153" d="M114 424l2 5h190q0 -154 77.5 -219.5t190.5 -65.5q129 0 201.5 61.5t72.5 170.5q0 89 -64 153t-210 114q-202 61 -305 163t-103 272q0 165 94.5 269t260.5 125v221h158v-222q168 -24 260.5 -143.5t92.5 -320.5h-196q0 136 -63 220t-175 84q-118 0 -176.5 -61.5 t-58.5 -168.5q0 -97 60.5 -157t218.5 -114q205 -66 304 -164.5t99 -267.5q0 -172 -103 -273.5t-283 -120.5v-192h-157v191q-172 18 -282 125.5t-106 315.5z" />
+<glyph unicode="%" horiz-adv-x="1498" d="M104 1099v77q0 127 82 214t219 87t219 -86.5t82 -214.5v-77q0 -127 -81.5 -213t-217.5 -86q-138 0 -220.5 86t-82.5 213zM250 1099q0 -74 40.5 -125.5t116.5 -51.5q73 0 113 51t40 126v77q0 74 -40.5 126.5t-114.5 52.5q-75 0 -115 -52.5t-40 -126.5v-77zM349 177 l711 1138l109 -67l-711 -1138zM809 279v78q0 127 82 213.5t219 86.5q136 0 218.5 -86.5t82.5 -213.5v-78q0 -128 -82 -214t-217 -86q-138 0 -220.5 86t-82.5 214zM955 279q0 -75 40.5 -126.5t116.5 -51.5q73 0 113 51.5t40 126.5v78q0 74 -41 126t-114 52q-74 0 -114.5 -52 t-40.5 -126v-78z" />
+<glyph unicode="&" horiz-adv-x="1276" d="M64 392q0 122 70.5 213.5t210.5 183.5q-78 99 -116 176.5t-38 159.5q0 169 97.5 260.5t268.5 91.5q158 0 257 -91t99 -219q0 -98 -52.5 -169.5t-155.5 -146.5l-109 -80l340 -409q41 65 64 144t23 167h176q0 -132 -39 -244t-113 -201l185 -223l-2 -5h-229l-85 102 q-80 -60 -177 -91.5t-201 -31.5q-217 0 -345.5 115t-128.5 298zM261 392q0 -113 71 -186t206 -73q72 0 142 24.5t132 70.5l-361 435l-40 -29q-91 -68 -120.5 -130t-29.5 -112zM388 1127q0 -53 27 -110.5t81 -125.5l138 95q57 38 77.5 82.5t20.5 98.5q0 61 -48.5 108 t-126.5 47q-81 0 -125 -56.5t-44 -138.5z" />
+<glyph unicode="'" horiz-adv-x="359" d="M80 1055l1 265v240h197v-223l-101 -282h-97z" />
+<glyph unicode="(" horiz-adv-x="679" d="M132 582v9q0 394 159 673t334 372l6 -1l38 -116q-137 -107 -238.5 -343t-101.5 -583v-13q0 -347 101 -583t239 -352l-38 -108h-6q-175 93 -334 371.5t-159 673.5z" />
+<glyph unicode=")" horiz-adv-x="687" d="M6 -355q135 105 237.5 345.5t102.5 589.5v13q0 342 -105.5 583.5t-234.5 351.5l38 108h6q174 -93 333.5 -372t159.5 -673v-9q0 -395 -159.5 -673.5t-333.5 -371.5h-6z" />
+<glyph unicode="*" horiz-adv-x="884" d="M28 1071l49 154l296 -111l-10 342h161l-10 -348l293 110l48 -156l-302 -89l193 -270l-131 -96l-181 287l-176 -279l-132 93l198 274z" />
+<glyph unicode="+" horiz-adv-x="1162" d="M78 605v178h402v423h197v-423h399v-178h-399v-459h-197v459h-402z" />
+<glyph unicode="," horiz-adv-x="404" d="M48 -258l70 316v163h197v-173l-150 -306h-117z" />
+<glyph unicode="-" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="." horiz-adv-x="548" d="M161 0v202h197v-202h-197z" />
+<glyph unicode="/" horiz-adv-x="850" d="M16 -125l608 1581h167l-607 -1581h-168z" />
+<glyph unicode="0" horiz-adv-x="1154" d="M113 555v345q0 278 124.5 427.5t338.5 149.5q215 0 339.5 -149.5t124.5 -427.5v-345q0 -279 -123.5 -427.5t-338.5 -148.5t-340 149t-125 427zM310 515q0 -189 69 -285.5t199 -96.5t197.5 96t67.5 286v427q0 189 -68.5 284.5t-198.5 95.5t-198 -95.5t-68 -284.5v-427z " />
+<glyph unicode="1" horiz-adv-x="1153" d="M186 1260v142l495 54v-1456h-197v1264z" />
+<glyph unicode="2" horiz-adv-x="1153" d="M97 1033q-5 188 125 316t360 128q196 0 312.5 -114.5t116.5 -291.5q0 -119 -70.5 -238.5t-197.5 -256.5l-383 -417l2 -5h700v-154h-944v135l477 530q128 143 173.5 227t45.5 172q0 109 -63.5 183.5t-168.5 74.5q-151 0 -222.5 -77.5t-71.5 -217.5h-189z" />
+<glyph unicode="3" horiz-adv-x="1153" d="M100 378l3 6h188q0 -115 70.5 -183t193.5 -68q125 0 196 68t71 201q0 135 -63 199t-199 64h-172v154h172q131 0 185.5 65.5t54.5 182.5q0 125 -62 190t-183 65q-115 0 -184.5 -67.5t-69.5 -179.5h-189l-2 6q-5 165 119.5 280.5t325.5 115.5q202 0 322 -107.5t120 -306.5 q0 -90 -54.5 -179.5t-163.5 -136.5q131 -43 185.5 -135t54.5 -206q0 -199 -130.5 -313t-333.5 -114q-199 0 -329.5 107.5t-125.5 291.5z" />
+<glyph unicode="4" horiz-adv-x="1153" d="M55 336v111l642 1009h208v-966h201v-154h-201v-336h-196v336h-654zM265 490h444v683l-6 1l-19 -50z" />
+<glyph unicode="5" horiz-adv-x="1153" d="M157 377l2 6h178q0 -119 68.5 -184.5t177.5 -65.5q125 0 194 88t69 241q0 140 -70 230t-193 90q-116 0 -168 -35t-76 -107l-164 17l84 799h729v-175h-562l-48 -409q46 34 102.5 56.5t130.5 24.5q201 2 316.5 -131t115.5 -358q0 -219 -117.5 -352t-342.5 -133 q-185 0 -308 101t-118 297z" />
+<glyph unicode="6" horiz-adv-x="1153" d="M132 571v278q0 280 156 454t387 174q75 0 148.5 -17t121.5 -43l-42 -151q-49 25 -102.5 40.5t-125.5 15.5q-156 0 -251.5 -125t-95.5 -326v-23q64 56 146.5 87.5t177.5 31.5q195 0 311 -135t116 -342q0 -226 -123.5 -368.5t-329.5 -142.5q-214 0 -354 155t-140 437z M328 552q0 -201 85 -310t213 -109q121 0 188.5 102.5t67.5 254.5q0 144 -72.5 237t-201.5 93q-101 0 -172 -41t-108 -109v-118z" />
+<glyph unicode="7" horiz-adv-x="1153" d="M77 1301v155h985v-155q-264 -314 -356.5 -556.5t-133.5 -587.5l-16 -157h-197l16 157q42 344 163 615t331 529h-792z" />
+<glyph unicode="8" horiz-adv-x="1153" d="M102 394q0 123 74 217t200 138q-109 42 -171 127.5t-62 199.5q0 192 118.5 296.5t313.5 104.5q192 0 313.5 -104.5t121.5 -296.5q0 -114 -64 -199.5t-173 -127.5q126 -44 201.5 -138t75.5 -217q0 -202 -131.5 -308.5t-341.5 -106.5q-214 0 -344.5 106.5t-130.5 308.5z M299 398q0 -124 76 -194.5t202 -70.5q123 0 200 71t77 194q0 120 -79 197t-200 77q-123 0 -199.5 -77t-76.5 -197zM340 1072q0 -111 65.5 -178t171.5 -67q104 0 170 67t66 178q0 108 -67.5 179t-170.5 71q-105 0 -170 -68.5t-65 -181.5z" />
+<glyph unicode="9" horiz-adv-x="1153" d="M83 978q0 219 131.5 359t319.5 140q228 0 359.5 -142.5t131.5 -419.5v-347q0 -285 -142.5 -437t-371.5 -152q-77 0 -156.5 14.5t-142.5 44.5l30 151q59 -31 122.5 -43.5t146.5 -12.5q144 0 230.5 109t86.5 324v66q-49 -71 -122.5 -107.5t-163.5 -36.5q-211 0 -335 130.5 t-124 359.5zM280 978q0 -150 70.5 -243t191.5 -93q109 0 181.5 47t104.5 120v126q0 191 -73.5 289t-214.5 98q-108 0 -184 -96.5t-76 -247.5z" />
+<glyph unicode=":" horiz-adv-x="517" d="M161 0v202h197v-202h-197zM161 876v202h197v-202h-197z" />
+<glyph unicode=";" horiz-adv-x="525" d="M99 -258l70 316v163h197v-173l-150 -306h-117zM162 876v202h197v-202h-197z" />
+<glyph unicode="<" horiz-adv-x="1040" d="M71 466v149l816 378v-201l-559 -233l-85 -18v-6l85 -19l559 -228v-201z" />
+<glyph unicode="=" horiz-adv-x="1153" d="M152 407v164h834v-164h-834zM152 823v164h834v-164h-834z" />
+<glyph unicode=">" horiz-adv-x="1072" d="M136 87v196l598 238l85 17v6l-85 20l-598 234v195l856 -378v-149z" />
+<glyph unicode="?" horiz-adv-x="974" d="M61 1122q-3 161 113.5 258t296.5 97q197 0 306 -100.5t109 -280.5q0 -129 -70.5 -236t-186.5 -219q-54 -54 -65.5 -97t-11.5 -134h-197q1 145 25 201t126 148q99 117 141 180t42 152q0 106 -56.5 163t-161.5 57q-91 0 -155 -49.5t-64 -145.5h-188zM353 0v208h206v-208 h-206z" />
+<glyph unicode="@" horiz-adv-x="1833" d="M114 478q19 423 249 688t602 265q379 0 581.5 -250t185.5 -679q-9 -214 -120 -368.5t-332 -154.5q-73 0 -126 41.5t-76 117.5q-50 -80 -122 -119.5t-168 -39.5q-125 0 -194 120.5t-51 316.5q23 259 137.5 415.5t279.5 156.5q105 0 169 -26t139 -80l-4 -4h6l-51 -585 q-9 -110 21.5 -151.5t81.5 -41.5q123 0 197 113.5t82 288.5q16 382 -144 595.5t-496 213.5q-308 0 -495.5 -231t-202.5 -602q-18 -376 150 -594.5t482 -218.5q88 0 178.5 21.5t152.5 56.5l38 -107q-67 -42 -170.5 -65.5t-202.5 -23.5q-380 0 -587.5 249.5t-189.5 681.5z M720 416q-11 -142 21.5 -216t106.5 -74q64 0 117 24.5t97 87.5q-1 12 -0.5 25.5t2.5 29.5l47 538q-26 12 -54.5 19t-59.5 7q-125 0 -191 -109.5t-86 -331.5z" />
+<glyph unicode="A" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6z" />
+<glyph unicode="B" horiz-adv-x="1309" d="M180 0v1456h475q228 0 357 -98.5t129 -295.5q0 -97 -62 -173.5t-163 -113.5q132 -28 207.5 -129t75.5 -235q0 -200 -129.5 -305.5t-351.5 -105.5h-538zM377 154h341q134 0 209 66.5t75 188.5q0 128 -62.5 201t-192.5 73h-370v-529zM377 837h319q110 0 179 60.5t69 168.5 q0 118 -74.5 176.5t-214.5 58.5h-278v-464z" />
+<glyph unicode="C" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5q247 1 393 -131q142 -128 142 -337v-12l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6v-11q0 -198 -144 -332q-148 -138 -391 -138 q-247 0 -402.5 175t-155.5 444z" />
+<glyph unicode="D" horiz-adv-x="1349" d="M180 0v1456h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447zM377 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-1147z" />
+<glyph unicode="E" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966z" />
+<glyph unicode="F" horiz-adv-x="1193" d="M180 0v1456h963v-155h-766v-502h664v-155h-664v-644h-197z" />
+<glyph unicode="G" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432z" />
+<glyph unicode="H" horiz-adv-x="1461" d="M180 0v1456h197v-658h707v658h197v-1456h-197v643h-707v-643h-197z" />
+<glyph unicode="I" horiz-adv-x="579" d="M190 0v1456h198v-1456h-198z" />
+<glyph unicode="J" horiz-adv-x="1130" d="M66 395l2 6h189q0 -135 68.5 -201.5t193.5 -66.5q109 0 178 73.5t69 196.5v1053h197v-1053q0 -195 -123.5 -309.5t-320.5 -114.5q-210 0 -334 107q-119 102 -119 293v16z" />
+<glyph unicode="K" horiz-adv-x="1317" d="M180 0v1456h197v-644h152l521 644h218l3 -5l-565 -699l606 -747l-3 -5h-235l-527 657h-170v-657h-197z" />
+<glyph unicode="L" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886z" />
+<glyph unicode="M" horiz-adv-x="1799" d="M180 0v1456h252l464 -1183h6l464 1183h252v-1456h-197v576l20 592l-5 1l-472 -1169h-131l-470 1166l-5 -1l19 -589v-576h-197z" />
+<glyph unicode="N" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197z" />
+<glyph unicode="O" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261z" />
+<glyph unicode="P" horiz-adv-x="1312" d="M180 0v1456h557q233 0 362 -120t129 -316q0 -199 -129 -317.5t-362 -118.5h-360v-584h-197zM377 738h360q148 0 221 79.5t73 200.5t-73.5 202t-220.5 81h-360v-563z" />
+<glyph unicode="Q" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -142 -50 -263t-140 -205l247 -233l-135 -129l-276 257q-56 -23 -116.5 -34.5t-124.5 -11.5q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5 t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128t-102.5 -328v-261z" />
+<glyph unicode="R" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM377 786h310q167 0 240.5 63.5t73.5 193.5 q0 123 -71.5 190.5t-222.5 67.5h-330v-515z" />
+<glyph unicode="S" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 381 -131q137 -127 136 -292v-12l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -386 118q-163 115 -162 305v11z" />
+<glyph unicode="T" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-1301h-197v1301h-467z" />
+<glyph unicode="U" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5z" />
+<glyph unicode="V" horiz-adv-x="1295" d="M22 1456h214l376 -1094l33 -115h6l33 115l376 1094h213l-541 -1456h-169z" />
+<glyph unicode="W" horiz-adv-x="1809" d="M54 1456h196l222 -952l27 -182l6 -1l39 183l267 952h174l269 -952l40 -187h6l29 187l217 952h197l-351 -1456h-176l-287 1010l-26 131h-6l-25 -131l-292 -1010h-176z" />
+<glyph unicode="X" horiz-adv-x="1295" d="M66 0l472 734l-462 722h236l338 -568l340 568h238l-462 -722l472 -734h-235l-349 578l-350 -578h-238z" />
+<glyph unicode="Y" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525z" />
+<glyph unicode="Z" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036z" />
+<glyph unicode="[" horiz-adv-x="552" d="M143 -312v1976h385v-155h-188v-1666h188v-155h-385z" />
+<glyph unicode="\" horiz-adv-x="846" d="M39 1456h186l608 -1581h-186z" />
+<glyph unicode="]" horiz-adv-x="552" d="M11 -157h189v1666h-189v155h386v-1976h-386v155z" />
+<glyph unicode="^" horiz-adv-x="856" d="M61 729l299 727h134l298 -727h-181l-166 419l-16 70h-6l-16 -70l-163 -419h-183z" />
+<glyph unicode="_" horiz-adv-x="931" d="M4 0h923v-154h-923v154z" />
+<glyph unicode="`" horiz-adv-x="641" d="M82 1471l3 6h230l175 -266h-158z" />
+<glyph unicode="a" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6v11q0 111 112 205q118 98 303 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="b" d="M143 0v1560h197v-606q51 72 126.5 110t176.5 38q200 0 312 -160t112 -421v-21q0 -234 -112.5 -377.5t-309.5 -143.5q-107 0 -186 41.5t-131 122.5l-24 -143h-161zM340 309q38 -80 99.5 -125t155.5 -45q139 0 207 99t68 262v21q0 186 -68.5 303.5t-208.5 117.5 q-91 0 -153.5 -44.5t-99.5 -119.5v-469z" />
+<glyph unicode="c" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q191 0 311 -112q117 -108 116 -265v-10l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6v-10q-1 -134 -125 -238 q-130 -108 -301 -109q-236 0 -361 154t-125 387z" />
+<glyph unicode="d" d="M98 500v21q0 261 111.5 421t312.5 160q95 0 168.5 -35t125.5 -102v595h197v-1560h-161l-23 133q-53 -76 -130 -115t-179 -39q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67 -262.5t208 -98.5q88 0 148 40t98 112v505q-38 67 -98.5 106.5t-145.5 39.5 q-142 0 -209.5 -117t-67.5 -304v-21z" />
+<glyph unicode="e" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="f" horiz-adv-x="707" d="M56 936v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-53.5 3q-86 0 -128 -51.5t-42 -149.5v-137h225v-146h-225v-936h-197v936h-169z" />
+<glyph unicode="g" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21z" />
+<glyph unicode="h" d="M143 0v1560h197v-623q56 78 137.5 121.5t180.5 43.5q173 0 269.5 -104t96.5 -320v-678h-197v680q0 134 -57.5 198t-171.5 64q-82 0 -148.5 -38.5t-109.5 -104.5v-799h-197z" />
+<glyph unicode="i" horiz-adv-x="516" d="M159 0v1082h197v-1082h-197zM159 1359v201h197v-201h-197z" />
+<glyph unicode="j" horiz-adv-x="530" d="M-66 -419l14 155q14 -5 40 -8.5t43 -3.5q65 0 103.5 44t38.5 143v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM167 1363v197h197v-197h-197z" />
+<glyph unicode="k" horiz-adv-x="1050" d="M144 0v1560h197v-904h126l296 426h236l-370 -492l423 -590h-232l-351 499h-128v-499h-197z" />
+<glyph unicode="l" horiz-adv-x="516" d="M159 0v1560h197v-1560h-197z" />
+<glyph unicode="m" horiz-adv-x="1790" d="M143 0v1082h176l14 -142q53 77 134.5 119.5t189.5 42.5t185.5 -50t116.5 -150q51 92 135 146t196 54q165 0 261 -113.5t96 -341.5v-647h-197v649q0 160 -55 226.5t-164 66.5q-101 0 -163.5 -70t-73.5 -177v-8v-687h-198v649q0 152 -56.5 222.5t-162.5 70.5 q-90 0 -148 -37t-89 -104v-801h-197z" />
+<glyph unicode="n" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197z" />
+<glyph unicode="o" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="p" d="M143 -416v1498h151l31 -140q53 78 132 119t184 41q201 0 312.5 -159.5t111.5 -421.5v-21q0 -234 -112 -377.5t-309 -143.5q-100 0 -175.5 33.5t-128.5 100.5v-529h-197zM340 275q37 -67 97 -104.5t147 -37.5q140 0 212 102.5t72 264.5v21q0 184 -72.5 302.5t-213.5 118.5 q-85 0 -145 -38.5t-97 -105.5v-523z" />
+<glyph unicode="q" d="M98 500v21q0 261 111.5 421t312.5 160q99 0 174 -37.5t127 -109.5l29 127h150v-1498h-197v518q-52 -61 -123 -92t-162 -31q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67.5 -265.5t207.5 -101.5q81 0 138.5 36t96.5 101v546q-39 61 -96.5 96t-136.5 35 q-141 0 -209 -119.5t-68 -306.5v-21z" />
+<glyph unicode="r" horiz-adv-x="702" d="M143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197z" />
+<glyph unicode="s" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 301 -97q107 -93 106 -224v-12l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105q-113 100 -113 232v13z" />
+<glyph unicode="t" horiz-adv-x="708" d="M34 936v146h172v261h197v-261h205v-146h-205v-657q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v657h-172z" />
+<glyph unicode="u" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352z" />
+<glyph unicode="v" horiz-adv-x="1030" d="M46 1082h202l256 -763l17 -76h6l19 76l249 763h201l-398 -1082h-149z" />
+<glyph unicode="w" horiz-adv-x="1550" d="M45 1082h196l179 -688l23 -131h6l28 131l216 688h158l217 -688l31 -146h6l29 146l170 688h196l-314 -1082h-159l-209 659l-45 184l-6 -1l-43 -183l-206 -659h-159z" />
+<glyph unicode="x" horiz-adv-x="1030" d="M46 0l361 547l-351 535h227l227 -399l230 399h230l-351 -535l361 -547h-226l-240 409l-240 -409h-228z" />
+<glyph unicode="y" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113z" />
+<glyph unicode="z" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860z" />
+<glyph unicode="{" horiz-adv-x="696" d="M63 543v147q106 0 157.5 61.5t51.5 174.5v206q0 171 82 290.5t277 174.5l40 -117q-110 -35 -156 -125.5t-46 -222.5v-206q0 -105 -42.5 -185t-127.5 -125q85 -46 127.5 -126.5t42.5 -183.5v-205q0 -132 46 -221.5t156 -125.5l-40 -118q-195 55 -277 175t-82 290v205 q0 112 -51.5 174.5t-157.5 62.5z" />
+<glyph unicode="|" horiz-adv-x="507" d="M175 -270v1726h158v-1726h-158z" />
+<glyph unicode="}" horiz-adv-x="696" d="M21 -246q109 36 156 125.5t47 221.5v205q0 107 45 187t139 123q-94 41 -139 121t-45 189v206q0 132 -47 222.5t-156 125.5l41 117q194 -55 276.5 -174.5t82.5 -290.5v-206q0 -113 50.5 -174.5t158.5 -61.5v-147q-108 0 -158.5 -62.5t-50.5 -174.5v-205q0 -170 -82.5 -290 t-276.5 -175z" />
+<glyph unicode="~" horiz-adv-x="1391" d="M128 474q0 136 85.5 232.5t217.5 96.5q88 0 163 -34.5t160 -104.5q58 -51 106 -74t100 -23q66 0 114.5 57t48.5 134l141 -18q0 -137 -87 -238t-217 -101q-90 0 -163.5 33t-158.5 107q-59 48 -108 72t-99 24q-67 0 -114.5 -53t-47.5 -128z" />
+<glyph unicode="¡" horiz-adv-x="507" d="M144 -374v978h197v-978h-197zM144 876v206h197v-206h-197z" />
+<glyph unicode="¢" horiz-adv-x="1122" d="M107 520v42q0 199 95 344.5t276 183.5v228h198v-223q157 -24 252.5 -130.5t92.5 -250.5l-2 -5h-179q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h178l3 -6q3 -122 -98 -223t-247 -126v-232 h-198v236q-182 36 -276.5 182t-94.5 347z" />
+<glyph unicode="£" horiz-adv-x="1194" d="M70 615v155h158l-10 270q0 204 112 320.5t300 116.5q200 0 310 -104.5t106 -276.5l-2 -6h-190q0 118 -63 175t-161 57q-99 0 -157 -74.5t-58 -207.5l10 -270h418v-155h-413l6 -149q0 -90 -15.5 -171.5t-44.5 -140.5h735l-1 -154h-976v154h10q48 13 72 111t24 201l-6 149 h-164z" />
+<glyph unicode="¤" horiz-adv-x="1456" d="M104 112l138 140q-50 76 -76.5 166.5t-26.5 189.5q0 102 28.5 196t82.5 172l-146 149l139 139l143 -146q74 55 163 85.5t185 30.5q97 0 186 -31t164 -87l146 149l140 -140l-150 -153q52 -78 80.5 -170.5t28.5 -193.5q0 -98 -26.5 -187.5t-74.5 -165.5l142 -143l-140 -139 l-133 135q-77 -62 -169.5 -95t-193.5 -33t-193.5 32.5t-167.5 93.5l-130 -132zM321 608q0 -188 120.5 -320.5t292.5 -132.5q170 0 290.5 132.5t120.5 320.5q0 186 -120.5 318t-290.5 132q-172 0 -292.5 -132t-120.5 -318z" />
+<glyph unicode="¥" horiz-adv-x="1243" d="M30 1456h226l359 -663l360 663h224l-418 -718h312v-155h-383v-135h383v-155h-383v-293h-197v293h-375v155h375v135h-375v155h311z" />
+<glyph unicode="¦" horiz-adv-x="499" d="M145 -270v792h197v-792h-197zM145 698v758h197v-758h-197z" />
+<glyph unicode="§" horiz-adv-x="1259" d="M94 551q0 91 47 161.5t134 111.5q-68 50 -102 119.5t-34 166.5q0 166 134 266.5t358 100.5q233 0 363 -111.5t126 -313.5l-3 -6h-188q0 118 -79 197t-219 79q-145 0 -220 -59.5t-75 -150.5q0 -99 67 -148.5t278 -107.5q244 -69 355.5 -159.5t111.5 -265.5q0 -94 -48 -164 t-135 -110q69 -51 104 -119t35 -166q0 -172 -133 -269.5t-358 -97.5q-221 0 -372 102.5t-146 322.5l2 6l188 2q0 -143 96.5 -210.5t231.5 -67.5q137 0 215.5 59.5t78.5 150.5t-72 141.5t-276 113.5q-239 63 -352 156t-113 270zM291 553q0 -100 68 -151.5t278 -110.5 q56 -17 93 -28t70 -23q72 20 112 69.5t40 118.5q0 91 -73.5 144.5t-275.5 116.5q-47 12 -88.5 24.5t-77.5 27.5q-73 -19 -109.5 -69t-36.5 -119z" />
+<glyph unicode="¨" horiz-adv-x="1021" d="M170 1256v200h219v-200h-219zM640 1256v200h219v-200h-219z" />
+<glyph unicode="©" horiz-adv-x="1604" d="M88 729q0 315 207 531t503 216q295 0 502 -216t207 -531q0 -316 -207.5 -533t-501.5 -217q-296 0 -503 217t-207 533zM209 729q0 -265 171.5 -447t417.5 -182q245 0 417 182t172 447q0 263 -172 444t-417 181q-246 0 -417.5 -181t-171.5 -444zM436 669v119q0 173 94 280 t254 107q157 0 245.5 -79t84.5 -228l-2 -6h-146q0 95 -45.5 138.5t-136.5 43.5q-94 0 -145 -70.5t-51 -184.5v-120q0 -117 51 -187t145 -70q91 0 136 43t45 141h146l2 -6q4 -151 -84 -229.5t-245 -78.5q-160 0 -254 106.5t-94 280.5z" />
+<glyph unicode="ª" horiz-adv-x="917" d="M120 920q0 110 84.5 170t245.5 60h139v52q0 63 -30 97t-88 34q-67 0 -103.5 -27t-36.5 -76l-162 13l-1 6q-6 98 78.5 163t224.5 65q134 0 212 -71t78 -205v-314q0 -50 6 -94t20 -87h-174q-8 21 -13 45t-8 50q-33 -47 -89.5 -78t-133.5 -31q-119 0 -184 61t-65 167z M293 924q0 -45 29 -69t89 -24q51 0 105.5 30t72.5 65v110h-138q-75 0 -116.5 -33t-41.5 -79z" />
+<glyph unicode="«" horiz-adv-x="966" d="M98 507v19l295 389h148l-255 -399l255 -398h-148zM432 507v19l295 389h148l-255 -399l255 -398h-148z" />
+<glyph unicode="¬" horiz-adv-x="1137" d="M127 637v165h835v-427h-198v262h-637z" />
+<glyph unicode="­" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="®" horiz-adv-x="1604" d="M88 729q0 315 207 531t503 216q295 0 502 -216t207 -531q0 -316 -207.5 -533t-501.5 -217q-296 0 -503 217t-207 533zM209 729q0 -266 171.5 -447.5t417.5 -181.5q244 0 416 182t172 447q0 264 -171.5 444.5t-416.5 180.5q-246 0 -417.5 -180.5t-171.5 -444.5zM504 316 v850h280q152 0 238.5 -65.5t86.5 -191.5q0 -62 -33 -109t-96 -78q66 -26 95.5 -79t29.5 -128v-56q0 -41 3.5 -73.5t13.5 -53.5v-16h-153q-9 21 -11 61.5t-2 82.5v54q0 72 -33.5 106t-110.5 34h-159v-338h-149zM653 784h152q65 1 110.5 32.5t45.5 87.5q0 73 -39.5 102.5 t-137.5 29.5h-131v-252z" />
+<glyph unicode="¯" horiz-adv-x="950" d="M123 1310v146h721v-146h-721z" />
+<glyph unicode="°" horiz-adv-x="763" d="M128 1216q0 106 76 183.5t181 77.5q103 0 177.5 -77.5t74.5 -183.5q0 -108 -74 -182.5t-178 -74.5q-106 0 -181.5 74.5t-75.5 182.5zM259 1216q0 -55 36.5 -91t89.5 -36q52 0 87.5 36t35.5 91t-36 92.5t-87 37.5q-53 0 -89.5 -37.5t-36.5 -92.5z" />
+<glyph unicode="±" horiz-adv-x="1097" d="M99 702v154h381v411h177v-411h358v-154h-358v-413h-177v413h-381zM136 4v155h835v-155h-835z" />
+<glyph unicode="²" horiz-adv-x="868" d="M119 1240q-6 99 78 169t225 70q135 0 211 -64t76 -180q0 -80 -44.5 -136t-160.5 -161l-153 -135l2 -6h361v-130h-592v130l302 262q69 60 91 97.5t22 79.5q0 50 -28.5 81t-86.5 31q-67 0 -103.5 -32t-36.5 -82h-161z" />
+<glyph unicode="³" horiz-adv-x="876" d="M112 882l1 6h163q0 -46 37.5 -74.5t100.5 -28.5q72 0 114 29.5t42 77.5q0 62 -36.5 90.5t-109.5 28.5h-132v126h132q67 0 99.5 28.5t32.5 80.5q0 43 -36.5 72t-105.5 29q-56 0 -90.5 -24t-34.5 -64h-162l-2 6q-6 94 78.5 153.5t210.5 59.5q145 0 229 -59.5t84 -169.5 q0 -55 -35.5 -100.5t-97.5 -71.5q70 -23 108 -71t38 -116q0 -111 -90 -173t-236 -62q-127 0 -217.5 58t-84.5 169z" />
+<glyph unicode="´" horiz-adv-x="654" d="M131 1211l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="µ" d="M153 -416v1498h196v-642q2 -178 57.5 -242.5t155.5 -64.5q98 0 158.5 36t92.5 106v807h197v-1082h-177l-9 108q-44 -63 -107.5 -96t-146.5 -33q-72 0 -126.5 16.5t-94.5 51.5v-463h-196z" />
+<glyph unicode="¶" horiz-adv-x="1006" d="M63 988q0 207 129.5 337.5t362.5 130.5h281v-1456h-197v520h-84q-233 0 -362.5 129.5t-129.5 338.5z" />
+<glyph unicode="·" horiz-adv-x="540" d="M161 624v212h198v-212h-198z" />
+<glyph unicode="¸" horiz-adv-x="509" d="M119 -326q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="¹" horiz-adv-x="557" d="M95 1320v134l301 23v-812h-174v655h-127z" />
+<glyph unicode="º" horiz-adv-x="933" d="M120 1025v117q0 148 94 241.5t251 93.5q158 0 252 -93.5t94 -241.5v-117q0 -149 -93.5 -241.5t-250.5 -92.5q-158 0 -252.5 92.5t-94.5 241.5zM293 1025q0 -88 44 -140.5t130 -52.5q83 0 127.5 53t44.5 140v117q0 84 -45 137.5t-129 53.5t-128 -53.5t-44 -137.5v-117z " />
+<glyph unicode="»" horiz-adv-x="966" d="M110 152l255 398l-255 399h148l295 -389v-19l-295 -389h-148zM456 152l255 398l-255 399h148l295 -389v-19l-295 -389h-148z" />
+<glyph unicode="¼" horiz-adv-x="1595" d="M184 1319v134l301 23v-812h-174v655h-127zM339 185l711 1138l109 -67l-711 -1138zM785 254l422 547h173v-519h126v-130h-126v-152h-170v152h-417zM967 282h243v310l-6 1l-13 -22z" />
+<glyph unicode="½" horiz-adv-x="1708" d="M184 1319v134l301 23v-812h-174v655h-127zM352 185l711 1138l109 -67l-711 -1138zM930 573q-6 99 78 169t225 70q135 0 211 -64t76 -180q0 -80 -44.5 -136t-160.5 -161l-153 -135l2 -6h361v-130h-592v130l302 262q69 60 91 97.5t22 79.5q0 50 -28.5 81t-86.5 31 q-67 0 -103.5 -32t-36.5 -82h-161z" />
+<glyph unicode="¾" horiz-adv-x="1781" d="M128 883l1 6h163q0 -46 37.5 -74.5t100.5 -28.5q72 0 114 29.5t42 77.5q0 62 -36.5 90.5t-109.5 28.5h-132v126h132q67 0 99.5 28.5t32.5 80.5q0 43 -36.5 72t-105.5 29q-56 0 -90.5 -24t-34.5 -64h-162l-2 6q-6 94 78.5 153.5t210.5 59.5q145 0 229 -59.5t84 -169.5 q0 -55 -35.5 -100.5t-97.5 -71.5q70 -23 108 -71t38 -116q0 -111 -90 -173t-236 -62q-127 0 -217.5 58t-84.5 169zM522 185l711 1138l109 -67l-711 -1138zM974 254l422 547h173v-519h126v-130h-126v-152h-170v152h-417zM1156 282h243v310l-6 1l-13 -22z" />
+<glyph unicode="¿" horiz-adv-x="1013" d="M114 -13q0 127 70 233.5t187 220.5q53 53 65 96t12 135h197q-2 -146 -26 -202t-125 -147q-100 -118 -141.5 -181t-41.5 -150q0 -106 56 -163t162 -57q90 0 154.5 49.5t64.5 145.5h188l3 -6q2 -161 -114.5 -258t-295.5 -97q-198 0 -306.5 100.5t-108.5 280.5zM441 874v209 h206v-209h-206z" />
+<glyph unicode="À" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM378 1820l3 6h230l175 -266h-158zM420 540h490l-240 663h-6z" />
+<glyph unicode="Á" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM613 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Â" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM356 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM420 540h490l-240 663h-6z" />
+<glyph unicode="Ã" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM316 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM420 540h490l-240 663h-6z " />
+<glyph unicode="Ä" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM319 1605v200h219v-200h-219zM420 540h490l-240 663h-6zM789 1605v200h219v-200h-219z" />
+<glyph unicode="Å" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM457 1734q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54q-87 0 -147.5 54t-60.5 140zM560 1734q0 -43 31 -73.5t74 -30.5q42 0 72 29.5 t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="Æ" horiz-adv-x="1922" d="M-20 0l880 1456h967v-155h-691l20 -466h590v-155h-584l22 -526h705v-154h-895l-15 350h-557l-202 -350h-240zM525 529h447l-31 710l-5 2z" />
+<glyph unicode="Ç" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM581 -334 q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="È" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM303 1820l3 6h230l175 -266h-158z" />
+<glyph unicode="É" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM538 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ê" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM322 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ë" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM284 1605v200h219v-200h-219zM754 1605v200h219v-200h-219z" />
+<glyph unicode="Ì" horiz-adv-x="579" d="M-34 1820l3 6h230l175 -266h-158zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="Í" horiz-adv-x="579" d="M190 0v1456h198v-1456h-198zM199 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Î" horiz-adv-x="579" d="M-15 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="Ï" horiz-adv-x="579" d="M-53 1605v200h219v-200h-219zM190 0v1456h198v-1456h-198zM417 1605v200h219v-200h-219z" />
+<glyph unicode="Ð" horiz-adv-x="1379" d="M42 663v155h168v638h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447v663h-168zM407 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-483h276v-155h-276v-509z" />
+<glyph unicode="Ñ" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM381 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="Ò" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM373 1841l3 6h230l175 -266h-158z" />
+<glyph unicode="Ó" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM608 1577l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ô" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM392 1622v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Õ" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM351 1649q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="Ö" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM354 1626v200h219v-200h-219zM824 1626v200h219v-200h-219z" />
+<glyph unicode="×" horiz-adv-x="1096" d="M88 351l327 334l-327 334l126 126l326 -333l327 333l126 -126l-328 -334l328 -334l-126 -126l-327 332l-326 -332z" />
+<glyph unicode="Ø" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q94 0 178.5 -25.5t156.5 -71.5l81 137h149l-132 -221q77 -84 119.5 -197t42.5 -242v-259q0 -267 -165.5 -443t-429.5 -176q-85 0 -160.5 20.5t-139.5 60.5l-91 -154h-149l139 234q-84 84 -128.5 202t-44.5 256zM310 598 q0 -85 19 -158t54 -125l6 -1l544 916q-50 41 -112 63t-134 22q-172 0 -274.5 -128t-102.5 -328v-261zM475 208q44 -34 97 -51t115 -17q183 0 290.5 127.5t107.5 330.5v261q0 75 -16.5 142t-46.5 117l-6 1z" />
+<glyph unicode="Ù" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM372 1820l3 6h230l175 -266h-158z" />
+<glyph unicode="Ú" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM607 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Û" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM391 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ü" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM353 1605v200h219v-200h-219zM823 1605v200h219v-200h-219z" />
+<glyph unicode="Ý" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM535 1555l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Þ" horiz-adv-x="1209" d="M163 0v1456h197v-293h269q232 0 362 -118t130 -307q0 -190 -130 -307.5t-362 -117.5h-269v-313h-197zM360 467h269q147 0 220.5 78t73.5 191q0 114 -73.5 193.5t-220.5 79.5h-269v-542z" />
+<glyph unicode="ß" horiz-adv-x="1221" d="M137 0v1082q0 223 117.5 348t300.5 125q161 0 262 -86t101 -253q0 -118 -64.5 -228t-64.5 -167q0 -82 173.5 -224t173.5 -281q0 -167 -104.5 -252t-282.5 -85q-84 0 -172.5 20.5t-125.5 50.5l44 159q43 -28 108 -52t126 -24q108 0 159 47.5t51 125.5q0 84 -173.5 227.5 t-173.5 289.5q0 80 70.5 190.5t70.5 186.5q0 93 -51 147t-117 54q-104 0 -168 -83.5t-64 -235.5v-1082h-196z" />
+<glyph unicode="à" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM230 1498l3 6h230l175 -266h-158zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="á" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM465 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="â" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM249 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="ã" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM208 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55 t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="ä" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM211 1283v200h219v-200h-219zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM681 1283v200h219v-200h-219z" />
+<glyph unicode="å" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM346 1412q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54q-87 0 -147.5 54t-60.5 140z M449 1412q0 -43 31 -73.5t74 -30.5q42 0 72 29.5t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="æ" horiz-adv-x="1729" d="M58 304q0 158 115 244.5t335 86.5h229v85q0 106 -51.5 166.5t-149.5 60.5q-103 0 -164 -55t-61 -133l-188 18l-2 6q-5 138 109.5 228.5t305.5 90.5q114 0 201.5 -40.5t137.5 -117.5q64 75 151.5 116.5t188.5 41.5q214 0 329.5 -130t115.5 -358v-119h-709l-2 -5 q1 -159 79.5 -258t233.5 -99q103 0 169.5 27.5t144.5 78.5l67 -138q-53 -44 -147 -83t-234 -39q-136 0 -240 48.5t-170 138.5q-56 -79 -167.5 -133t-271.5 -54q-170 0 -262.5 87t-92.5 238zM255 300q0 -74 50 -120.5t147 -46.5q76 0 159 43.5t126 100.5v216h-227 q-120 0 -187.5 -56t-67.5 -137zM953 645l2 -5h508v31q0 122 -60 199t-188 77q-113 0 -182 -84.5t-80 -217.5z" />
+<glyph unicode="ç" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM440 -334q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="è" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM233 1499l3 6h230l175 -266h-158zM307 654l2 -5 h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="é" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5zM468 1235l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ê" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM252 1280v26l246 237h120l248 -238v-25h-161 l-147 148l-146 -148h-160zM307 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="ë" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM214 1284v200h219v-200h-219zM307 654l2 -5h499 v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5zM684 1284v200h219v-200h-219z" />
+<glyph unicode="ì" horiz-adv-x="515" d="M-71 1477l3 6h230l175 -266h-158zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="í" horiz-adv-x="515" d="M153 0v1082h197v-1082h-197zM162 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="î" horiz-adv-x="515" d="M-52 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="ï" horiz-adv-x="515" d="M-90 1262v200h219v-200h-219zM153 0v1082h197v-1082h-197zM380 1262v200h219v-200h-219z" />
+<glyph unicode="ð" horiz-adv-x="1202" d="M72 466q0 228 138 370t351 142q90 0 169.5 -37t131.5 -97l4 5q-9 109 -51.5 197t-110.5 154l-290 -165l-77 102l256 146q-39 22 -80.5 39t-85.5 31l60 164q79 -19 151 -52t135 -79l218 125l77 -102l-195 -112q95 -104 147 -241.5t52 -300.5v-220q0 -245 -144 -400.5 t-359 -155.5q-218 0 -357.5 140t-139.5 347zM269 466q0 -132 82 -232.5t222 -100.5q133 0 217.5 114t84.5 288v148q-35 59 -115.5 99.5t-198.5 40.5q-131 0 -211.5 -104t-80.5 -253z" />
+<glyph unicode="ñ" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM231 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32 q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="ò" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM257 1498l3 6h230l175 -266h-158zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="ó" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z M492 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ô" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM276 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22 q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="õ" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM235 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5 t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="ö" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM238 1283v200h219v-200h-219zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22zM708 1283v200h219v-200h-219z" />
+<glyph unicode="÷" horiz-adv-x="1170" d="M71 597v188h998v-188h-998zM472 180v203h198v-203h-198zM472 999v203h198v-203h-198z" />
+<glyph unicode="ø" d="M97 529v22q0 240 130 395.5t353 155.5q56 0 107.5 -11t97.5 -31l74 149h129l-104 -211q88 -74 135 -190t47 -257v-22q0 -242 -130 -396t-354 -154q-51 0 -97 8.5t-88 24.5l-72 -147h-129l100 204q-96 71 -147.5 191t-51.5 269zM294 529q0 -91 20 -166.5t61 -123.5h6 l332 674q-29 16 -62.5 25t-70.5 9q-141 0 -213.5 -113t-72.5 -283v-22zM469 156q24 -12 52 -17.5t61 -5.5q141 0 214 112t73 284v22q0 80 -17.5 150.5t-49.5 117.5h-6z" />
+<glyph unicode="ù" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM255 1477l3 6h230l175 -266h-158z" />
+<glyph unicode="ú" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM490 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="û" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM274 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ü" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM236 1262v200h219v-200h-219zM706 1262v200h219v-200h-219z" />
+<glyph unicode="ý" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM424 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="þ" horiz-adv-x="1186" d="M153 -416v1976h197v-598q53 68 128 104t173 36q201 0 312.5 -159.5t111.5 -421.5v-21q0 -234 -112 -377.5t-309 -143.5q-100 0 -175.5 33.5t-128.5 100.5v-529h-197zM350 275q37 -67 97 -104.5t147 -37.5q140 0 212 102.5t72 264.5v21q0 184 -72.5 302.5t-213.5 118.5 q-85 0 -145 -38.5t-97 -105.5v-523z" />
+<glyph unicode="ÿ" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM170 1262v200h219v-200h-219zM640 1262v200h219v-200h-219z" />
+<glyph unicode="Ā" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM303 1640v146h721v-146h-721zM420 540h490l-240 663h-6z" />
+<glyph unicode="ā" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM200 1318v146h721v-146h-721zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="Ă" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM369 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM420 540h490l-240 663h-6z" />
+<glyph unicode="ă" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM261 1542l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141 z" />
+<glyph unicode="Ą" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM962 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5 q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="ą" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM667 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5 l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="Ć" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM588 1577 l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ć" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM447 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ĉ" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM372 1622 v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ĉ" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM231 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ċ" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM569 1625 v201h218v-201h-218z" />
+<glyph unicode="ċ" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM428 1282v201h218v-201h-218z" />
+<glyph unicode="Č" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM364 1866 v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="č" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM223 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="Ď" horiz-adv-x="1349" d="M180 0v1456h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447zM306 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119zM377 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-1147z" />
+<glyph unicode="ď" horiz-adv-x="1314" d="M98 500v21q0 261 111.5 421t312.5 160q95 0 168.5 -35t125.5 -102v595h197v-1560h-161l-23 133q-53 -76 -130 -115t-179 -39q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67 -262.5t208 -98.5q88 0 148 40t98 112v505q-38 67 -98.5 106.5t-145.5 39.5 q-142 0 -209.5 -117t-67.5 -304v-21zM1090 1183l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="Đ" horiz-adv-x="1379" d="M42 663v155h168v638h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447v663h-168zM407 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-483h276v-155h-276v-509z" />
+<glyph unicode="đ" horiz-adv-x="1194" d="M98 500v21q0 261 111.5 421t312.5 160q95 0 168.5 -35t125.5 -102v266h-247v155h247v174h197v-174h197v-155h-197v-1231h-161l-23 133q-53 -76 -130 -115t-179 -39q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67 -262.5t208 -98.5q88 0 148 40t98 112v505 q-38 67 -98.5 106.5t-145.5 39.5q-142 0 -209.5 -117t-67.5 -304v-21z" />
+<glyph unicode="Ē" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM273 1640v146h721v-146h-721z" />
+<glyph unicode="ē" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM203 1319v146h721v-146h-721zM307 654l2 -5h499 v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="Ĕ" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM334 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189z" />
+<glyph unicode="ĕ" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM264 1543l2 6h151q0 -66 34 -107t108 -41 q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM307 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="Ė" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM519 1604v201h218v-201h-218z" />
+<glyph unicode="ė" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5zM449 1283v201h218v-201h-218z" />
+<glyph unicode="Ę" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM399 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z " />
+<glyph unicode="ę" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5zM560 -161q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="Ě" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM314 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="ě" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM244 1524v20h166l147 -148l147 148h170v-18 l-257 -245h-119zM307 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="Ĝ" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM362 1622v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ĝ" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM258 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21z" />
+<glyph unicode="Ğ" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM374 1885l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189z" />
+<glyph unicode="ğ" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM270 1542l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21z" />
+<glyph unicode="Ġ" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM559 1625v201h218v-201h-218z" />
+<glyph unicode="ġ" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21zM455 1282v201h218v-201h-218z" />
+<glyph unicode="Ģ" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM521 -494l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ģ" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21zM459 1253v148l121 247h97l-21 -257v-138h-197z" />
+<glyph unicode="Ĥ" horiz-adv-x="1461" d="M180 0v1456h197v-658h707v658h197v-1456h-197v643h-707v-643h-197zM415 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ĥ" d="M143 0v1560h197v-623q56 78 137.5 121.5t180.5 43.5q173 0 269.5 -104t96.5 -320v-678h-197v680q0 134 -57.5 198t-171.5 64q-82 0 -148.5 -38.5t-109.5 -104.5v-799h-197zM203 1600v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ħ" horiz-adv-x="1439" d="M31 1024v145h147v287h197v-287h707v287h197v-287h144v-145h-144v-1024h-197v643h-707v-643h-197v1024h-147zM375 798h707v226h-707v-226z" />
+<glyph unicode="ħ" horiz-adv-x="1194" d="M1 1231v155h172v174h197v-174h272v-155h-272v-294q56 78 137.5 121.5t180.5 43.5q173 0 269.5 -104t96.5 -320v-678h-197v680q0 134 -57.5 198t-171.5 64q-82 0 -148.5 -38.5t-109.5 -104.5v-799h-197v1231h-172z" />
+<glyph unicode="Ĩ" horiz-adv-x="579" d="M-56 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="ĩ" horiz-adv-x="515" d="M-93 1285q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="Ī" horiz-adv-x="579" d="M-64 1640v146h721v-146h-721zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="ī" horiz-adv-x="515" d="M-101 1299v146h721v-146h-721zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="Ĭ" horiz-adv-x="579" d="M-3 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="ĭ" horiz-adv-x="515" d="M-40 1521l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="Į" horiz-adv-x="579" d="M46 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="į" horiz-adv-x="516" d="M14 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154zM159 0v1082h197v-1082h-197zM159 1359v201h197v-201h-197z" />
+<glyph unicode="İ" horiz-adv-x="579" d="M180 1604v201h218v-201h-218zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="ı" horiz-adv-x="515" d="M153 0v1082h197v-1082h-197z" />
+<glyph unicode="IJ" horiz-adv-x="1709" d="M190 0v1456h198v-1456h-198zM645 395l2 6h189q0 -135 68.5 -201.5t193.5 -66.5q109 0 178 73.5t69 196.5v1053h197v-1053q0 -195 -123.5 -309.5t-320.5 -114.5q-210 0 -334 106.5t-119 309.5z" />
+<glyph unicode="ij" horiz-adv-x="1046" d="M159 0v1082h197v-1082h-197zM159 1359v201h197v-201h-197zM450 -419l14 155q14 -5 40 -8.5t43 -3.5q65 0 103.5 44t38.5 143v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM683 1363v197h197v-197h-197z" />
+<glyph unicode="Ĵ" horiz-adv-x="1130" d="M66 395l2 6h189q0 -135 68.5 -201.5t193.5 -66.5q109 0 178 73.5t69 196.5v1053h197v-1053q0 -195 -123.5 -309.5t-320.5 -114.5q-210 0 -334 106.5t-119 309.5zM550 1589v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ĵ" horiz-adv-x="523" d="M-68 -419l14 150q14 -5 46.5 -9t50.5 -4q59 0 93.5 51.5t34.5 141.5v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM-34 1240v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ķ" horiz-adv-x="1317" d="M180 0v1456h197v-644h152l521 644h218l3 -5l-565 -699l606 -747l-3 -5h-235l-527 657h-170v-657h-197zM487 -477l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ķ" horiz-adv-x="1050" d="M144 0v1560h197v-904h126l296 426h236l-370 -492l423 -590h-232l-351 499h-128v-499h-197zM388 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ĸ" horiz-adv-x="1144" d="M153 0v1082h197v-457h84l388 457h231l2 -5l-450 -514l483 -558l-2 -5h-241l-394 459h-101v-459h-197z" />
+<glyph unicode="Ĺ" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM186 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ĺ" horiz-adv-x="516" d="M159 0v1560h197v-1560h-197zM168 1594l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ļ" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM480 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ļ" horiz-adv-x="516" d="M110 -475l61 246v131h158v-140l-122 -237h-97zM159 0v1560h197v-1560h-197z" />
+<glyph unicode="Ľ" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM583 1080l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ľ" horiz-adv-x="666" d="M159 0v1560h197v-1560h-197zM453 1183l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="Ŀ" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM613 688v201h218v-201h-218z" />
+<glyph unicode="ŀ" horiz-adv-x="736" d="M159 0v1560h197v-1560h-197zM485 671v201h218v-201h-218z" />
+<glyph unicode="Ł" horiz-adv-x="1077" d="M40 576v166l123 39v675h197v-613l269 86v-166l-269 -86v-523h689v-154h-886v615z" />
+<glyph unicode="ł" horiz-adv-x="558" d="M37 578v165l142 54v763h197v-688l150 58v-165l-150 -58v-707h-197v632z" />
+<glyph unicode="Ń" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM638 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ń" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM488 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ņ" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM580 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ņ" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM430 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="Ň" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM414 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="ň" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM264 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="ʼn" d="M-32 1183l61 246v131h158v-140l-122 -237h-97zM143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197z" />
+<glyph unicode="Ŋ" horiz-adv-x="1416" d="M161 0v1456h197l701 -1112l6 2v1110h197v-1545q0 -167 -86 -257.5t-240 -90.5q-31 0 -57 4.5t-55 13.5l14 150q13 -5 47 -9t51 -4q60 0 94.5 51.5t34.5 141.5v89l-701 1112l-6 -2v-1110h-197z" />
+<glyph unicode="ŋ" d="M143 0v1082h176l13 -150q54 81 134 125.5t181 44.5q174 0 270 -102.5t96 -316.5v-772q0 -167 -86 -257.5t-240 -90.5q-31 0 -57.5 4.5t-54.5 13.5l14 160q13 -5 46.5 -8.5t51.5 -3.5q61 0 95 47t34 135v768q0 143 -57 203t-173 60q-85 0 -146.5 -33t-99.5 -92v-817h-197z " />
+<glyph unicode="Ō" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM343 1661v146h721v-146h-721z" />
+<glyph unicode="ō" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM227 1318v146h721v-146h-721zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="Ŏ" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM404 1885l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189z" />
+<glyph unicode="ŏ" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM288 1542l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM294 529 q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="Ő" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM462 1622l184 266h211l2 -5l-240 -261h-157zM731 1627l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="ő" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z M346 1279l184 266h211l2 -5l-240 -261h-157zM615 1284l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="Œ" horiz-adv-x="1960" d="M104 576v304q0 265 154.5 431t403.5 166q69 0 140.5 -6t150.5 -15h907v-155h-758v-471h667v-155h-667v-521h769v-154h-918q-92 -10 -157 -15.5t-132 -5.5q-249 0 -404.5 166t-155.5 431zM301 576q0 -214 97 -328t266 -114q61 0 122 4.5t119 13.5v1151q-61 8 -122 13.5 t-121 5.5q-169 0 -265 -113.5t-96 -326.5v-306z" />
+<glyph unicode="œ" horiz-adv-x="1854" d="M97 529v22q0 240 130 395.5t353 155.5q130 0 230 -54.5t164 -152.5q65 97 161.5 152t204.5 55q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-131 0 -232.5 52.5t-166.5 148.5 q-64 -96 -163 -148.5t-226 -52.5q-224 0 -354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22zM1085 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5 t-86 -209.5z" />
+<glyph unicode="Ŕ" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM377 786h310q167 0 240.5 63.5t73.5 193.5 q0 123 -71.5 190.5t-222.5 67.5h-330v-515zM530 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ŕ" horiz-adv-x="702" d="M143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197zM323 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ŗ" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM377 786h310q167 0 240.5 63.5t73.5 193.5 q0 123 -71.5 190.5t-222.5 67.5h-330v-515zM472 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ŗ" horiz-adv-x="702" d="M107 -475l61 246v131h158v-140l-122 -237h-97zM143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197z" />
+<glyph unicode="Ř" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM306 1845v20h166l147 -148l147 148h170v-18 l-257 -245h-119zM377 786h310q167 0 240.5 63.5t73.5 193.5q0 123 -71.5 190.5t-222.5 67.5h-330v-515z" />
+<glyph unicode="ř" horiz-adv-x="702" d="M101 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119zM143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197z" />
+<glyph unicode="Ś" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM523 1577l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ś" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM445 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ŝ" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM307 1622v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ŝ" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM229 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ş" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM516 -334q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="ş" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM438 -333q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="Š" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM299 1866v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="š" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM221 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="Ţ" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-1301h-197v1301h-467zM455 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="ţ" horiz-adv-x="708" d="M34 936v146h172v261h197v-261h205v-146h-205v-657q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v657h-172zM308 -485l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="Ť" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-1301h-197v1301h-467zM289 1844v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="ť" horiz-adv-x="748" d="M34 936v146h172v261h197v-261h205v-146h-205v-657q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v657h-172zM545 1210l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="Ŧ" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-326h220v-155h-220v-820h-197v820h-224v155h224v326h-467z" />
+<glyph unicode="ŧ" horiz-adv-x="708" d="M-8 600v155h214v181h-172v146h172v261h197v-261h205v-146h-205v-181h230v-155h-230v-321q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v321h-214z" />
+<glyph unicode="Ũ" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM350 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32 q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="ũ" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM233 1285q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159 t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="Ū" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM342 1640v146h721v-146h-721z" />
+<glyph unicode="ū" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM225 1299v146h721v-146h-721z" />
+<glyph unicode="Ŭ" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM403 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73 q-138 0 -219 73t-76 189z" />
+<glyph unicode="ŭ" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM286 1521l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73 q-138 0 -219 73t-76 189z" />
+<glyph unicode="Ů" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM488 1734q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54 q-87 0 -147.5 54t-60.5 140zM591 1734q0 -43 31 -73.5t74 -30.5q42 0 72 29.5t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="ů" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM371 1391q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54 q-87 0 -147.5 54t-60.5 140zM474 1391q0 -43 31 -73.5t74 -30.5q42 0 72 29.5t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="Ű" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM461 1601l184 266h211l2 -5l-240 -261h-157zM730 1606l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="ű" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM344 1258l184 266h211l2 -5l-240 -261h-157zM613 1263l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="Ų" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM493 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66 t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="ų" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM675 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24 q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="Ŵ" horiz-adv-x="1809" d="M54 1456h196l222 -952l27 -182l6 -1l39 183l267 952h174l269 -952l40 -187h6l29 187l217 952h197l-351 -1456h-176l-287 1010l-26 131h-6l-25 -131l-292 -1010h-176zM592 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ŵ" horiz-adv-x="1550" d="M45 1082h196l179 -688l23 -131h6l28 131l216 688h158l217 -688l31 -146h6l29 146l170 688h196l-314 -1082h-159l-209 659l-45 184l-6 -1l-43 -183l-206 -659h-159zM467 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ŷ" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM319 1600v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="ŷ" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM208 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="Ÿ" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM281 1604v200h219v-200h-219zM751 1604v200h219v-200h-219z" />
+<glyph unicode="Ź" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036zM519 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ź" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860zM434 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="Ż" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036zM500 1604v201h218v-201h-218z" />
+<glyph unicode="ż" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860zM415 1261v201h218v-201h-218z" />
+<glyph unicode="Ž" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036zM295 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="ž" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860zM210 1502v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="ſ" horiz-adv-x="516" d="M159 0v1219q0 173 91 267.5t253 94.5q33 0 67.5 -5.5t76.5 -15.5l-24 -145q-20 5 -42 8t-47 3q-87 0 -132.5 -54.5t-45.5 -152.5v-1219h-197z" />
+<glyph unicode="ƒ" horiz-adv-x="702" d="M-23 -419l14 150q12 -5 45.5 -9t51.5 -4q60 0 94 51.5t34 141.5v1025h-169v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-52.5 3q-87 0 -129 -51.5t-42 -149.5v-137h196v-146h-196v-1025q0 -167 -85.5 -257.5 t-239.5 -90.5q-32 0 -58 4.5t-53 13.5z" />
+<glyph unicode="Ơ" horiz-adv-x="1403" d="M108 598v259q0 266 159.5 443t414.5 177q120 0 223 -40t182 -113q123 11 187 96.5t64 232.5h197q0 -192 -88 -313.5t-250 -157.5q38 -71 59 -154t21 -171v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM305 598q0 -202 102.5 -330t274.5 -128 q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128t-102.5 -328v-261z" />
+<glyph unicode="ơ" horiz-adv-x="1175" d="M97 529v22q0 240 130 395.5t353 155.5q102 0 187 -35t149 -98q82 18 122 84t40 170h178q0 -143 -66.5 -237t-195.5 -126q35 -66 53.5 -144.5t18.5 -164.5v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112 t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="Ư" horiz-adv-x="1430" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-178l6 -2q86 27 132 108.5t46 206.5h190l3 -5q2 -193 -96 -314.5t-281 -155.5v-647q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5z" />
+<glyph unicode="ư" horiz-adv-x="1204" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-114l6 -2q100 7 142.5 71t42.5 190h169l3 -6q3 -177 -85.5 -273t-277.5 -110v-838h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352z" />
+<glyph unicode="ǰ" horiz-adv-x="523" d="M-68 -419l14 150q14 -5 46.5 -9t50.5 -4q59 0 93.5 51.5t34.5 141.5v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM-42 1484v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="Ǻ" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM487 1684q0 72 51 119.5t124 47.5q70 0 120 -47.5t50 -119.5t-49.5 -118t-120.5 -46q-73 0 -124 46t-51 118zM575 1684q0 -35 25.5 -59.5t61.5 -24.5q34 0 58.5 24t24.5 60 q0 37 -24.5 62.5t-58.5 25.5q-36 0 -61.5 -25.5t-25.5 -62.5zM615 1900l144 185h199l2 -6l-216 -179h-129z" />
+<glyph unicode="ǻ" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM383 1362q0 72 51 119.5t124 47.5q70 0 120 -47.5t50 -119.5t-49.5 -118t-120.5 -46q-73 0 -124 46t-51 118zM471 1362 q0 -35 25.5 -59.5t61.5 -24.5q34 0 58.5 24t24.5 60q0 37 -24.5 62.5t-58.5 25.5q-36 0 -61.5 -25.5t-25.5 -62.5zM511 1578l144 185h199l2 -6l-216 -179h-129z" />
+<glyph unicode="Ǽ" horiz-adv-x="1922" d="M-20 0l880 1456h967v-155h-691l20 -466h590v-155h-584l22 -526h705v-154h-895l-15 350h-557l-202 -350h-240zM525 529h447l-31 710l-5 2zM845 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="ǽ" horiz-adv-x="1729" d="M58 304q0 158 115 244.5t335 86.5h229v85q0 106 -51.5 166.5t-149.5 60.5q-103 0 -164 -55t-61 -133l-188 18l-2 6q-5 138 109.5 228.5t305.5 90.5q114 0 201.5 -40.5t137.5 -117.5q64 75 151.5 116.5t188.5 41.5q214 0 329.5 -130t115.5 -358v-119h-709l-2 -5 q1 -159 79.5 -258t233.5 -99q103 0 169.5 27.5t144.5 78.5l67 -138q-53 -44 -147 -83t-234 -39q-136 0 -240 48.5t-170 138.5q-56 -79 -167.5 -133t-271.5 -54q-170 0 -262.5 8
<TRUNCATED>
[32/51] [abbrv] ambari git commit: AMBARI-22384. Disable HDP 2.3
stack. (swagle)
Posted by nc...@apache.org.
AMBARI-22384. Disable HDP 2.3 stack. (swagle)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7074e6e8
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7074e6e8
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7074e6e8
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 7074e6e8a736fbdc1bb3afb86480c6cd349611b0
Parents: 5adcea7
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Wed Nov 8 13:07:11 2017 -0800
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Wed Nov 8 13:07:11 2017 -0800
----------------------------------------------------------------------
ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7074e6e8/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
index f98b24b..9fa9b90 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
@@ -17,7 +17,7 @@
-->
<metainfo>
<versions>
- <active>true</active>
+ <active>false</active>
</versions>
<extends>2.2</extends>
<minJdk>1.7</minJdk>
[22/51] [abbrv] ambari git commit: AMBARI-22337 each service should
be able to implement server actions,
package them add a jar to be loaded during EU (dili)
Posted by nc...@apache.org.
AMBARI-22337 each service should be able to implement server actions, package them add a jar to be loaded during EU (dili)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/063ba36e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/063ba36e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/063ba36e
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 063ba36ef5d2ae2f407b46aae3f993ab81eae310
Parents: 38f6740
Author: Di Li <di...@apache.org>
Authored: Tue Nov 7 10:51:48 2017 -0500
Committer: Di Li <di...@apache.org>
Committed: Tue Nov 7 10:51:48 2017 -0500
----------------------------------------------------------------------
ambari-server/pom.xml | 12 ++
.../serveraction/ServerActionExecutor.java | 147 +++++++++++++++++--
.../ambari/server/stack/ServiceDirectory.java | 29 ++++
.../ambari/server/stack/ServiceModule.java | 8 +
.../apache/ambari/server/state/ServiceInfo.java | 14 ++
.../ambari/server/stack/ServiceModuleTest.java | 30 ++++
.../server/stack/StackManagerExtensionTest.java | 6 +
7 files changed, 232 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index a86acf5..2ecf435 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -198,6 +198,18 @@
</target>
</configuration>
</execution>
+ <execution>
+ <id>generate-test-oozie2-server-actions-dir</id>
+ <phase>process-test-classes</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <mkdir dir="target/test-classes/extensions/EXT/0.1/services/OOZIE2/server_actions/tmp"/>
+ </target>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
index 50e3cfe..e219dc3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
@@ -18,10 +18,17 @@
package org.apache.ambari.server.serveraction;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
@@ -38,11 +45,17 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.actionmanager.Stage;
import org.apache.ambari.server.agent.CommandReport;
import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.security.authorization.internal.InternalAuthenticationToken;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.UpgradeContext.UpgradeServiceSummary;
+import org.apache.ambari.server.state.UpgradeContext.UpgradeSummary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.ClassUtils;
import com.google.inject.Inject;
import com.google.inject.Injector;
@@ -495,7 +508,6 @@ public class ServerActionExecutor {
throw new AmbariException("Missing ExecutionCommand data");
} else {
Map<String, String> roleParams = executionCommand.getRoleParams();
-
if (roleParams == null) {
throw new AmbariException("Missing RoleParams data");
} else {
@@ -504,8 +516,30 @@ public class ServerActionExecutor {
if (actionClassname == null) {
throw new AmbariException("Missing action classname for server action");
} else {
- ServerAction action = createServerAction(actionClassname);
-
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ UpgradeSummary upgradeSummary = executionCommand.getUpgradeSummary();
+ if (upgradeSummary != null) {
+ Map<String, UpgradeServiceSummary> upgradeServiceSummaries = upgradeSummary.services;
+ LOG.debug("UpgradeServiceSummary: " + upgradeServiceSummaries);
+ AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
+ AmbariMetaInfo ambariMetaInfo = ambariManagementController.getAmbariMetaInfo();
+ String serviceName = executionCommand.getServiceName();
+ if (serviceName != null && !serviceName.isEmpty()){
+ LOG.info(String.format("Server action %s is associated with service %s", actionClassname, serviceName));
+ //Execution stage of a given service, only need to examine stack information for this one service
+ UpgradeServiceSummary serviceSummary = upgradeServiceSummaries.get(serviceName);
+ addServiceInfo(services, ambariMetaInfo, serviceSummary.sourceStackId, serviceName);
+ } else {
+ LOG.info(String.format("Server action %s is not associated with a service", actionClassname));
+ //Load all Jars
+ for(String key: upgradeServiceSummaries.keySet()){
+ UpgradeServiceSummary serviceSummary = upgradeServiceSummaries.get(key);
+ addServiceInfo(services, ambariMetaInfo, serviceSummary.sourceStackId, key);
+ }
+ }
+ LOG.info(String.format("Attempt to load server action classes from %s", services.keySet().toString()));
+ }
+ ServerAction action = createServerAction(actionClassname, services);
if (action == null) {
throw new AmbariException("Failed to create server action: " + actionClassname);
} else {
@@ -520,6 +554,30 @@ public class ServerActionExecutor {
}
}
+ private void addServiceInfo(Map<String, ServiceInfo> services, AmbariMetaInfo ambariMetaInfo, String stackId, String serviceName) {
+ List<String> stackInfo = getStackInfo(stackId);
+ LOG.debug(String.format("Stack info list: %s", stackInfo));
+ if (stackInfo.size() > 1) {
+ try {
+ ServiceInfo service = ambariMetaInfo.getService(stackInfo.get(0), stackInfo.get(1), serviceName);
+ LOG.debug(String.format("Adding %s to the list of services for loading external Jars...", service.getName()));
+ services.put(serviceName, service);
+ } catch (AmbariException e) {
+ LOG.error(String.format("Failed to obtain service info for stack %s, service name %s", stackId, serviceName), e);
+ }
+ }
+ }
+
+ private List<String> getStackInfo(String stackId) {
+ LOG.debug(String.format("Stack id: %s", stackId));
+ StringTokenizer tokens = new StringTokenizer(stackId, "-");
+ List<String> info = new ArrayList<String>();
+ while (tokens.hasMoreElements()) {
+ info.add((String)tokens.nextElement());
+ }
+ return info;
+ }
+
/**
* Attempts to create an instance of the ServerAction class implementation specified in
* classname.
@@ -528,24 +586,85 @@ public class ServerActionExecutor {
* @return the instantiated ServerAction implementation
* @throws AmbariException
*/
- private ServerAction createServerAction(String classname) throws AmbariException {
- try {
- Class<?> actionClass = Class.forName(classname);
+ private ServerAction createServerAction(String classname, Map<String, ServiceInfo> services) throws AmbariException {
+ Class<?> actionClass = null;
+ actionClass = getServerActionClass(classname);
+ if (actionClass == null) {
+ LOG.debug(String.format("Did not find %s in Ambari, try to load it from external directories", classname));
+ actionClass = getServiceLevelServerActionClass(classname, services);
+ }
- if (actionClass == null) {
- throw new AmbariException("Unable to load server action class: " + classname);
+ if (actionClass == null) {
+ throw new AmbariException("Unable to load server action class: " + classname);
+ } else {
+ LOG.debug(String.format("Ready to init server action %s", classname));
+ Class<? extends ServerAction> serverActionClass = actionClass.asSubclass(ServerAction.class);
+ if (serverActionClass == null) {
+ throw new AmbariException("Unable to execute server action class, invalid type: " + classname);
} else {
- Class<? extends ServerAction> serverActionClass = actionClass.asSubclass(ServerAction.class);
+ return injector.getInstance(serverActionClass);
+ }
+ }
+ }
- if (serverActionClass == null) {
- throw new AmbariException("Unable to execute server action class, invalid type: " + classname);
- } else {
- return injector.getInstance(serverActionClass);
+ /**
+ * Load server action classes defined in the service level Jar files
+ * */
+ private Class<?> getServiceLevelServerActionClass(String classname, Map<String, ServiceInfo> services) {
+ List<URL> urls = new ArrayList<>();
+ for (ServiceInfo service : services.values()) {
+ LOG.debug(String.format("Checking service %s", service));
+ File dir = service.getServerActionsFolder();
+ if ( dir != null) {
+ LOG.debug(String.format("Service %s, external dir %s",service.getName(), dir.getAbsolutePath()));
+ File[] jars = dir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ LOG.debug(String.format("Checking folder %s", name));
+ return name.endsWith(".jar");
+ }
+ });
+ for (File jar : jars) {
+ try {
+ URL url = jar.toURI().toURL();
+ urls.add(url);
+ LOG.info("Adding server action jar to classpath: {}", url);
+ }
+ catch (Exception e) {
+ LOG.error("Failed to add server action jar to classpath: {}", jar.getAbsolutePath(), e);
+ }
}
+ } else {
+ LOG.error(String.format("%s service server actions folder returned null", service));
+ }
+ }
+
+ ClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), ClassUtils.getDefaultClassLoader());
+ Class<?> actionClass = null;
+ try {
+ actionClass = ClassUtils.resolveClassName(classname, classLoader);
+ LOG.debug(String.format("Found external server action %s", classname));
+ } catch(IllegalArgumentException illegalArgumentException) {
+ LOG.error(String.format("Unable to find server action %s in external server action directories", classname), illegalArgumentException);
+ }
+
+ return actionClass;
+ }
+
+ /**
+ * Load server action classes defined in Ambari source code
+ * */
+ private Class<?> getServerActionClass(String classname) throws AmbariException{
+ Class<?> actionClass = null;
+ try {
+ actionClass = Class.forName(classname);
+ if (actionClass == null) {
+ LOG.warn(String.format("Unable to load server action class: %s from Ambari", classname));
}
} catch (ClassNotFoundException e) {
- throw new AmbariException("Unable to load server action class: " + classname, e);
+ LOG.error(String.format("Unable to load server action class: %s", classname), e);
}
+ return actionClass;
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
index 119163e..7464e61 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
@@ -93,6 +93,11 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
protected File checksDir;
/**
+ * server side action directory path
+ */
+ protected File serverActionsDir;
+
+ /**
* service metainfo file object representation
*/
private ServiceMetainfoXml metaInfoXml;
@@ -118,6 +123,11 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
protected static final String CHECKS_FOLDER_NAME = "checks";
/**
+ * Server actions directory name
+ */
+ protected static final String SERVER_ACTIONS_FOLDER_NAME = "server_actions";
+
+ /**
* service metainfo file name
*/
private static final String SERVICE_METAINFO_FILE_NAME = "metainfo.xml";
@@ -172,6 +182,15 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
}
/**
+ * Obtain the server side actions directory path.
+ *
+ * @return server side actions directory path
+ */
+ public File getServerActionsDir() {
+ return serverActionsDir;
+ }
+
+ /**
* Obtain the metrics file.
*
* @return metrics file
@@ -303,6 +322,7 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
calculatePackageDirectory(stack, service);
calculateUpgradesDirectory(stack, service);
calculateChecksDirectory(stack, service);
+ calculateServerActionsDirectory(stack, service);
}
/**
@@ -378,6 +398,15 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
}
/**
+ * Sets the serverActionsDir if the dir exists and is not empty
+ * @param stack
+ * @param service
+ */
+ protected void calculateServerActionsDirectory(String stack, String service) {
+ serverActionsDir = resolveDirectory(SERVER_ACTIONS_FOLDER_NAME, stack, service);
+ }
+
+ /**
* Unmarshal the metainfo file into its object representation.
*
* @throws AmbariException if the metainfo file doesn't exist or
http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
index 3b3d52c..4eb3858 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
@@ -150,6 +150,7 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
serviceInfo.setServicePackageFolder(serviceDirectory.getPackageDir());
serviceInfo.setServiceUpgradesFolder(serviceDirectory.getUpgradesDir());
serviceInfo.setChecksFolder(serviceDirectory.getChecksDir());
+ serviceInfo.setServerActionsFolder(serviceDirectory.getServerActionsDir());
serviceInfo.setAdvisorFile(serviceDirectory.getAdvisorFile());
serviceInfo.setAdvisorName(serviceDirectory.getAdvisorName(serviceInfo.getName()));
@@ -270,6 +271,13 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
}
/*
+ * Use parent's server actions if the current one does not have any.
+ */
+ if (serviceInfo.getServerActionsFolder() == null) {
+ serviceInfo.setServerActionsFolder(parent.getServerActionsFolder());
+ }
+
+ /*
* If current stack version does not specify the credential store information
* for the service, then use parent definition.
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index 8fe6583..f1c63bf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -305,6 +305,12 @@ public class ServiceInfo implements Validable{
@XmlTransient
private File checksFolder;
+ /**
+ * Stores the path to the server actions folder which contains server actions jars for the given service.
+ */
+ @XmlTransient
+ private File serverActionsFolder;
+
public boolean isDeleted() {
return isDeleted;
}
@@ -796,6 +802,14 @@ public class ServiceInfo implements Validable{
this.checksFolder = checksFolder;
}
+ public File getServerActionsFolder() {
+ return serverActionsFolder;
+ }
+
+ public void setServerActionsFolder(File serverActionsFolder) {
+ this.serverActionsFolder = serverActionsFolder;
+ }
+
/**
* Exposes (and initializes on first use) map of os-specific details.
* @return map of OS specific details keyed by family
http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
index dbdd043..13c32cf 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
@@ -499,6 +499,36 @@ public class ServiceModuleTest {
}
@Test
+ public void testResolve_ServerActionDirectory() throws Exception {
+ File serverActions = new File("server_actions");
+
+ // check directory specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ ServiceModule child = createServiceModule(info);
+ ServiceModule parent = createServiceModule(parentInfo);
+ child.getModuleInfo().setServerActionsFolder(serverActions);
+ resolveService(child, parent);
+ assertEquals(serverActions.getPath(), child.getModuleInfo().getServerActionsFolder().getPath());
+
+ // check directory specified in parent only
+ child = createServiceModule(info);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setServerActionsFolder(serverActions);
+ resolveService(child, parent);
+ assertEquals(serverActions.getPath(), child.getModuleInfo().getServerActionsFolder().getPath());
+
+ // check directory set in both
+ info.setServerActionsFolder(serverActions);
+ child = createServiceModule(info);
+ child.getModuleInfo().setServerActionsFolder(serverActions);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setServerActionsFolder(new File("other"));
+ resolveService(child, parent);
+ assertEquals(serverActions.getPath(), child.getModuleInfo().getServerActionsFolder().getPath());
+ }
+
+ @Test
public void testResolve_CustomCommands() throws Exception {
List<CustomCommandDefinition> customCommands = new ArrayList<>();
CustomCommandDefinition cmd1 = new CustomCommandDefinition();
http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
index 6617b33..bf55e6f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
@@ -140,6 +140,9 @@ public class StackManagerExtensionTest {
File checks = oozie.getChecksFolder();
assertNotNull(checks);
assertTrue("Checks dir is " + checks.getPath(), checks.getPath().contains("extensions/EXT/0.1/services/OOZIE2/checks"));
+ File serverActions = oozie.getServerActionsFolder();
+ assertNotNull(serverActions);
+ assertTrue("Server actions dir is " + serverActions.getPath(), serverActions.getPath().contains("extensions/EXT/0.1/services/OOZIE2/server_actions"));
List<ThemeInfo> themes = oozie.getThemes();
assertNotNull(themes);
assertTrue("Number of themes is " + themes.size(), themes.size() == 1);
@@ -158,6 +161,9 @@ public class StackManagerExtensionTest {
checks = oozie.getChecksFolder();
assertNotNull(checks);
assertTrue("Checks dir is " + checks.getPath(), checks.getPath().contains("extensions/EXT/0.1/services/OOZIE2/checks"));
+ serverActions = oozie.getServerActionsFolder();
+ assertNotNull(serverActions);
+ assertTrue("Server actions dir is " + serverActions.getPath(), serverActions.getPath().contains("extensions/EXT/0.1/services/OOZIE2/server_actions"));
themes = oozie.getThemes();
assertNotNull(themes);
assertTrue("Number of themes is " + themes.size(), themes.size() == 0);
[38/51] [abbrv] ambari git commit: AMBARI-22400 Ambari 3.0: Implement
new design for Admin View: Cluster Information page. (atkach)
Posted by nc...@apache.org.
AMBARI-22400 Ambari 3.0: Implement new design for Admin View: Cluster Information page. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/430dcbf1
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/430dcbf1
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/430dcbf1
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 430dcbf1224996c76276a8c40fb58eb54addd10a
Parents: e968b12
Author: Andrii Tkach <at...@apache.org>
Authored: Thu Nov 9 16:13:29 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Thu Nov 9 16:53:02 2017 +0200
----------------------------------------------------------------------
.../main/resources/ui/admin-web/app/index.html | 3 +-
.../app/scripts/controllers/AppCtrl.js | 2 +-
.../controllers/ClusterInformationCtrl.js | 65 +++++++++++
.../controllers/clusters/ExportBlueprintCtrl.js | 58 ----------
.../app/scripts/controllers/mainCtrl.js | 27 -----
.../ui/admin-web/app/scripts/i18n.config.js | 13 +--
.../ui/admin-web/app/scripts/routes.js | 59 +++++-----
.../app/styles/cluster-information.css | 59 ++++++++++
.../resources/ui/admin-web/app/styles/main.css | 98 -----------------
.../admin-web/app/views/clusterInformation.html | 66 ++++++++++++
.../app/views/clusters/exportBlueprint.html | 40 -------
.../ui/admin-web/app/views/groups/list.html | 3 +-
.../resources/ui/admin-web/app/views/main.html | 107 -------------------
.../app/views/remoteClusters/list.html | 3 +-
.../ui/admin-web/app/views/sideNav.html | 19 ++--
.../admin-web/app/views/stackVersions/list.html | 3 +-
.../ui/admin-web/app/views/users/list.html | 3 +-
.../test/unit/services/Utility_test.js | 2 +-
18 files changed, 240 insertions(+), 390 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index 41cc60f..2b350f0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -121,7 +121,7 @@
<script src="scripts/app.js"></script>
<script src="scripts/routes.js"></script>
<script src="scripts/i18n.config.js"></script>
-<script src="scripts/controllers/mainCtrl.js"></script>
+<script src="scripts/controllers/ClusterInformationCtrl.js"></script>
<script src="scripts/controllers/AppCtrl.js"></script>
<script src="scripts/controllers/SideNavCtrl.js"></script>
<script src="scripts/controllers/authentication/AuthenticationMainCtrl.js"></script>
@@ -142,7 +142,6 @@
<script src="scripts/controllers/ambariViews/CloneViewInstanceCtrl.js"></script>
<script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
<script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script>
-<script src="scripts/controllers/clusters/ExportBlueprintCtrl.js"></script>
<script src="scripts/controllers/stackVersions/StackVersionsCreateCtrl.js"></script>
<script src="scripts/controllers/stackVersions/StackVersionsListCtrl.js"></script>
<script src="scripts/controllers/stackVersions/StackVersionsEditCtrl.js"></script>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
index 4ac5b38..eb9a9b0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
@@ -31,7 +31,7 @@ angular.module('ambariAdminConsole')
return $route.current;
}, function (value) {
var breadcrumbs = [$t('common.admin')];
- if (value && value.$$route.label) {
+ if (value && value.$$route && value.$$route.label) {
breadcrumbs.push(value.$$route.label);
}
$scope.breadcrumbs = breadcrumbs;
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js
new file mode 100644
index 0000000..60a610c
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('ClusterInformationCtrl', ['$scope', '$http', '$location', 'Cluster', '$routeParams', '$translate', '$rootScope',
+function($scope, $http, $location, Cluster, $routeParams, $translate, $rootScope) {
+ var $t = $translate.instant;
+ $scope.isDataLoaded = false;
+
+ $scope.$watch(function() {
+ return $rootScope.cluster;
+ }, function() {
+ $scope.cluster = $rootScope.cluster;
+ if ($scope.cluster) {
+ $scope.getBlueprint();
+ }
+ }, true);
+
+ $scope.getBlueprint = function () {
+ Cluster.getBlueprint({
+ clusterName: $scope.cluster.Clusters.cluster_name
+ }).then(function (data) {
+ console.debug($t('exportBlueprint.dataLoaded'), data);
+ $scope.isDataLoaded = true;
+ var response = JSON.stringify(data, null, 4),
+ lt = /</g,
+ gt = />/g,
+ ap = /'/g,
+ ic = /"/g;
+ $scope.blueprint = response ? response.toString().replace(lt, "<").replace(gt, ">").replace(ap, "'").replace(ic, '"') : "";
+ });
+ };
+
+ $scope.downloadBlueprint = function () {
+ if (window.navigator.msSaveOrOpenBlob) {
+ var blob = new Blob([decodeURIComponent(encodeURI($scope.blueprint))], {
+ type: "text/csv;charset=utf-8;"
+ });
+ navigator.msSaveBlob(blob, 'blueprint.json');
+ } else {
+ var a = document.createElement('a');
+ a.href = 'data:attachment/csv;charset=utf-8,' + encodeURI($scope.blueprint);
+ a.target = '_blank';
+ a.download = 'blueprint.json';
+ document.body.appendChild(a);
+ a.click();
+ }
+ };
+}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js
deleted file mode 100644
index 6b74b40..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-'use strict';
-
-angular.module('ambariAdminConsole')
-.controller('ExportBlueprintCtrl', ['$scope', '$http', '$location', 'Cluster', '$routeParams', '$translate', function($scope, $http, $location, Cluster, $routeParams, $translate) {
- var $t = $translate.instant;
- $scope.identity = angular.identity;
-
- $scope.isDataLoaded = false;
- $scope.clusterName = $routeParams.id;
-
- $scope.getBlueprint = function() {
- Cluster.getBlueprint({
- clusterName: $scope.clusterName
- }).then(function(data) {
- console.debug($t('exportBlueprint.dataLoaded'), data);
- $scope.isDataLoaded = true;
- var response = JSON.stringify(data, null, 4),
- lt = /</g,
- gt = />/g,
- ap = /'/g,
- ic = /"/g;
- $scope.blueprint = response ? response.toString().replace(lt, "<").replace(gt, ">").replace(ap, "'").replace(ic, '"') : "";
- });
- };
-
- $scope.downloadBlueprint = function() {
- if (window.navigator.msSaveOrOpenBlob) {
- var blob = new Blob([decodeURIComponent(encodeURI($scope.blueprint))], {
- type: "text/csv;charset=utf-8;"
- });
- navigator.msSaveBlob(blob, 'blueprint.json');
- } else {
- var a = document.createElement('a');
- a.href = 'data:attachment/csv;charset=utf-8,' + encodeURI($scope.blueprint);
- a.target = '_blank';
- a.download = 'blueprint.json';
- document.body.appendChild(a);
- a.click();
- }
- };
-}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
deleted file mode 100644
index 30f7568..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-'use strict';
-
-angular.module('ambariAdminConsole')
-.controller('MainCtrl',['$scope','$rootScope', function($scope, $rootScope) {
- $scope.$watch(function() {
- return $rootScope.cluster;
- }, function() {
- $scope.cluster = $rootScope.cluster;
- }, true);
-}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
index 73ab064..4ef3ee9 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
@@ -41,7 +41,6 @@ angular.module('ambariAdminConsole')
'common.dashboard': 'Dashboard',
'common.goToDashboard': 'Go to Dashboard',
'common.exportBlueprint': 'Export Blueprint',
- 'common.blueprint': 'Blueprint',
'common.download': 'Download',
'common.noClusters': 'No Clusters',
'common.noViews': 'No Views',
@@ -168,23 +167,12 @@ angular.module('ambariAdminConsole')
'main.title': 'Welcome to Apache Ambari',
'main.noClusterDescription': 'Provision a cluster, manage who can access the cluster, and customize views for Ambari users.',
- 'main.hasClusterDescription': 'Monitor your cluster resources, manage who can access the cluster, and customize views for Ambari users.',
'main.autoLogOut': 'Automatic Logout',
- 'main.operateCluster.title': 'Operate Your Cluster',
- 'main.operateCluster.description': 'Manage the configuration of your cluster and monitor the health of your services',
- 'main.operateCluster.manageRoles': 'Manage Roles',
-
'main.createCluster.title': 'Create a Cluster',
'main.createCluster.description': 'Use the Install Wizard to select services and configure your cluster',
'main.createCluster.launchInstallWizard': 'Launch Install Wizard',
- 'main.manageUsersAndGroups.title': 'Manage Users + Groups',
- 'main.manageUsersAndGroups.description': 'Manage the users and groups that can access Ambari',
-
- 'main.deployViews.title': 'Deploy Views',
- 'main.deployViews.description': 'Create view instances and grant permissions',
-
'main.controls.remainLoggedIn': 'Remain Logged In',
'main.controls.logOut': 'Log Out Now',
@@ -284,6 +272,7 @@ angular.module('ambariAdminConsole')
'clusters.assignRoles': 'Assign roles to these {{term}}',
'clusters.alerts.cannotLoadClusterData': 'Cannot load cluster data',
+ 'clusters.devBlueprint': 'Dev Blueprint',
'groups.createLocal': 'Add Groups',
'groups.name': 'Group name',
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index 2cb077a..486e598 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -19,12 +19,6 @@
angular.module('ambariAdminConsole')
.constant('ROUTES', {
- root: {
- url: '/',
- templateUrl: 'views/main.html',
- controller: 'MainCtrl',
- label: 'Welcome'
- },
authentication: {
main: {
url: '/authentication',
@@ -33,7 +27,7 @@ angular.module('ambariAdminConsole')
}
},
loginActivities: {
- loginMessage:{
+ loginMessage: {
url: '/loginMessage',
templateUrl: 'views/loginActivities/main.html',
controller: 'LoginActivitiesMainCtrl'
@@ -109,19 +103,19 @@ angular.module('ambariAdminConsole')
controller: 'ViewsEditCtrl',
label: 'Views'
},
- createViewUrl:{
+ createViewUrl: {
url: '/urls/new',
templateUrl: 'views/urls/create.html',
controller: 'ViewUrlCtrl',
label: 'Views'
},
- linkViewUrl:{
+ linkViewUrl: {
url: '/urls/link/:viewName/:viewVersion/:viewInstanceName',
templateUrl: 'views/urls/create.html',
controller: 'ViewUrlCtrl',
label: 'Views'
},
- editViewUrl:{
+ editViewUrl: {
url: '/urls/edit/:urlName',
templateUrl: 'views/urls/edit.html',
controller: 'ViewUrlEditCtrl',
@@ -133,19 +127,19 @@ angular.module('ambariAdminConsole')
url: '/stackVersions',
templateUrl: 'views/stackVersions/list.html',
controller: 'StackVersionsListCtrl',
- label: 'Cluster Information'
+ label: 'Versions'
},
create: {
url: '/stackVersions/create',
templateUrl: 'views/stackVersions/stackVersionPage.html',
controller: 'StackVersionsCreateCtrl',
- label: 'Cluster Information'
+ label: 'Versions'
},
edit: {
url: '/stackVersions/:stackName/:versionId/edit',
templateUrl: 'views/stackVersions/stackVersionPage.html',
controller: 'StackVersionsEditCtrl',
- label: 'Cluster Information'
+ label: 'Versions'
}
},
remoteClusters: {
@@ -161,12 +155,12 @@ angular.module('ambariAdminConsole')
controller: 'RemoteClustersCreateCtrl',
label: 'Remote Clusters'
},
- edit: {
- url: '/remoteClusters/:clusterName/edit',
- templateUrl: 'views/remoteClusters/editRemoteClusterPage.html',
- controller: 'RemoteClustersEditCtrl',
- label: 'Remote Clusters'
- }
+ edit: {
+ url: '/remoteClusters/:clusterName/edit',
+ templateUrl: 'views/remoteClusters/editRemoteClusterPage.html',
+ controller: 'RemoteClustersEditCtrl',
+ label: 'Remote Clusters'
+ }
},
clusters: {
manageAccess: {
@@ -180,31 +174,36 @@ angular.module('ambariAdminConsole')
templateUrl: 'views/clusters/userAccessList.html',
controller: 'UserAccessListCtrl'
},
- exportBlueprint: {
- url: '/clusters/:id/exportBlueprint',
- templateUrl: 'views/clusters/exportBlueprint.html',
- controller: 'ExportBlueprintCtrl'
+ clusterInformation: {
+ url: '/clusterInformation',
+ templateUrl: 'views/clusterInformation.html',
+ controller: 'ClusterInformationCtrl',
+ label: 'Cluster Information'
}
},
- dashboard:{
+ dashboard: {
url: '/dashboard',
- controller: ['$window', function($window) {
+ controller: ['$window', function ($window) {
$window.location.replace('/#/main/dashboard');
}],
template: ''
}
})
-.config(['$routeProvider', '$locationProvider', 'ROUTES', function($routeProvider, $locationProvider, ROUTES) {
- var createRoute = function(routeObj) {
- if(routeObj.url){
+.config(['$routeProvider', '$locationProvider', 'ROUTES', function ($routeProvider, $locationProvider, ROUTES) {
+ var createRoute = function (routeObj) {
+ if (routeObj.url) {
$routeProvider.when(routeObj.url, routeObj);
} else {
angular.forEach(routeObj, createRoute);
}
};
+ var rootUrl = ROUTES['clusters']['clusterInformation'].url;
angular.forEach(ROUTES, createRoute);
+ $routeProvider.otherwise({
+ redirectTo: rootUrl
+ });
}])
-.run(['$rootScope', 'ROUTES', 'Settings', function($rootScope, ROUTES, Settings) {
+.run(['$rootScope', 'ROUTES', 'Settings', function ($rootScope, ROUTES, Settings) {
// Make routes available in every template and controller
$rootScope.ROUTES = ROUTES;
$rootScope.$on('$locationChangeStart', function (e, nextUrl) {
@@ -226,7 +225,7 @@ angular.module('ambariAdminConsole')
* @param {string} url
* @returns {string}
*/
- $rootScope.fromSiteRoot = function(url) {
+ $rootScope.fromSiteRoot = function (url) {
var path = url[0] === '/' ? url.substring(1) : url;
return Settings.siteRoot + path;
};
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css
new file mode 100644
index 0000000..63f4150
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+#cluster-information .cluster-name label {
+ font-weight: normal;
+}
+
+#cluster-information .dev-blueprint {
+ line-height: 35px;
+}
+
+#cluster-information .dev-blueprint span {
+ vertical-align: text-top;
+}
+
+#cluster-information .cluster-name label {
+ font-weight: normal;
+}
+
+#cluster-information .dev-blueprint {
+ line-height: 35px;
+}
+
+#cluster-information .dev-blueprint span {
+ vertical-align: text-top;
+}
+
+
+#cluster-information .welcome-header {
+ margin: -15px;
+ padding: 15px 15px 40px 15px;
+ background-color: #f0f0f0;
+ text-align: center;
+}
+
+#cluster-information .create-cluster-section {
+ text-align: center;
+ padding: 30px;
+}
+
+#cluster-information .fa-cloud {
+ font-size: 150px;
+ color: #f0f0f0;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index bd06bc0..4224f62 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -123,14 +123,6 @@
transition: none;
}
-.cluster-installation-progress-label{
- display: block;
- color: #888;
- text-align: center;
- padding: 10px 0;
- cursor: default;
-}
-
.add-item-input span{
display: block;
outline: none;
@@ -236,96 +228,6 @@
.paginator{
margin: 0;
}
-.mainpage .panel-body{
- padding: 20px;
- height: 620px;
-}
-.mainpage h1{
- font-size: 24px;
- margin-top: 10px;
-}
-.mainpage .panel-body #main-operations-boxes {
- padding: 10px;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail{
- display: block;
- height: 230px;
- padding: 8px;
- background-color: #eeeeee;
- margin-bottom: 20px;
- margin-left: 20px;
- margin-right: 10px;
- border: none;
- border-radius: 0;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .title,
-.mainpage .panel-body #main-operations-boxes .thumbnail .description,
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons {
- text-align: center;
- line-height: 1.5;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn{
- width: 200px;
- margin: 5px;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn.userslist-button,
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn.groupslist-button {
- width: 100px;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .glyphicon {
- font-size: 50px;
- text-align: center;
- display: block;
- line-height: 1.5;
-}
-.mainpage .panel-body #main-operations-boxes .col-sm-5 {
- width: 43.5%;
-}
-
-.views-list-table .panel{
- border-radius: 0;
- border: none;
- margin-top: 0;
-}
-.views-list-table h4{
- font-size: 14px;
-}
-.views-list-table .panel-group .panel + .panel{
- margin-top: 0;
-}
-.views-list-table .panel-group .panel .panel-heading{
- border-radius: 0;
- border-top: 1px solid #ddd;
-}
-.views-list-table .panel-group .panel .panel-heading{
- background: #f9f9f9;
-}
-.views-list-table .panel-group .panel:nth-child(even) .panel-heading{
- background: none;
-}
-.views-list-table .panel-group .panel .panel-heading .panel-title{
- font-size: 14px;
- font-weight: normal;
- cursor: pointer;
-}
-.views-list-table .panel-group .panel .panel-body{
- padding-top: 0;
- padding-bottom: 0;
-}
-.views-list-table .panel-group .panel .panel-body table tr:first-child td{
- border-top: none;
-}
-.views-list-table .glyphicon.glyphicon-chevron-right{
- -webkit-transition: all 0.3s;
- -o-transition: all 0.3s;
- transition: all 0.3s;
-}
-.views-list-table .glyphicon.glyphicon-chevron-right.opened{
- -webkit-transform: rotateZ(90deg);
- -ms-transform: rotateZ(90deg);
- -o-transform: rotateZ(90deg);
- transform: rotateZ(90deg);
-}
a.gotoinstance{
font-size: 12px;
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html
new file mode 100644
index 0000000..6334d06
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html
@@ -0,0 +1,66 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.
+-->
+
+<div id="cluster-information">
+ <div ng-show="cluster.Clusters.provisioning_state !== 'INSTALLED'">
+ <div class="welcome-header">
+ <h1>{{'main.title' | translate}}</h1>
+ <span>{{'main.noClusterDescription' | translate}}</span>
+ </div>
+ <div class="create-cluster-section">
+ <h2>{{'main.createCluster.title' | translate}}</h2>
+ <div>
+ <span>
+ {{'main.createCluster.description' | translate}}
+ </span>
+ </div>
+ <div><i class="fa fa-cloud" aria-hidden="true"></i></div>
+ <div>
+ <a href="{{fromSiteRoot('/#/installer/step0')}}" class="btn btn-primary">
+ {{'main.createCluster.launchInstallWizard' | translate}}
+ </a>
+ </div>
+ </div>
+ </div>
+
+ <div ng-show="cluster.Clusters.provisioning_state === 'INSTALLED'">
+ <div class="row">
+ <div class="form-group col-xs-3 cluster-name">
+ <label for="clusterName">{{'views.clusterName' | translate}}*</label>
+ <input type="text" class="form-control" id="clusterName" ng-model="cluster.Clusters.cluster_name">
+ </div>
+ </div>
+ <div>
+ <div class="row dev-blueprint">
+ <div class="col-sm-11"><span>{{'clusters.devBlueprint' | translate}}</span></div>
+ <div class="col-sm-1">
+ <div class="btn btn-default pull-right" ng-click="downloadBlueprint()">{{"common.download" | translate}}
+ </div>
+ </div>
+ </div>
+ <textarea type="text"
+ rows="20"
+ class="form-control"
+ name="blueprint_text"
+ ng-model="blueprint"
+ ng-disabled="true"
+ ng-readonly="true">
+ </textarea>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html
deleted file mode 100644
index 6ccbffe..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you 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.
--->
-<div class="cluster-manage-access-pane" data-ng-init="getBlueprint()" ng-controller="ExportBlueprintCtrl">
- <div class="clearfix">
- <ol class="breadcrumb pull-left">
- <li class="active">{{clusterName}} {{'common.blueprint' | translate}}</li>
- </ol>
- <div class="pull-right top-margin-4">
- <div class="pull-right top-margin-4">
- <div class="btn btn-default" ng-click="downloadBlueprint()">{{"common.download" | translate}}</div>
- </div>
- </div>
- </div>
- <hr>
- <div>
- <textarea type="text"
- rows="20"
- class="form-control"
- name="blueprint_text"
- ng-model="blueprint"
- ng-disabled="true"
- ng-readonly="true">
- </textarea>
- </div>
-</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
index 5271ceb..b39f55d 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
@@ -26,7 +26,6 @@
</link-to>
</div>
</div>
- <hr>
<table class="table table-striped table-hover col-sm-12">
<thead>
<tr>
@@ -63,7 +62,7 @@
<div ng-if="isLoading" class="spinner-container">
<i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
</div>
- <div class="alert alert-info col-sm-12" ng-show="!groups.length && !isLoading">
+ <div class="alert empty-table-alert col-sm-12" ng-show="!groups.length && !isLoading">
{{'common.alerts.nothingToDisplay' | translate: '{term: constants.groups}'}}
</div>
<div class="col-sm-12 table-bar">
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
deleted file mode 100644
index 3c382af..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
+++ /dev/null
@@ -1,107 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you 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.
--->
-<div class="panel panel-default mainpage">
- <div class="panel-body">
- <h1>{{'main.title' | translate}}</h1>
-
- <div id="main-operations-boxes" class="row thumbnails">
- <p ng-hide="cluster">{{'main.noClusterDescription' | translate}}</p>
-
- <p ng-show="cluster">{{'main.hasClusterDescription' | translate}}</p>
-
- <!--Clusters-->
- <div ng-show="cluster" class="col-sm-11 thumbnail">
- <h4 class="title">{{'main.operateCluster.title' | translate}}</h4>
-
- <div class="description">{{'main.operateCluster.description' | translate}}</div>
- <div class="glyphicon glyphicon-cloud"></div>
- <div class="buttons">
- <span ng-class="{active: isActive('clusters.manageAccess')}">
- <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
- class="btn btn-primary permission-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
- {{'main.operateCluster.manageRoles' | translate}}
- </a>
- <a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
- href="#/clusters/{{cluster.Clusters.cluster_name}}/userAccessList"
- class="btn btn-primary permission-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
- {{'main.operateCluster.manageRoles' | translate}}
- </a>
- </span>
- <span>
- <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
- class="btn btn-primary go-dashboard-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
- {{'common.goToDashboard' | translate}}
- </a>
- <a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
- href="{{fromSiteRoot('/#/main/dashboard/metrics')}}" class="btn btn-primary go-dashboard-button"
- ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
- {{'common.goToDashboard' | translate}}
- </a>
- </span>
- </div>
- </div>
- <div ng-hide="cluster" class="col-sm-11 thumbnail">
- <h4 class="title">{{'main.createCluster.title' | translate}}</h4>
-
- <div class="description">{{'main.createCluster.description' | translate}}</div>
- <div class="glyphicon glyphicon-cloud"></div>
- <div class="buttons">
- <a href="{{fromSiteRoot('/#/installer/step0')}}" class="btn btn-primary create-cluster-button">
- {{'main.createCluster.launchInstallWizard' | translate}}
- </a>
- </div>
- </div>
-
- <!--Manage Users and groups-->
- <div class="col-sm-5 thumbnail">
- <h4 class="title">{{'main.manageUsersAndGroups.title' | translate}}</h4>
-
- <div class="description">{{'main.manageUsersAndGroups.description' | translate}}</div>
- <div class="glyphicon glyphicon-user"></div>
- <div class="buttons">
- <span ng-class="{active: isActive('users.list')}">
- <link-to route="users.list" class="btn btn-primary userslist-button">
- {{'common.users' | translate}}
- </link-to>
- </span>
- <span ng-class="{active: isActive('groups.list')}">
- <link-to route="groups.list" class="btn btn-primary groupslist-button">
- {{'common.groups' | translate}}
- </link-to>
- </span>
- </div>
- </div>
-
- <!--Deploy Views-->
- <div class="col-sm-5 thumbnail">
- <h4 class="title">{{'main.deployViews.title' | translate}}</h4>
-
- <div class="description">{{'main.deployViews.description' | translate}}</div>
- <div class="glyphicon glyphicon-th"></div>
- <div ng-class="{active: isActive('views.list')}" class="buttons">
- <link-to route="views.list" class="btn btn-primary viewslist-button">
- {{'common.views' | translate}}
- </link-to>
- </div>
- </div>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
index e3e11d5..8bb6632 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
@@ -27,7 +27,6 @@
</a>
</div>
</div>
- <hr>
<table class="table table-striped table-hover">
<thead>
<tr>
@@ -62,7 +61,7 @@
<div ng-if="isLoading" class="spinner-container">
<i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
</div>
- <div class="alert alert-info col-sm-12" ng-show="!remoteClusters.length && !isLoading">
+ <div class="alert empty-table-alert col-sm-12" ng-show="!remoteClusters.length && !isLoading">
{{'common.alerts.noRemoteClusterDisplay' | translate}}
</div>
<div class="col-sm-12 table-bar">
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
index 09b4cd9..97dc5d3 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
@@ -33,36 +33,43 @@
</li>
</ul>
<ul class="nav side-nav-menu nav-pills nav-stacked">
- <li class="mainmenu-li active">
+ <li class="mainmenu-li active" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED'">
<a title="{{'common.dashboard' | translate}}" rel="tooltip" data-placement="right" href="{{fromSiteRoot('/#/dashboard')}}" class="gotodashboard">
<i class="navigation-icon fa fa-tachometer" aria-hidden="true"></i>
<span class="navigation-menu-item">{{'common.dashboard' | translate}}</span>
</a>
</li>
- <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+ <li class="mainmenu-li dropdown has-sub-menu">
<a title="{{'common.clusterManagement' | translate}}" data-toggle="collapse-sub-menu" rel="tooltip" data-placement="right">
<span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
<i class="navigation-icon fa fa-cloud" aria-hidden="true"></i>
<span class="navigation-menu-item">{{'common.clusterManagement' | translate}}</span>
</a>
<ul class="sub-menu nav nav-pills nav-stacked">
+ <li class="submenu-li" ng-class="{active: isActive('clusters.clusterInformation')}">
+ <a href="#/clusterInformation" class="clusterInformation">
+ {{'common.clusterInformation' | translate}}
+ </a>
+ </li>
<li class="submenu-li" ng-class="{active: isActive('stackVersions.list')}" ng-show="cluster && totalRepos > 0">
- <a href="#/stackVersions">{{'common.clusterInformation' | translate}}</a>
+ <a href="#/stackVersions">{{'common.versions' | translate}}</a>
</li>
<li class="submenu-li" ng-class="{active: isActive('remoteClusters.list')}">
<a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a>
</li>
</ul>
</li>
- <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+ <li class="mainmenu-li dropdown has-sub-menu">
<a title="{{'common.userManagement' | translate}}" rel="tooltip" data-placement="right" data-toggle="collapse-sub-menu">
<span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
<i class="navigation-icon fa fa-users" aria-hidden="true"></i>
<span class="navigation-menu-item">{{'common.userManagement' | translate}}</span>
</a>
<ul class="sub-menu nav nav-pills nav-stacked">
- <li class="submenu-li" ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}">
- <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="roles">Roles</a>
+ <li class="submenu-li"
+ ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}"
+ ng-show="cluster.Clusters.provisioning_state === 'INSTALLED'">
+ <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="roles">{{'common.roles' | translate}}</a>
</li>
<li class="submenu-li" ng-class="{active: isActive('users.list')}">
<link-to route="users.list" class="userslist-link">{{'common.users' | translate}}</link-to>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
index f6b6ee9..99f9ac0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
@@ -27,7 +27,6 @@
</a>
</div>
</div>
- <hr/>
<table class="table table-striped table-hover">
<thead>
<tr>
@@ -119,7 +118,7 @@
<div ng-if="isLoading" class="spinner-container">
<i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
</div>
- <div class="alert alert-info col-sm-12" ng-show="!repos.length && !isLoading">
+ <div class="alert empty-table-alert col-sm-12" ng-show="!repos.length && !isLoading">
{{'common.alerts.nothingToDisplay' | translate: '{term: getConstant("common.version")}'}}
</div>
<div class="col-sm-12 table-bar">
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
index 7b8e12a..12227c3 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
@@ -27,7 +27,6 @@
</link-to>
</div>
</div>
- <hr>
<table class="table table-striped table-hover">
<thead>
<tr>
@@ -80,7 +79,7 @@
<div ng-if="isLoading" class="spinner-container">
<i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
</div>
- <div class="alert alert-info col-sm-12" ng-show="!users.length && !isLoading">
+ <div class="alert empty-table-alert col-sm-12" ng-show="!users.length && !isLoading">
{{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}}
</div>
<div class="col-sm-12 table-bar">
http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
index d17747b..1b76dcf 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
@@ -54,7 +54,7 @@ describe('Utility Service', function () {
httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
items: []
});
- httpBackend.whenGET("views/main.html").respond(200, {});
+ httpBackend.whenGET("views/clusterInformation.html").respond(200, {});
});
});
[04/51] [abbrv] ambari git commit: AMBARI-22358 : VersionUtils
incorrectly compares versions when it has double digits (mradhakrishnan)
Posted by nc...@apache.org.
AMBARI-22358 : VersionUtils incorrectly compares versions when it has double digits (mradhakrishnan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fe02abf6
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fe02abf6
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fe02abf6
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: fe02abf62b1aaee7d48d5ea36eeadfe782294aa4
Parents: f844e5f
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Authored: Thu Nov 2 14:51:11 2017 -0700
Committer: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Committed: Thu Nov 2 14:51:11 2017 -0700
----------------------------------------------------------------------
.../src/main/java/org/apache/ambari/server/utils/VersionUtils.java | 2 +-
.../test/java/org/apache/ambari/server/utils/TestVersionUtils.java | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe02abf6/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
index 65966ed..08948e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
@@ -81,7 +81,7 @@ public class VersionUtils {
}
//String pattern = "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+).*";
- String pattern = "([0-9]+).([0-9]+).([0-9]+).([0-9]+)?.*";
+ String pattern = "([0-9]+).([0-9]+).([0-9]+).?([0-9]+)?.*";
String[] version1Parts = version1.replaceAll(pattern, "$1.$2.$3.$4").split("\\.");
String[] version2Parts = version2.replaceAll(pattern, "$1.$2.$3.$4").split("\\.");
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe02abf6/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
index 9d20a01..6ad4e26 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
@@ -118,6 +118,7 @@ public class TestVersionUtils {
//Assert.assertEquals(-1, VersionUtils.compareVersions("1.2.3_MYAMBARI_000000", "1.2.4_MYAMBARI_000000"));
Assert.assertEquals(1, VersionUtils.compareVersions("1.2.4_MYAMBARI_000000", "1.2.3_MYAMBARI_000000"));
Assert.assertEquals(0, VersionUtils.compareVersions("1.2.3_MYAMBARI_000000", "1.2.3_MYAMBARI_000000"));
+ Assert.assertEquals(0, VersionUtils.compareVersions("2.99.99.0", "2.99.99"));
Assert.assertEquals(-1, VersionUtils.compareVersions("1.2.3_MYAMBARI_000000", "1.2.4_MYAMBARI_000000", 3));
Assert.assertEquals(1, VersionUtils.compareVersions("1.2.4_MYAMBARI_000000", "1.2.3_MYAMBARI_000000", 3));
[28/51] [abbrv] ambari git commit: AMBARI-22361. Fix bug in
base_alert when matching hostnames (stephanesan via dlysnichenko)
Posted by nc...@apache.org.
AMBARI-22361. Fix bug in base_alert when matching hostnames (stephanesan via dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0f67d1c6
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0f67d1c6
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0f67d1c6
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 0f67d1c690f019ef5289e9bbb4aa93abb607b40b
Parents: 30a43c9
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Wed Nov 8 13:28:03 2017 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Wed Nov 8 13:28:03 2017 +0200
----------------------------------------------------------------------
ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f67d1c6/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index 05f8023..5c0305e 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -463,7 +463,7 @@ class BaseAlert(object):
# get the host for dfs.namenode.http-address.c1ha.nn1 and see if it's
# this host
value = self._get_configuration_value(key)
- if value is not None and (self.host_name in value or self.public_host_name in value):
+ if value is not None and (self.host_name.lower() in value.lower() or self.public_host_name.lower() in value.lower()):
return AlertUri(uri=value, is_ssl_enabled=is_ssl_enabled)
return None
[02/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC
integration (rlevas)
Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
index 0997f65..bbcd6e8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
@@ -18,21 +18,17 @@
package org.apache.ambari.server.serveraction.kerberos;
-import java.text.NumberFormat;
-import java.text.ParseException;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Set;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.utils.ShellCommandUtil;
-import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,37 +41,24 @@ import com.google.inject.Inject;
* It is assumed that a MIT Kerberos client is installed and that the kdamin shell command is
* available
*/
-public class MITKerberosOperationHandler extends KerberosOperationHandler {
+public class MITKerberosOperationHandler extends KDCKerberosOperationHandler {
+
+ private final static Logger LOG = LoggerFactory.getLogger(MITKerberosOperationHandler.class);
@Inject
private Configuration configuration;
/**
- * A regular expression pattern to use to parse the key number from the text captured from the
- * get_principal kadmin command
- */
- private final static Pattern PATTERN_GET_KEY_NUMBER = Pattern.compile("^.*?Key: vno (\\d+).*$", Pattern.DOTALL);
-
- private final static Logger LOG = LoggerFactory.getLogger(MITKerberosOperationHandler.class);
-
- /**
* A String containing user-specified attributes used when creating principals
*/
private String createAttributes = null;
- private String adminServerHost = null;
-
/**
* A String containing the resolved path to the kdamin executable
*/
private String executableKadmin = null;
/**
- * A String containing the resolved path to the kdamin.local executable
- */
- private String executableKadminLocal = null;
-
- /**
* Prepares and creates resources to be used by this KerberosOperationHandler
* <p/>
* It is expected that this KerberosOperationHandler will not be used before this call.
@@ -92,39 +75,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public void open(PrincipalKeyCredential administratorCredentials, String realm,
- Map<String, String> kerberosConfiguration)
+ public void open(PrincipalKeyCredential administratorCredentials, String realm, Map<String, String> kerberosConfiguration)
throws KerberosOperationException {
- setAdministratorCredential(administratorCredentials);
- setDefaultRealm(realm);
-
if (kerberosConfiguration != null) {
- setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
- setAdminServerHost(kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST));
- setExecutableSearchPaths(kerberosConfiguration.get(KERBEROS_ENV_EXECUTABLE_SEARCH_PATHS));
- setCreateAttributes(kerberosConfiguration.get(KERBEROS_ENV_KDC_CREATE_ATTRIBUTES));
- } else {
- setKeyEncryptionTypes(null);
- setAdminServerHost(null);
- setExecutableSearchPaths((String) null);
- setCreateAttributes(null);
+ createAttributes = kerberosConfiguration.get(KERBEROS_ENV_KDC_CREATE_ATTRIBUTES);
}
// Pre-determine the paths to relevant Kerberos executables
executableKadmin = getExecutable("kadmin");
- executableKadminLocal = getExecutable("kadmin.local");
- setOpen(true);
+ super.open(administratorCredentials, realm, kerberosConfiguration);
}
@Override
public void close() throws KerberosOperationException {
- // There is nothing to do here.
- setOpen(false);
-
+ createAttributes = null;
executableKadmin = null;
- executableKadminLocal = null;
+
+ super.close();
}
/**
@@ -134,6 +103,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* the result from STDOUT to determine if the presence of the specified principal.
*
* @param principal a String containing the principal to test
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal exists; false otherwise
* @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
* @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -141,26 +111,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public boolean principalExists(String principal)
+ public boolean principalExists(String principal, boolean service)
throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
- if (principal == null) {
- return false;
- } else {
+ if (!StringUtils.isEmpty(principal)) {
// Create the KAdmin query to execute:
- ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal), null);
+ ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal));
// If there is data from STDOUT, see if the following string exists:
// Principal: <principal>
String stdOut = result.getStdout();
return (stdOut != null) && stdOut.contains(String.format("Principal: %s", principal));
}
- }
+ return false;
+ }
/**
* Creates a new principal in a previously configured MIT KDC
@@ -188,72 +157,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
if (StringUtils.isEmpty(principal)) {
throw new KerberosOperationException("Failed to create new principal - no principal specified");
- } else if (StringUtils.isEmpty(password)) {
- throw new KerberosOperationException("Failed to create new principal - no password specified");
- } else {
- String createAttributes = getCreateAttributes();
- // Create the kdamin query: add_principal <-randkey|-pw <password>> [<options>] <principal>
- ShellCommandUtil.Result result = invokeKAdmin(String.format("add_principal %s %s",
- (createAttributes == null) ? "" : createAttributes, principal), password);
-
- // If there is data from STDOUT, see if the following string exists:
- // Principal "<principal>" created
- String stdOut = result.getStdout();
- String stdErr = result.getStderr();
- if ((stdOut != null) && stdOut.contains(String.format("Principal \"%s\" created", principal))) {
- return getKeyNumber(principal);
- } else if ((stdErr != null) && stdErr.contains(String.format("Principal or policy already exists while creating \"%s\"", principal))) {
- throw new KerberosPrincipalAlreadyExistsException(principal);
- } else {
- LOG.error("Failed to execute kadmin query: add_principal -pw \"********\" {} {}\nSTDOUT: {}\nSTDERR: {}",
- (createAttributes == null) ? "" : createAttributes, principal, stdOut, result.getStderr());
- throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
- principal, stdOut, result.getStderr()));
- }
- }
- }
-
- /**
- * Updates the password for an existing principal in a previously configured MIT KDC
- * <p/>
- * This implementation creates a query to send to the kadmin shell command and then interrogates
- * the exit code to determine if the operation executed successfully.
- *
- * @param principal a String containing the principal to update
- * @param password a String containing the password to set
- * @return an Integer declaring the new key number
- * @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
- * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
- * @throws KerberosRealmException if the realm does not map to a KDC
- * @throws KerberosPrincipalDoesNotExistException if the principal does not exist
- * @throws KerberosOperationException if an unexpected error occurred
- */
- @Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
- if (!isOpen()) {
- throw new KerberosOperationException("This operation handler has not been opened");
}
- if (StringUtils.isEmpty(principal)) {
- throw new KerberosOperationException("Failed to set password - no principal specified");
- } else if (StringUtils.isEmpty(password)) {
- throw new KerberosOperationException("Failed to set password - no password specified");
+ // Create the kdamin query: add_principal <-randkey|-pw <password>> [<options>] <principal>
+ ShellCommandUtil.Result result = invokeKAdmin(String.format("add_principal -randkey %s %s",
+ (createAttributes == null) ? "" : createAttributes, principal));
+
+ // If there is data from STDOUT, see if the following string exists:
+ // Principal "<principal>" created
+ String stdOut = result.getStdout();
+ String stdErr = result.getStderr();
+ if ((stdOut != null) && stdOut.contains(String.format("Principal \"%s\" created", principal))) {
+ return 0;
+ } else if ((stdErr != null) && stdErr.contains(String.format("Principal or policy already exists while creating \"%s\"", principal))) {
+ throw new KerberosPrincipalAlreadyExistsException(principal);
} else {
- // Create the kdamin query: change_password <-randkey|-pw <password>> <principal>
- ShellCommandUtil.Result result = invokeKAdmin(String.format("change_password %s", principal), password);
-
- String stdOut = result.getStdout();
- String stdErr = result.getStderr();
- if ((stdOut != null) && stdOut.contains(String.format("Password for \"%s\" changed", principal))) {
- return getKeyNumber(principal);
- } else if ((stdErr != null) && stdErr.contains("Principal does not exist")) {
- throw new KerberosPrincipalDoesNotExistException(principal);
- } else {
- LOG.error("Failed to execute kadmin query: change_password -pw \"********\" {} \nSTDOUT: {}\nSTDERR: {}",
- principal, stdOut, result.getStderr());
- throw new KerberosOperationException(String.format("Failed to update password for %s\nSTDOUT: %s\nSTDERR: %s",
- principal, stdOut, result.getStderr()));
- }
+ LOG.error("Failed to execute kadmin query: add_principal -pw \"********\" {} {}\nSTDOUT: {}\nSTDERR: {}",
+ (createAttributes == null) ? "" : createAttributes, principal, stdOut, result.getStderr());
+ throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
+ principal, stdOut, result.getStderr()));
}
}
@@ -263,6 +185,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* The implementation is specific to a particular type of KDC.
*
* @param principal a String containing the principal to remove
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal was successfully removed; otherwise false
* @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
* @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -270,181 +193,63 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
if (StringUtils.isEmpty(principal)) {
- throw new KerberosOperationException("Failed to remove new principal - no principal specified");
- } else {
- ShellCommandUtil.Result result = invokeKAdmin(String.format("delete_principal -force %s", principal), null);
-
- // If there is data from STDOUT, see if the following string exists:
- // Principal "<principal>" created
- String stdOut = result.getStdout();
- return (stdOut != null) && !stdOut.contains("Principal does not exist");
+ throw new KerberosOperationException("Failed to remove principal - no principal specified");
}
- }
- /**
- * Sets the KDC administrator server host address
- *
- * @param adminServerHost the ip address or FQDN of the KDC administrator server
- */
- public void setAdminServerHost(String adminServerHost) {
- this.adminServerHost = adminServerHost;
- }
+ ShellCommandUtil.Result result = invokeKAdmin(String.format("delete_principal -force %s", principal));
- /**
- * Gets the IP address or FQDN of the KDC administrator server
- *
- * @return the IP address or FQDN of the KDC administrator server
- */
- public String getAdminServerHost() {
- return this.adminServerHost;
- }
-
- /**
- * Sets the (additional) principal creation attributes
- *
- * @param createAttributes the additional principal creations attributes
- */
- public void setCreateAttributes(String createAttributes) {
- this.createAttributes = createAttributes;
- }
-
- /**
- * Gets the (additional) principal creation attributes
- *
- * @return the additional principal creations attributes or null
- */
- public String getCreateAttributes() {
- return createAttributes;
- }
-
- /**
- * Retrieves the current key number assigned to the identity identified by the specified principal
- *
- * @param principal a String declaring the principal to look up
- * @return an Integer declaring the current key number
- * @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
- * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
- * @throws KerberosRealmException if the realm does not map to a KDC
- * @throws KerberosOperationException if an unexpected error occurred
- */
- private Integer getKeyNumber(String principal) throws KerberosOperationException {
- if (!isOpen()) {
- throw new KerberosOperationException("This operation handler has not been opened");
- }
-
- if (StringUtils.isEmpty(principal)) {
- throw new KerberosOperationException("Failed to get key number for principal - no principal specified");
- } else {
- // Create the kdamin query: get_principal <principal>
- ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal), null);
-
- String stdOut = result.getStdout();
- if (stdOut == null) {
- String message = String.format("Failed to get key number for %s:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
-
- Matcher matcher = PATTERN_GET_KEY_NUMBER.matcher(stdOut);
- if (matcher.matches()) {
- NumberFormat numberFormat = NumberFormat.getIntegerInstance();
- String keyNumber = matcher.group(1);
-
- numberFormat.setGroupingUsed(false);
- try {
- Number number = numberFormat.parse(keyNumber);
- return (number == null) ? 0 : number.intValue();
- } catch (ParseException e) {
- String message = String.format("Failed to get key number for %s - invalid key number value (%s):\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, keyNumber, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
- } else {
- String message = String.format("Failed to get key number for %s - unexpected STDOUT data:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
- }
+ // If there is data from STDOUT, see if the following string exists:
+ // Principal "<principal>" created
+ String stdOut = result.getStdout();
+ return (stdOut != null) && !stdOut.contains("Principal does not exist");
}
/**
* Invokes the kadmin shell command to issue queries
*
- * @param query a String containing the query to send to the kdamin command
- * @param userPassword a String containing the user's password to set or update if necessary,
- * null if not needed
+ * @param query a String containing the query to send to the kdamin command
* @return a ShellCommandUtil.Result containing the result of the operation
* @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
* @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
* @throws KerberosRealmException if the realm does not map to a KDC
* @throws KerberosOperationException if an unexpected error occurred
*/
- protected ShellCommandUtil.Result invokeKAdmin(String query, String userPassword)
+ protected ShellCommandUtil.Result invokeKAdmin(String query)
throws KerberosOperationException {
if (StringUtils.isEmpty(query)) {
throw new KerberosOperationException("Missing kadmin query");
}
- ShellCommandUtil.Result result = null;
- PrincipalKeyCredential administratorCredential = getAdministratorCredential();
- String defaultRealm = getDefaultRealm();
+ if (StringUtils.isEmpty(executableKadmin)) {
+ throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
+ }
List<String> command = new ArrayList<>();
+ command.add(executableKadmin);
- String adminPrincipal = (administratorCredential == null)
- ? null
- : administratorCredential.getPrincipal();
-
- ShellCommandUtil.InteractiveHandler interactiveHandler = null;
-
- if (StringUtils.isEmpty(adminPrincipal)) {
- // Set the kdamin interface to be kadmin.local
- if (StringUtils.isEmpty(executableKadminLocal)) {
- throw new KerberosOperationException("No path for kadmin.local is available - this KerberosOperationHandler may not have been opened.");
- }
-
- command.add(executableKadminLocal);
-
- if (userPassword != null) {
- interactiveHandler = new InteractivePasswordHandler(null, userPassword);
- }
- } else {
- if (StringUtils.isEmpty(executableKadmin)) {
- throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
- }
- char[] adminPassword = administratorCredential.getKey();
-
- // Set the kdamin interface to be kadmin
- command.add(executableKadmin);
-
- // Add explicit KDC admin host, if available
- if (!StringUtils.isEmpty(getAdminServerHost())) {
- command.add("-s");
- command.add(getAdminServerHost());
- }
-
- // Add the administrative principal
- command.add("-p");
- command.add(adminPrincipal);
+ // Add the credential cache, if available
+ String credentialCacheFilePath = getCredentialCacheFilePath();
+ if (!StringUtils.isEmpty(credentialCacheFilePath)) {
+ command.add("-c");
+ command.add(credentialCacheFilePath);
+ }
- if (!ArrayUtils.isEmpty(adminPassword)) {
- interactiveHandler = new InteractivePasswordHandler(String.valueOf(adminPassword), userPassword);
- } else if (userPassword != null) {
- interactiveHandler = new InteractivePasswordHandler(null, userPassword);
- }
+ // Add explicit KDC admin host, if available
+ String adminSeverHost = getAdminServerHost();
+ if (!StringUtils.isEmpty(adminSeverHost)) {
+ command.add("-s");
+ command.add(adminSeverHost);
}
+ // Add default realm clause, if available
+ String defaultRealm = getDefaultRealm();
if (!StringUtils.isEmpty(defaultRealm)) {
- // Add default realm clause
command.add("-r");
command.add(defaultRealm);
}
@@ -457,12 +262,13 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
LOG.debug("Executing: {}", command);
}
+ ShellCommandUtil.Result result = null;
int retryCount = configuration.getKerberosOperationRetries();
int tries = 0;
while (tries <= retryCount) {
try {
- result = executeCommand(command.toArray(new String[command.size()]), null, interactiveHandler);
+ result = executeCommand(command.toArray(new String[command.size()]));
} catch (KerberosOperationException exception) {
if (tries == retryCount) {
throw exception;
@@ -486,13 +292,16 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
}
- if (!result.isSuccessful()) {
+ if ((result == null) || !result.isSuccessful()) {
+ int exitCode = (result == null) ? -999 : result.getExitCode();
+ String stdOut = (result == null) ? "" : result.getStdout();
+ String stdErr = (result == null) ? "" : result.getStderr();
+
String message = String.format("Failed to execute kadmin:\n\tCommand: %s\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
- command, result.getExitCode(), result.getStdout(), result.getStderr());
+ command, exitCode, stdOut, stdErr);
LOG.warn(message);
// Test STDERR to see of any "expected" error conditions were encountered...
- String stdErr = result.getStderr();
// Did admin credentials fail?
if (stdErr.contains("Client not found in Kerberos database")) {
throw new KerberosAdminAuthenticationException(stdErr);
@@ -513,57 +322,56 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
} else {
throw new KerberosOperationException(String.format("Unexpected error condition executing the kadmin command. STDERR: %s", stdErr));
}
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Executed the following command:\n{}\nSTDOUT: {}\nSTDERR: {}",
+ StringUtils.join(command, " "), result.getStdout(), result.getStderr());
+ }
}
return result;
}
- /**
- * InteractivePasswordHandler is a {@link org.apache.ambari.server.utils.ShellCommandUtil.InteractiveHandler}
- * implementation that answers queries from kadmin or kdamin.local command for the admin and/or user
- * passwords.
- */
- protected static class InteractivePasswordHandler implements ShellCommandUtil.InteractiveHandler {
- /**
- * The queue of responses to return
- */
- private LinkedList<String> responses;
- private Queue<String> currentResponses;
-
- /**
- * Constructor.
- *
- * @param adminPassword the KDC administrator's password (optional)
- * @param userPassword the user's password (optional)
- */
- public InteractivePasswordHandler(String adminPassword, String userPassword) {
- responses = new LinkedList<>();
-
- if (adminPassword != null) {
- responses.offer(adminPassword);
- }
+ @Override
+ protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache) {
+ // kinit -c <path> -S kadmin/`hostname -f` <principal>
+ return new String[]{
+ executableKinit,
+ "-c",
+ credentialsCache,
+ "-S",
+ String.format("kadmin/%s", getAdminServerHost()),
+ credentials.getPrincipal()
+ };
+ }
- if (userPassword != null) {
- responses.offer(userPassword);
- responses.offer(userPassword); // Add a 2nd time for the password "confirmation" request
+ @Override
+ protected void exportKeytabFile(String principal, String keytabFileDestinationPath, Set<EncryptionType> keyEncryptionTypes) throws KerberosOperationException {
+ String encryptionTypeSpec = null;
+ if (!CollectionUtils.isEmpty(keyEncryptionTypes)) {
+ StringBuilder encryptionTypeSpecBuilder = new StringBuilder();
+ for (EncryptionType encryptionType : keyEncryptionTypes) {
+ if (encryptionTypeSpecBuilder.length() > 0) {
+ encryptionTypeSpecBuilder.append(',');
+ }
+ encryptionTypeSpecBuilder.append(encryptionType.getName());
+ encryptionTypeSpecBuilder.append(":normal");
}
- currentResponses = new LinkedList<>(responses);
+ encryptionTypeSpec = encryptionTypeSpecBuilder.toString();
}
- @Override
- public boolean done() {
- return currentResponses.size() == 0;
- }
+ String query = (StringUtils.isEmpty(encryptionTypeSpec))
+ ? String.format("xst -k \"%s\" %s", keytabFileDestinationPath, principal)
+ : String.format("xst -k \"%s\" -e %s %s", keytabFileDestinationPath, encryptionTypeSpec, principal);
- @Override
- public String getResponse(String query) {
- return currentResponses.poll();
- }
+ ShellCommandUtil.Result result = invokeKAdmin(query);
- @Override
- public void start() {
- currentResponses = new LinkedList<>(responses);
+ if (!result.isSuccessful()) {
+ String message = String.format("Failed to export the keytab file for %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+ principal, result.getExitCode(), result.getStdout(), result.getStderr());
+ LOG.warn(message);
+ throw new KerberosOperationException(message);
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
index bfe2a13..d3e924e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
@@ -45,6 +45,7 @@ import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -149,6 +150,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
showHcatDeletedUserMessage();
setStatusOfStagesAndRequests();
updateLogSearchConfigs();
+ updateKerberosConfigurations();
}
protected void showHcatDeletedUserMessage() {
@@ -265,7 +267,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
"logsearch-common-properties", Collections.emptyMap(), "ambari-upgrade",
String.format("Updated logsearch-common-properties during Ambari Upgrade from %s to %s",
getSourceVersion(), getTargetVersion()));
-
+
String defaultLogLevels = logSearchProperties.getProperties().get("logsearch.logfeeder.include.default.level");
Set<String> removeProperties = Sets.newHashSet("logsearch.logfeeder.include.default.level");
@@ -324,7 +326,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
updateConfigurationPropertiesForCluster(cluster, "logsearch-audit_logs-solrconfig", Collections.singletonMap("content", content), true, true);
}
}
-
+
Config logFeederOutputConfig = cluster.getDesiredConfigByType("logfeeder-output-config");
if (logFeederOutputConfig != null) {
String content = logFeederOutputConfig.getProperties().get("content");
@@ -346,4 +348,28 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
}
}
}
+
+ protected void updateKerberosConfigurations() throws AmbariException {
+ AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
+ Clusters clusters = ambariManagementController.getClusters();
+ if (clusters != null) {
+ Map<String, Cluster> clusterMap = clusters.getClusters();
+
+ if (!MapUtils.isEmpty(clusterMap)) {
+ for (Cluster cluster : clusterMap.values()) {
+ Config config = cluster.getDesiredConfigByType("kerberos-env");
+
+ if (config != null) {
+ Map<String, String> properties = config.getProperties();
+ if (properties.containsKey("group")) {
+ // Covert kerberos-env/group to kerberos-env/ipa_user_group
+ updateConfigurationPropertiesForCluster(cluster, "kerberos-env",
+ Collections.singletonMap("ipa_user_group", properties.get("group")), Collections.singleton("group"),
+ true, false);
+ }
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
index 0a08121..293bcf8 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
@@ -349,8 +349,8 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>group</name>
- <display-name>IPA Group</display-name>
+ <name>ipa_user_group</name>
+ <display-name>IPA User Group</display-name>
<description>
The group in IPA user principals should be member of
</description>
@@ -362,38 +362,6 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>set_password_expiry</name>
- <display-name>Set IPA principal password expiry</display-name>
- <description>
- Indicates whether Ambari should set the password expiry for the principals it creates. By default
- IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
- attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
- policy is in place for the IPA Group principals are added to.
- </description>
- <value>false</value>
- <value-attributes>
- <type>boolean</type>
- <overridable>false</overridable>
- <visible>false</visible>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
- <name>password_chat_timeout</name>
- <display-name>Set IPA kinit password chat timeout</display-name>
- <description>
- Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
- because it can take some time due to lookups before a response is there.
- </description>
- <value>5</value>
- <value-attributes>
- <visible>false</visible>
- <type>int</type>
- <overridable>false</overridable>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
<name>preconfigure_services</name>
<display-name>Pre-configure services</display-name>
<description>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
index 0a08121..293bcf8 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
@@ -349,8 +349,8 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>group</name>
- <display-name>IPA Group</display-name>
+ <name>ipa_user_group</name>
+ <display-name>IPA User Group</display-name>
<description>
The group in IPA user principals should be member of
</description>
@@ -362,38 +362,6 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>set_password_expiry</name>
- <display-name>Set IPA principal password expiry</display-name>
- <description>
- Indicates whether Ambari should set the password expiry for the principals it creates. By default
- IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
- attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
- policy is in place for the IPA Group principals are added to.
- </description>
- <value>false</value>
- <value-attributes>
- <type>boolean</type>
- <overridable>false</overridable>
- <visible>false</visible>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
- <name>password_chat_timeout</name>
- <display-name>Set IPA kinit password chat timeout</display-name>
- <description>
- Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
- because it can take some time due to lookups before a response is there.
- </description>
- <value>5</value>
- <value-attributes>
- <visible>false</visible>
- <type>int</type>
- <overridable>false</overridable>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
<name>preconfigure_services</name>
<display-name>Pre-configure services</display-name>
<description>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
index 66e81db..a66a7a6 100644
--- a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
@@ -348,8 +348,8 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>group</name>
- <display-name>IPA Group</display-name>
+ <name>ipa_user_group</name>
+ <display-name>IPA User Group</display-name>
<description>
The group in IPA user principals should be member of
</description>
@@ -360,36 +360,4 @@
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
- <property>
- <name>set_password_expiry</name>
- <display-name>Set IPA principal password expiry</display-name>
- <description>
- Indicates whether Ambari should set the password expiry for the principals it creates. By default
- IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
- attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
- policy is in place for the IPA Group principals are added to.
- </description>
- <value>false</value>
- <value-attributes>
- <type>boolean</type>
- <overridable>false</overridable>
- <visible>false</visible>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
- <name>password_chat_timeout</name>
- <display-name>Set IPA kinit password chat timeout</display-name>
- <description>
- Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
- because it can take some time due to lookups before a response is there.
- </description>
- <value>5</value>
- <value-attributes>
- <visible>false</visible>
- <type>int</type>
- <overridable>false</overridable>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
index a3074ae..ee87d24 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
@@ -188,7 +188,7 @@ public class KerberosHelperTest extends EasyMockSupport {
}
@Override
- public boolean principalExists(String principal) throws KerberosOperationException {
+ public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
return "principal".equals(principal);
}
@@ -198,12 +198,12 @@ public class KerberosHelperTest extends EasyMockSupport {
}
@Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+ public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
return null;
}
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
return false;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
index 483cc0a..8b3c19a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
@@ -19,11 +19,15 @@
package org.apache.ambari.server.serveraction.kerberos;
import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isNull;
import static org.easymock.EasyMock.newCapture;
import static org.easymock.EasyMock.replay;
+import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
@@ -50,6 +54,8 @@ import org.apache.ambari.server.state.stack.OsFamily;
import org.easymock.Capture;
import org.easymock.CaptureType;
import org.easymock.IAnswer;
+import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@@ -65,6 +71,36 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
private static final String DEFAULT_LDAP_URL = "ldaps://10.0.100.4";
private static final String DEFAULT_PRINCIPAL_CONTAINER_DN = "ou=HDP,DC=HDP01,DC=LOCAL";
private static final String DEFAULT_REALM = "HDP01.LOCAL";
+ private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
+ {
+ put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
+ put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
+ }
+ };
+
+ private static Method methodCreateInitialLdapContext;
+
+ private Injector injector;
+ private LdapContext ldapContext;
+
+ @BeforeClass
+ public static void beforeMITKerberosOperationHandlerTest() throws Exception {
+ methodCreateInitialLdapContext = ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class);
+ }
+
+ @Before
+ public void setup() {
+ injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
+ bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ }
+ });
+
+ ldapContext = createMock(LdapContext.class);
+ }
@Test(expected = KerberosKDCConnectionException.class)
public void testOpenExceptionLdapUrlNotProvided() throws Exception {
@@ -95,13 +131,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
@Test(expected = KerberosAdminAuthenticationException.class)
public void testOpenExceptionAdminCredentialsNotProvided() throws Exception {
KerberosOperationHandler handler = new ADKerberosOperationHandler();
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
- handler.open(null, DEFAULT_REALM, kerberosEnvMap);
+
+ handler.open(null, DEFAULT_REALM, getKerberosEnv());
handler.close();
}
@@ -124,13 +155,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, "wrong");
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
-
ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
.addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
.createNiceMock();
@@ -145,7 +169,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -155,12 +179,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential("wrong", DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
.addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
@@ -176,7 +194,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -184,17 +202,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
@Test(expected = KerberosKDCConnectionException.class)
public void testTestAdministratorCredentialsKDCConnectionException() throws Exception {
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, "invalid");
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
-
- ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
- .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
- .createNiceMock();
+ ADKerberosOperationHandler handler = createMockedHandler(methodCreateInitialLdapContext);
expect(handler.createInitialLdapContext(anyObject(Properties.class), anyObject(Control[].class))).andAnswer(new IAnswer<LdapContext>() {
@Override
public LdapContext answer() throws Throwable {
@@ -204,7 +213,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -212,21 +221,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
@Test
public void testTestAdministratorCredentialsSuccess() throws Exception {
- Injector injector = getInjector();
-
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
-
- ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
- .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
- .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createSearchControls"))
- .createNiceMock();
- injector.injectMembers(handler);
+ ADKerberosOperationHandler handler = createMockedHandler(methodCreateInitialLdapContext);
expect(handler.createInitialLdapContext(anyObject(Properties.class), anyObject(Control[].class)))
.andAnswer(new IAnswer<LdapContext>() {
@@ -245,23 +241,14 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
}
})
.once();
- replay(ldapContext);
return ldapContext;
}
})
.once();
- expect(handler.createSearchControls()).andAnswer(new IAnswer<SearchControls>() {
- @Override
- public SearchControls answer() throws Throwable {
- SearchControls searchControls = createNiceMock(SearchControls.class);
- replay(searchControls);
- return searchControls;
- }
- }).once();
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -271,12 +258,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
Capture<Name> capturedName = newCapture(CaptureType.ALL);
Capture<Attributes> capturedAttributes = newCapture(CaptureType.ALL);
@@ -315,7 +296,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.createPrincipal("nn/c6501.ambari.apache.org", "secret", true);
handler.createPrincipal("hdfs@" + DEFAULT_REALM, "secret", false);
handler.close();
@@ -384,31 +365,26 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
- "#set( $user = \"${principal_primary}-${principal_digest}\" )" +
- "{" +
- " \"objectClass\": [" +
- " \"top\"," +
- " \"person\"," +
- " \"organizationalPerson\"," +
- " \"user\"" +
- " ]," +
- " \"cn\": \"$user\"," +
- " \"sAMAccountName\": \"$user.substring(0,20)\"," +
- " #if( $is_service )" +
- " \"servicePrincipalName\": \"$principal_name\"," +
- " #end" +
- " \"userPrincipalName\": \"$normalized_principal\"," +
- " \"unicodePwd\": \"$password\"," +
- " \"accountExpires\": \"0\"," +
- " \"userAccountControl\": \"66048\"" +
- "}");
- }
- };
+ Map<String, String> kerberosEnvMap = new HashMap<>(getKerberosEnv());
+ kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
+ "#set( $user = \"${principal_primary}-${principal_digest}\" )" +
+ "{" +
+ " \"objectClass\": [" +
+ " \"top\"," +
+ " \"person\"," +
+ " \"organizationalPerson\"," +
+ " \"user\"" +
+ " ]," +
+ " \"cn\": \"$user\"," +
+ " \"sAMAccountName\": \"$user.substring(0,20)\"," +
+ " #if( $is_service )" +
+ " \"servicePrincipalName\": \"$principal_name\"," +
+ " #end" +
+ " \"userPrincipalName\": \"$normalized_principal\"," +
+ " \"unicodePwd\": \"$password\"," +
+ " \"accountExpires\": \"0\"," +
+ " \"userAccountControl\": \"66048\"" +
+ "}");
Capture<Name> capturedName = newCapture();
Capture<Attributes> capturedAttributes = newCapture();
@@ -491,9 +467,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<>();
- kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
+ Map<String, String> kerberosEnvMap = new HashMap<>(getKerberosEnv());
kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
"{" +
"\"principal_digest\": \"$principal_digest\"," +
@@ -596,7 +570,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
System.out.println("Test Admin Credentials: " + handler.testAdministratorCredentials());
// does the principal already exist?
- System.out.println("Principal exists: " + handler.principalExists("nn/c1508.ambari.apache.org"));
+ System.out.println("Principal exists: " + handler.principalExists("nn/c1508.ambari.apache.org", true));
handler.close();
@@ -605,15 +579,15 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
String evaluatedPrincipal;
evaluatedPrincipal = "nn/c6501.ambari.apache.org@" + DEFAULT_REALM;
- if (handler.principalExists(evaluatedPrincipal)) {
- handler.setPrincipalPassword(evaluatedPrincipal, "some password");
+ if (handler.principalExists(evaluatedPrincipal, true)) {
+ handler.setPrincipalPassword(evaluatedPrincipal, "some password", true);
} else {
handler.createPrincipal(evaluatedPrincipal, "some password", true);
}
evaluatedPrincipal = "hdfs@" + DEFAULT_REALM;
- if (handler.principalExists(evaluatedPrincipal)) {
- handler.setPrincipalPassword(evaluatedPrincipal, "some password");
+ if (handler.principalExists(evaluatedPrincipal, false)) {
+ handler.setPrincipalPassword(evaluatedPrincipal, "some password", false);
} else {
handler.createPrincipal(evaluatedPrincipal, "some password", true);
}
@@ -644,14 +618,14 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
handler.open(credentials, realm, kerberosEnvMap);
// remove the principal
- handler.removePrincipal("abcdefg");
- handler.removePrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM);
+ handler.removePrincipal("abcdefg", false);
+ handler.removePrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, true);
handler.createPrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password", true);
handler.createPrincipal("abcdefg@" + DEFAULT_REALM, "some password", false);
//update the password
- handler.setPrincipalPassword("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password");
+ handler.setPrincipalPassword("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password", true);
handler.close();
}
@@ -687,11 +661,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- Map<String, String> kerberosConfiguration = new HashMap<>();
- kerberosConfiguration.put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- kerberosConfiguration.put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-
- handler.open(new PrincipalKeyCredential("principal", "key"), "EXAMPLE.COM", kerberosConfiguration);
+ handler.open(new PrincipalKeyCredential("principal", "key"), "EXAMPLE.COM", getKerberosEnv());
Properties properties = capturedProperties.getValue();
Assert.assertNotNull(properties);
@@ -705,13 +675,78 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
}
private Injector getInjector() {
- return Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
- bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- }
- });
+ return injector;
+ }
+
+ @Override
+ protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
+ return createMockedHandler(methodCreateInitialLdapContext);
+ }
+
+
+ private ADKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+ ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
+ .addMockedMethods(mockedMethods)
+ .createMock();
+ injector.injectMembers(handler);
+ return handler;
+ }
+
+
+ @Override
+ protected void setupOpenSuccess(KerberosOperationHandler handler) throws Exception {
+
+ ADKerberosOperationHandler adHandler = (ADKerberosOperationHandler) handler;
+
+ expect(adHandler.createInitialLdapContext(anyObject(Properties.class), isNull())).andReturn(ldapContext).anyTimes();
+ }
+
+ @Override
+ protected void setupOpenFailure(KerberosOperationHandler handler) throws Exception {
+ ADKerberosOperationHandler adHandler = (ADKerberosOperationHandler) handler;
+ expect(adHandler.createInitialLdapContext(anyObject(Properties.class), isNull())).andThrow(new AuthenticationException("Bogus error!")).anyTimes();
+ }
+
+ @Override
+ protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ setupPrincipalExists(handler, service);
+ }
+
+ @Override
+ protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+ NamingEnumeration<SearchResult> results = createMock(NamingEnumeration.class);
+ results.close();
+ expectLastCall().once();
+ expect(results.hasMore()).andReturn(false).anyTimes();
+
+ expect(ldapContext.search(anyObject(Name.class), anyString(), anyObject(SearchControls.class)))
+ .andReturn(results)
+ .anyTimes();
+ ldapContext.close();
+ expectLastCall().once();
+ }
+
+ @Override
+ protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ SearchResult result = createMock(SearchResult.class);
+ expect(result.getNameInNamespace()).andReturn("user/service dn").anyTimes();
+
+ NamingEnumeration<SearchResult> results = createMock(NamingEnumeration.class);
+ results.close();
+ expectLastCall().anyTimes();
+ expect(results.hasMore()).andReturn(true).once();
+ expect(results.next()).andReturn(result).once();
+ expect(results.hasMore()).andReturn(false).anyTimes();
+
+ expect(ldapContext.search(anyObject(Name.class), anyString(), anyObject(SearchControls.class)))
+ .andReturn(results)
+ .anyTimes();
+ ldapContext.close();
+ expectLastCall().once();
+ }
+
+ @Override
+ protected Map<String, String> getKerberosEnv() {
+ return KERBEROS_ENV_MAP;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
index f2a09ba..558ca79 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
@@ -18,36 +18,26 @@
package org.apache.ambari.server.serveraction.kerberos;
+import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
+import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
-import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.configuration.Configuration;
-import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.utils.ShellCommandUtil;
import org.easymock.EasyMock;
import org.junit.BeforeClass;
-import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
-import junit.framework.Assert;
-
-public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
- private static final String DEFAULT_ADMIN_PRINCIPAL = "admin";
- private static final String DEFAULT_ADMIN_PASSWORD = "Hadoop12345";
-
- private static final String DEFAULT_REALM = "IPA01.LOCAL";
-
- private static Injector injector;
-
- private static boolean hasIpa = false;
+public class IPAKerberosOperationHandlerTest extends KDCKerberosOperationHandlerTest {
private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
{
@@ -58,8 +48,10 @@ public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTes
}
};
+ private static Injector injector;
+
@BeforeClass
- public static void beforeClass() throws AmbariException {
+ public static void beforeIPAKerberosOperationHandlerTest() throws Exception {
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
@@ -72,85 +64,74 @@ public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTes
bind(OsFamily.class).toInstance(EasyMock.createNiceMock(OsFamily.class));
}
});
- if (System.getenv("HAS_IPA") != null) {
- hasIpa = true;
- }
}
- @Test
- public void testSetPrincipalPasswordExceptions() throws Exception {
- if (!hasIpa) {
- return;
- }
+ @Override
+ protected IPAKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+ IPAKerberosOperationHandler handler = createMockBuilder(IPAKerberosOperationHandler.class)
+ .addMockedMethods(mockedMethods)
+ .createMock();
+ injector.injectMembers(handler);
+ return handler;
+ }
- IPAKerberosOperationHandler handler = injector.getInstance(IPAKerberosOperationHandler.class);
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- try {
- handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, null);
- Assert.fail("KerberosOperationException not thrown for null password");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ @Override
+ protected Map<String, String> getKerberosEnv() {
+ return KERBEROS_ENV_MAP;
+ }
- try {
- handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, "");
- Assert.fail("KerberosOperationException not thrown for empty password");
- handler.createPrincipal("", "1234", false);
- Assert.fail("AmbariException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
+ @Override
+ protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(1).anyTimes();
+ expect(result.isSuccessful()).andReturn(false).anyTimes();
+ if(service) {
+ expect(result.getStderr()).andReturn("ipa: ERROR: service with name \"service/host@EXAMPLE.COM\" already exists").anyTimes();
}
-
- try {
- handler.setPrincipalPassword(null, DEFAULT_ADMIN_PASSWORD);
- Assert.fail("KerberosOperationException not thrown for null principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
+ else {
+ expect(result.getStderr()).andReturn("ipa: ERROR: user with name \"user\" already exists").anyTimes();
}
+ expect(result.getStdout()).andReturn("").anyTimes();
- try {
- handler.setPrincipalPassword("", DEFAULT_ADMIN_PASSWORD);
- Assert.fail("KerberosOperationException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-add" : "user-add"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
}
- @Test
- public void testCreateServicePrincipal_Exceptions() throws Exception {
- if (!hasIpa) {
- return;
- }
-
- IPAKerberosOperationHandler handler = new IPAKerberosOperationHandler();
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+ @Override
+ protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(2).anyTimes();
+ expect(result.isSuccessful()).andReturn(false).anyTimes();
+ expect(result.getStderr()).andReturn(String.format("ipa: ERROR: %s: user not found", (service) ? "service/host" : "user")).anyTimes();
+ expect(result.getStdout()).andReturn("").anyTimes();
- try {
- handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, null, false);
- Assert.fail("KerberosOperationException not thrown for null password");
- } catch (Throwable t) {
- Assert.fail("KerberosOperationException thrown on null password with IPA");
- }
- try {
- handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, "", false);
- } catch (Throwable t) {
- Assert.fail("KerberosOperationException thrown for empty password");
- }
-
- try {
- handler.createPrincipal(null, DEFAULT_ADMIN_PASSWORD, false);
- Assert.fail("KerberosOperationException not thrown for null principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
-
- try {
- handler.createPrincipal("", DEFAULT_ADMIN_PASSWORD, false);
- Assert.fail("KerberosOperationException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-show" : "user-show"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
}
+ @Override
+ protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(0).anyTimes();
+ expect(result.isSuccessful()).andReturn(true).anyTimes();
+ expect(result.getStderr()).andReturn("").anyTimes();
+ expect(result.getStdout()).andReturn(String.format(" User login: %s\n" +
+ " Last name: User\n" +
+ " Home directory: /home/user\n" +
+ " Login shell: /bin/bash\n" +
+ " Principal alias: user@EXAMPLE.COM\n" +
+ " UID: 324200000\n" +
+ " GID: 324200000\n" +
+ " Account disabled: False\n" +
+ " Password: True\n" +
+ " Member of groups: users\n" +
+ " Kerberos keys available: True", (service) ? "service/host" : "user")).anyTimes();
+
+ expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-show" : "user-show"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
new file mode 100644
index 0000000..271c787
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ambari.server.serveraction.kerberos;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.lang.StringUtils;
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
+
+ static Method methodExecuteCommand;
+
+ @BeforeClass
+ public static void beforeKDCKerberosOperationHandlerTest() throws Exception {
+ methodExecuteCommand = KDCKerberosOperationHandler.class.getDeclaredMethod("executeCommand", String[].class, Map.class, ShellCommandUtil.InteractiveHandler.class);
+ }
+
+ @Test
+ public void testInteractivePasswordHandler() {
+ KDCKerberosOperationHandler.InteractivePasswordHandler handler = new KDCKerberosOperationHandler.InteractivePasswordHandler("admin_password", "user_password");
+
+ handler.start();
+ Assert.assertEquals("admin_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertTrue(handler.done());
+
+ // Test restarting
+ handler.start();
+ Assert.assertEquals("admin_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertTrue(handler.done());
+ }
+
+ @Override
+ protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
+ return createMockedHandler(methodExecuteCommand);
+ }
+
+ @Override
+ protected void setupOpenSuccess(KerberosOperationHandler handler) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.isSuccessful()).andReturn(true);
+
+ expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
+ }
+
+ @Override
+ protected void setupOpenFailure(KerberosOperationHandler handler) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.isSuccessful()).andReturn(false).once();
+ expect(result.getExitCode()).andReturn(-1).once();
+ expect(result.getStdout()).andReturn("STDOUT data").once();
+ expect(result.getStderr()).andReturn("STDERR data").once();
+
+ expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
+ }
+
+ protected abstract KDCKerberosOperationHandler createMockedHandler(Method... mockedMethods);
+
+ public static class ArrayContains implements IArgumentMatcher {
+
+ private String[] startItems;
+
+ ArrayContains(String startItem) {
+ this.startItems = new String[]{startItem};
+ }
+
+ ArrayContains(String[] startItems) {
+ this.startItems = startItems;
+ }
+
+ @Override
+ public boolean matches(Object o) {
+ if (o instanceof String[]) {
+ String[] array = (String[]) o;
+
+ for (String item : startItems) {
+ boolean valueContains = false;
+ for (String value : array) {
+ if (value.contains(item)) {
+ valueContains = true;
+ break;
+ }
+ }
+
+ if (!valueContains) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void appendTo(StringBuffer stringBuffer) {
+ stringBuffer.append("arrayContains(");
+ stringBuffer.append(StringUtils.join(startItems, ", "));
+ stringBuffer.append("\")");
+ }
+ }
+
+ static String[] arrayContains(String in) {
+ EasyMock.reportMatcher(new ArrayContains(in));
+ return null;
+ }
+
+ static String[] arrayContains(String[] in) {
+ EasyMock.reportMatcher(new ArrayContains(in));
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
index 88c841c..9d1e8e0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
@@ -40,10 +40,128 @@ import junit.framework.Assert;
public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
+ static final String DEFAULT_ADMIN_PRINCIPAL = "admin";
+ static final String DEFAULT_ADMIN_PASSWORD = "hadoop";
+ static final String DEFAULT_REALM = "EXAMPLE.COM";
+ static final PrincipalKeyCredential DEFAULT_ADMIN_CREDENTIALS = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
+
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
+ public void testOpenSucceeded() throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+
+ verifyAll();
+
+ Assert.assertTrue(handler.isOpen());
+ }
+
+ @Test
+ public void testOpenFailed() throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenFailure(handler);
+
+ replayAll();
+
+ try {
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ Assert.fail("KerberosAdminAuthenticationException expected");
+ } catch (KerberosAdminAuthenticationException e) {
+ // This is expected
+ }
+
+ verifyAll();
+
+ Assert.assertFalse(handler.isOpen());
+ }
+
+ @Test(expected = KerberosPrincipalAlreadyExistsException.class)
+ public void testCreateUserPrincipalPrincipalAlreadyExists() throws Exception {
+ testCreatePrincipalPrincipalAlreadyExists(false);
+ }
+
+ @Test(expected = KerberosPrincipalAlreadyExistsException.class)
+ public void testCreateServicePrincipalPrincipalAlreadyExists() throws Exception {
+ testCreatePrincipalPrincipalAlreadyExists(true);
+ }
+
+ private void testCreatePrincipalPrincipalAlreadyExists(boolean service) throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+ setupPrincipalAlreadyExists(handler, service);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ handler.createPrincipal(createPrincipal(service), "password", service);
+ handler.close();
+
+ verifyAll();
+
+ }
+
+
+ @Test
+ public void testUserPrincipalExistsNotFound() throws Exception {
+ testPrincipalExistsNotFound(false);
+ }
+
+ @Test
+ public void testServicePrincipalExistsNotFound() throws Exception {
+ testPrincipalExistsNotFound(true);
+ }
+
+ private void testPrincipalExistsNotFound(boolean service) throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+ setupPrincipalDoesNotExist(handler, service);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ Assert.assertFalse(handler.principalExists(createPrincipal(service), service));
+ handler.close();
+
+ verifyAll();
+ }
+
+ @Test
+ public void testUserPrincipalExistsFound() throws Exception {
+ testPrincipalExistsFound(false);
+ }
+
+ @Test
+ public void testServicePrincipalExistsFound() throws Exception {
+ testPrincipalExistsFound(true);
+ }
+
+ private void testPrincipalExistsFound(boolean service) throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+ setupPrincipalExists(handler, service);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ Assert.assertTrue(handler.principalExists(createPrincipal(service), service));
+ handler.close();
+
+ verifyAll();
+
+ }
+
+ @Test
public void testCreateKeytabFileOneAtATime() throws Exception {
KerberosOperationHandler handler = createHandler();
File file = folder.newFile();
@@ -285,7 +403,7 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
public void testAdminCredentialsNullCredential() throws KerberosOperationException {
KerberosOperationHandler handler = createHandler();
- PrincipalKeyCredential credentials = new PrincipalKeyCredential("principal", (char[])null);
+ PrincipalKeyCredential credentials = new PrincipalKeyCredential("principal", (char[]) null);
handler.setAdministratorCredential(credentials);
}
@@ -301,10 +419,10 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
public void testSetExecutableSearchPaths() throws KerberosOperationException {
KerberosOperationHandler handler = createHandler();
- handler.setExecutableSearchPaths((String)null);
+ handler.setExecutableSearchPaths((String) null);
Assert.assertNull(handler.getExecutableSearchPaths());
- handler.setExecutableSearchPaths((String[])null);
+ handler.setExecutableSearchPaths((String[]) null);
Assert.assertNull(handler.getExecutableSearchPaths());
handler.setExecutableSearchPaths("");
@@ -341,6 +459,24 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
Assert.assertEquals("path3/", handler.getExecutableSearchPaths()[2]);
}
+ protected abstract KerberosOperationHandler createMockedHandler() throws KerberosOperationException;
+
+ protected abstract void setupOpenSuccess(KerberosOperationHandler handler) throws Exception;
+
+ protected abstract void setupOpenFailure(KerberosOperationHandler handler) throws Exception;
+
+ protected abstract void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception;
+
+ protected abstract void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception;
+
+ protected abstract void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception;
+
+ protected abstract Map<String, String> getKerberosEnv();
+
+ protected PrincipalKeyCredential getAdminCredentials() {
+ return DEFAULT_ADMIN_CREDENTIALS;
+ }
+
private KerberosOperationHandler createHandler() throws KerberosOperationException {
KerberosOperationHandler handler = new KerberosOperationHandler() {
@@ -357,7 +493,7 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
}
@Override
- public boolean principalExists(String principal) throws KerberosOperationException {
+ public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
return false;
}
@@ -367,12 +503,12 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
}
@Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+ public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
return 0;
}
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
return false;
}
};
@@ -380,4 +516,8 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
handler.open(new PrincipalKeyCredential("admin/admin", "hadoop"), "EXAMPLE.COM", null);
return handler;
}
+
+ private String createPrincipal(boolean service) {
+ return String.format("%s@%s", (service) ? "service/host" : "user", DEFAULT_REALM);
+ }
}
[03/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC
integration (rlevas)
Posted by nc...@apache.org.
AMBARI-22293. Improve KDC integration (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f844e5f3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f844e5f3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f844e5f3
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: f844e5f3f952b57d790a238f0bafaf7d5ba1ddca
Parents: a7f0f45
Author: Robert Levas <rl...@hortonworks.com>
Authored: Thu Nov 2 12:37:36 2017 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Thu Nov 2 12:37:36 2017 -0400
----------------------------------------------------------------------
.../docs/security/kerberos/kerberos_service.md | 22 +-
.../kerberos/ADKerberosOperationHandler.java | 22 +-
.../kerberos/CreatePrincipalsServerAction.java | 4 +-
.../kerberos/DestroyPrincipalsServerAction.java | 3 +-
.../kerberos/IPAKerberosOperationHandler.java | 1067 +++---------------
.../kerberos/KDCKerberosOperationHandler.java | 391 +++++++
.../kerberos/KerberosOperationHandler.java | 64 +-
.../kerberos/MITKerberosOperationHandler.java | 406 ++-----
.../server/upgrade/UpgradeCatalog300.java | 30 +-
.../1.10.3-10/configuration/kerberos-env.xml | 36 +-
.../1.10.3-30/configuration/kerberos-env.xml | 36 +-
.../KERBEROS/configuration/kerberos-env.xml | 36 +-
.../server/controller/KerberosHelperTest.java | 6 +-
.../ADKerberosOperationHandlerTest.java | 261 +++--
.../IPAKerberosOperationHandlerTest.java | 147 ++-
.../KDCKerberosOperationHandlerTest.java | 152 +++
.../kerberos/KerberosOperationHandlerTest.java | 152 ++-
.../kerberos/KerberosServerActionTest.java | 133 ++-
.../MITKerberosOperationHandlerTest.java | 633 +++--------
.../server/upgrade/UpgradeCatalog300Test.java | 152 ++-
.../2.5/configs/ranger-admin-secured.json | 2 -
.../stacks/2.5/configs/ranger-kms-secured.json | 2 -
.../2.6/configs/ranger-admin-secured.json | 2 -
.../PreconfigureActionTest_cluster_config.json | 4 +-
.../main/admin/kerberos/step2_controller.js | 2 +-
25 files changed, 1623 insertions(+), 2142 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/docs/security/kerberos/kerberos_service.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/security/kerberos/kerberos_service.md b/ambari-server/docs/security/kerberos/kerberos_service.md
index 65e312b..c9cbd49 100644
--- a/ambari-server/docs/security/kerberos/kerberos_service.md
+++ b/ambari-server/docs/security/kerberos/kerberos_service.md
@@ -231,32 +231,12 @@ _Example:_ `-requires_preauth max_renew_life=7d`
This property is optional and only used if the `kdc_type` is `mit-kdc`
-##### group
+##### ipa_user_group
The group in IPA user principals should be member of
This property is mandatory and only used if the `kdc_type` is `ipa`
-##### set_password_expiry
-
-Indicates whether Ambari should set the password expiry for the principals it creates. By default
-IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
-attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
-policy is in place for the IPA Group principals are added to.
-
-_Possible values:_ `true`, `false`
-
-_Default value:_ `false`
-
-This property is mandatory and only used if the `kdc_type` is `ipa`
-
-##### password_chat_timeout
-
-Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
-because it can take some time due to lookups before a response is there.
-
-This property is mandatory and only used if the `kdc_type` is `ipa`
-
<a name="krb5-conf"></a>
#### krb5-conf
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
index f7d6060..d7b91b0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
@@ -175,9 +175,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
throw new KerberosLDAPContainerException("principalContainerDn is not a valid LDAP name", e);
}
- setAdministratorCredential(administratorCredential);
- setDefaultRealm(realm);
- setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
+ super.open(administratorCredential, realm, kerberosConfiguration);
this.ldapContext = createLdapContext();
this.searchControls = createSearchControls();
@@ -215,11 +213,12 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
* The implementation is specific to a particular type of KDC.
*
* @param principal a String containing the principal to test
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal exists; false otherwise
* @throws KerberosOperationException
*/
@Override
- public boolean principalExists(String principal) throws KerberosOperationException {
+ public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
@@ -260,7 +259,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
if (password == null) {
throw new KerberosOperationException("principal password is null");
}
- if (principalExists(principal)) {
+ if (principalExists(principal, service)) {
throw new KerberosPrincipalAlreadyExistsException(principal);
}
@@ -347,12 +346,13 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
*
* @param principal a String containing the principal to update
* @param password a String containing the password to set
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return an Integer declaring the new key number
* @throws KerberosPrincipalDoesNotExistException if the principal does not exist
* @throws KerberosOperationException
*/
@Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+ public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
@@ -362,7 +362,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
if (password == null) {
throw new KerberosOperationException("principal password is null");
}
- if(!principalExists(principal)) {
+ if (!principalExists(principal, service)) {
throw new KerberosPrincipalDoesNotExistException(principal);
}
@@ -396,11 +396,12 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
* The implementation is specific to a particular type of KDC.
*
* @param principal a String containing the principal to remove
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal was successfully removed; otherwise false
* @throws KerberosOperationException
*/
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
@@ -469,10 +470,9 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
String message = String.format("Failed to communicate with the Active Directory at %s: %s", ldapUrl, e.getMessage());
LOG.warn(message, e);
- if(rootCause instanceof SSLHandshakeException) {
+ if (rootCause instanceof SSLHandshakeException) {
throw new KerberosKDCSSLConnectionException(message, e);
- }
- else {
+ } else {
throw new KerberosKDCConnectionException(message, e);
}
} catch (AuthenticationException e) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
index 08e03bd..59d5327 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
@@ -253,7 +253,7 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
if (regenerateKeytabs) {
try {
- keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password);
+ keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password, isServicePrincipal);
created = false;
} catch (KerberosPrincipalDoesNotExistException e) {
message = String.format("Principal, %s, does not exist, creating new principal", principal);
@@ -276,7 +276,7 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
actionLog.writeStdOut(message);
}
- keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password);
+ keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password, isServicePrincipal);
created = false;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
index 2b3a0ca..4c80bd4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
@@ -114,7 +114,8 @@ public class DestroyPrincipalsServerAction extends KerberosServerAction {
try {
try {
- operationHandler.removePrincipal(evaluatedPrincipal);
+ boolean servicePrincipal = "service".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL_TYPE));
+ operationHandler.removePrincipal(evaluatedPrincipal, servicePrincipal);
} catch (KerberosOperationException e) {
message = String.format("Failed to remove identity for %s from the KDC - %s", evaluatedPrincipal, e.getMessage());
LOG.warn(message);
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
index 9a6a07e..c411237 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
@@ -18,32 +18,14 @@
package org.apache.ambari.server.serveraction.kerberos;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TimeZone;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Set;
import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
-import org.apache.ambari.server.utils.Closeables;
import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.directory.server.kerberos.shared.keytab.Keytab;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,12 +36,9 @@ import org.slf4j.LoggerFactory;
* It is assumed that the IPA admin tools are installed and that the ipa shell command is
* available
*/
-public class IPAKerberosOperationHandler extends KerberosOperationHandler {
+public class IPAKerberosOperationHandler extends KDCKerberosOperationHandler {
private final static Logger LOG = LoggerFactory.getLogger(IPAKerberosOperationHandler.class);
- private String adminServerHost = null;
-
- private HashMap<String, Keytab> cachedKeytabs = null;
/**
* This is where user principals are members of. Important as the password should not expire
* and thus a separate password policy should apply to this group
@@ -67,27 +46,6 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
private String userPrincipalGroup = null;
/**
- * The format used for krbPasswordExpiry
- */
- private final SimpleDateFormat expiryFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
-
- /**
- * Time zone for krbPasswordExpiry
- */
- private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
-
- /**
- * Years to add for password expiry
- */
- private static final int PASSWORD_EXPIRY_YEAR = 30;
-
- /**
- * A regular expression pattern to use to parse the key number from the text captured from the
- * kvno command
- */
- private final static Pattern PATTERN_GET_KEY_NUMBER = Pattern.compile("^.*?: kvno = (\\d+).*$", Pattern.DOTALL);
-
- /**
* A String containing the resolved path to the ipa executable
*/
private String executableIpaGetKeytab = null;
@@ -98,31 +56,6 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
private String executableIpa = null;
/**
- * A String containing the resolved path to the kinit executable
- */
- private String executableKinit = null;
-
- /**
- * A String containing the resolved path to the ipa-getkeytab executable
- */
- private String executableKvno = null;
-
- /**
- * A boolean indicating if password expiry should be set
- */
- private boolean usePasswordExpiry = false;
-
- /**
- * An int indicating the time out in seconds for the password chat;
- */
- private int timeout = DEFAULT_PASSWORD_CHAT_TIMEOUT;
-
- /**
- * Credentials context stores a handler to the ccache so it can be reused and removed on request
- */
- private CredentialsContext credentialsContext;
-
- /**
* Prepares and creates resources to be used by this KerberosOperationHandler
* <p/>
* It is expected that this KerberosOperationHandler will not be used before this call.
@@ -139,84 +72,27 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public void open(PrincipalKeyCredential administratorCredentials, String realm,
- Map<String, String> kerberosConfiguration)
- throws KerberosOperationException {
-
- setAdministratorCredential(administratorCredentials);
- setDefaultRealm(realm);
+ public void open(PrincipalKeyCredential administratorCredentials, String realm, Map<String, String> kerberosConfiguration)
+ throws KerberosOperationException {
if (kerberosConfiguration != null) {
- // todo: ignore if ipa managed krb5.conf?
- setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
- setExecutableSearchPaths(kerberosConfiguration.get(KERBEROS_ENV_EXECUTABLE_SEARCH_PATHS));
- setUserPrincipalGroup(kerberosConfiguration.get(KERBEROS_ENV_USER_PRINCIPAL_GROUP));
- setAdminServerHost(kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST));
- setUsePasswordExpiry(kerberosConfiguration.get(KERBEROS_ENV_SET_PASSWORD_EXPIRY));
- setTimeout(kerberosConfiguration.get(KERBEROS_ENV_PASSWORD_CHAT_TIMEOUT));
- } else {
- setKeyEncryptionTypes(null);
- setAdminServerHost(null);
- setExecutableSearchPaths((String) null);
- setUserPrincipalGroup(null);
- setUsePasswordExpiry(null);
- setTimeout(null);
+ userPrincipalGroup = kerberosConfiguration.get(KERBEROS_ENV_USER_PRINCIPAL_GROUP);
}
// Pre-determine the paths to relevant Kerberos executables
executableIpa = getExecutable("ipa");
- executableKvno = getExecutable("kvno");
- executableKinit = getExecutable("kinit");
executableIpaGetKeytab = getExecutable("ipa-getkeytab");
- credentialsContext = new CredentialsContext(administratorCredentials);
- cachedKeytabs = new HashMap<>();
- expiryFormat.setTimeZone(UTC);
-
- setOpen(true);
- }
-
- private void setUsePasswordExpiry(String usePasswordExpiry) {
- if (usePasswordExpiry == null) {
- this.usePasswordExpiry = false;
- return;
- }
-
- if (usePasswordExpiry.equalsIgnoreCase("true")) {
- this.usePasswordExpiry = true;
- } else {
- this.usePasswordExpiry = false;
- }
- }
-
- private void setTimeout(String timeout) {
- if (timeout == null || timeout.isEmpty()) {
- this.timeout = DEFAULT_PASSWORD_CHAT_TIMEOUT;
- return;
- }
-
- try {
- this.timeout = Integer.parseInt(timeout);
- } catch (NumberFormatException e) {
- this.timeout = DEFAULT_PASSWORD_CHAT_TIMEOUT;
- }
+ super.open(administratorCredentials, realm, kerberosConfiguration);
}
@Override
public void close() throws KerberosOperationException {
- if (isOpen()) {
- credentialsContext.delete();
- }
-
- // There is nothing to do here.
- setOpen(false);
-
+ userPrincipalGroup = null;
executableIpa = null;
- executableKvno = null;
executableIpaGetKeytab = null;
- executableKinit = null;
- credentialsContext = null;
- cachedKeytabs = null;
+
+ super.close();
}
/**
@@ -226,190 +102,121 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
* the result from STDOUT to determine if the presence of the specified principal.
*
* @param principal a String containing the principal to test
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal exists; false otherwise
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public boolean principalExists(String principal)
- throws KerberosOperationException {
-
- LOG.debug("Entering principal exists");
+ public boolean principalExists(String principal, boolean service)
+ throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
- if (principal == null) {
- return false;
- } else if (isServicePrincipal(principal)) {
- return true;
- } else {
- // TODO: fix exception check to only check for relevant exceptions
- try {
- DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
- LOG.debug("Running IPA command user-show");
+ if (!StringUtils.isEmpty(principal)) {
+ DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
+ String principalName = deconstructedPrincipal.getPrincipalName();
- // Create the ipa query to execute:
- ShellCommandUtil.Result result = invokeIpa(String.format("user-show %s", deconstructedPrincipal.getPrincipalName()));
- if (result.isSuccessful()) {
- return true;
- }
- } catch (KerberosOperationException e) {
- LOG.error("Cannot invoke IPA: " + e);
- throw e;
+ String[] ipaCommand = new String[]{
+ (service) ? "service-show" : "user-show",
+ principalName
+ };
+
+ ShellCommandUtil.Result result = invokeIpa(ipaCommand);
+ if (result.isSuccessful()) {
+ return true;
}
}
return false;
}
-
/**
- * Creates a new principal in a previously configured IPA Realm
- * <p/>
- * This implementation creates a query to send to the kadmin shell command and then interrogates
- * the result from STDOUT to determine if the operation executed successfully.
+ * Creates a new principal in a previously configured KDC.
+ * <p>
+ * This implementation uses the ipa shell to create either a user or service account. No password
+ * will be set for either account type. The password (or key) will be automatically generated by
+ * the IPA server when exporting the keytab entry. Upon success, this method will always return
+ * <code>0</code> as the key number since the value is not generated until the keytab entry is
+ * exported.
*
- * @param principal a String containing the principal add
- * @param password a String containing the password to use when creating the principal
+ * @param principal a String containing the principal to add
+ * @param password a String containing the password to use when creating the principal (ignored)
* @param service a boolean value indicating whether the principal is to be created as a service principal or not
- * @return an Integer declaring the generated key number
- * @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
+ * @return an Integer declaring the generated key number (always 0)
+ * @throws KerberosOperationException
*/
@Override
public Integer createPrincipal(String principal, String password, boolean service)
- throws KerberosOperationException {
+ throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
- if ((principal == null) || principal.isEmpty()) {
+ if (StringUtils.isEmpty(principal)) {
throw new KerberosOperationException("Failed to create new principal - no principal specified");
- } else if (((password == null) || password.isEmpty()) && service) {
- throw new KerberosOperationException("Failed to create new user principal - no password specified");
- } else {
- DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
-
- if (service) {
- // Create the ipa query: service-add --ok-as-delegate <principal>
- ShellCommandUtil.Result result = invokeIpa(String.format("service-add %s", principal));
- if (result.isSuccessful()) {
- // IPA does not generate encryption types when no keytab has been generated
- // So getKeyNumber(principal) cannot be used.
- // createKeytabCredentials(principal, password);
- // return getKeyNumber(principal);
- return 0;
- } else {
- LOG.error("Failed to execute ipa query: service-add --ok-as-delegate=TRUE {}\nSTDOUT: {}\nSTDERR: {}",
- principal, result.getStdout(), result.getStderr());
- throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
- principal, result.getStdout(), result.getStderr()));
- }
- } else {
- if (!StringUtils.isAllLowerCase(deconstructedPrincipal.getPrincipalName())) {
- LOG.warn(deconstructedPrincipal.getPrincipalName() + " is not in lowercase. FreeIPA does not recognize user " +
- "principals that are not entirely in lowercase. This can lead to issues with kinit and keytabs. Make " +
- "sure users are in lowercase ");
- }
- // Create the ipa query: user-add <username> --principal=<principal_name> --first <primary> --last <primary>
- // set-attr userPassword="<password>"
- // first and last are required for IPA so we make it equal to the primary
- // the --principal arguments makes sure that Kerberos keys are available for use in getKeyNumber
- ShellCommandUtil.Result result = invokeIpa(String.format("user-add %s --principal=%s --first %s --last %s --setattr userPassword=%s",
- deconstructedPrincipal.getPrimary(), deconstructedPrincipal.getPrincipalName(),
- deconstructedPrincipal.getPrimary(), deconstructedPrincipal.getPrimary(), password));
-
- if (!result.isSuccessful()) {
- throw new KerberosOperationException(String.format("Failed to create user principal for %s\nSTDOUT: %s\nSTDERR: %s",
- principal, result.getStdout(), result.getStderr()));
- }
-
- if (getUserPrincipalGroup() != null && !getUserPrincipalGroup().isEmpty()) {
- result = invokeIpa(String.format("group-add-member %s --users=%s",
- getUserPrincipalGroup(), deconstructedPrincipal.getPrimary()));
- if (!result.isSuccessful()) {
- throw new KerberosOperationException(String.format("Failed to create user principal for %s\nSTDOUT: %s\nSTDERR: %s",
- principal, result.getStdout(), result.getStderr()));
- }
- }
-
- if (!usePasswordExpiry) {
- updatePassword(deconstructedPrincipal.getPrimary(), password);
- return getKeyNumber(principal);
- }
-
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.YEAR, PASSWORD_EXPIRY_YEAR);
+ }
- result = invokeIpa(String.format("user-mod %s --setattr krbPasswordExpiration=%s",
- deconstructedPrincipal.getPrimary(), expiryFormat.format(calendar.getTime())));
+ DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
+ String normalizedPrincipal = deconstructedPrincipal.getNormalizedPrincipal();
- if (result.isSuccessful()) {
- return getKeyNumber(principal);
- }
+ String[] ipaCommand;
+ if (service) {
+ ipaCommand = new String[]{
+ "service-add",
+ normalizedPrincipal
+ };
+ } else {
+ String principalName = deconstructedPrincipal.getPrincipalName();
- throw new KerberosOperationException(String.format("Unknown error while creating principal for %s\n" +
- "STDOUT: %s\n" +
- "STDERR: %s\n",
- principal, result.getStdout(), result.getStderr()));
+ if (!principalName.equals(principal.toLowerCase())) {
+ LOG.warn("{} is not in lowercase. FreeIPA does not recognize user " +
+ "principals that are not entirely in lowercase. This can lead to issues with kinit and keytabs. Make " +
+ "sure users are in lowercase.", principalName);
}
- }
- }
- /**
- * Updates the password for an existing user principal in a previously configured IPA KDC
- * <p/>
- * This implementation creates a query to send to the ipa shell command and then interrogates
- * the exit code to determine if the operation executed successfully.
- *
- * @param principal a String containing the principal to update
- * @param password a String containing the password to set
- * @return an Integer declaring the new key number
- * @throws KerberosOperationException if an unexpected error occurred
- */
- @Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
- if (!isOpen()) {
- throw new KerberosOperationException("This operation handler has not been opened");
+ ipaCommand = new String[]{
+ "user-add",
+ deconstructedPrincipal.getPrimary(),
+ "--principal",
+ principalName,
+ "--first",
+ deconstructedPrincipal.getPrimary(),
+ "--last",
+ deconstructedPrincipal.getPrimary()
+ };
}
- if ((principal == null) || principal.isEmpty()) {
- throw new KerberosOperationException("Failed to set password - no principal specified");
- } else if ((password == null) || password.isEmpty()) {
- throw new KerberosOperationException("Failed to set password - no password specified");
- } else if (!isServicePrincipal(principal)) {
- DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
-
- if (usePasswordExpiry) {
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.YEAR, PASSWORD_EXPIRY_YEAR);
+ ShellCommandUtil.Result result = invokeIpa(ipaCommand);
+ if (!result.isSuccessful()) {
+ String message = String.format("Failed to create principal for %s\n%s\nSTDOUT: %s\nSTDERR: %s",
+ normalizedPrincipal, StringUtils.join(ipaCommand, " "), result.getStdout(), result.getStderr());
+ LOG.error(message);
- // Create the ipa query: user-mod <user> --setattr userPassword=<password>
- invokeIpa(String.format("user-mod %s --setattr userPassword=%s", deconstructedPrincipal.getPrimary(), password));
+ String stdErr = result.getStderr();
- List<String> command = new ArrayList<>();
- command.add(executableIpa);
- command.add("user-mod");
- command.add(deconstructedPrincipal.getPrimary());
- command.add("--setattr");
- command.add(String.format("krbPasswordExpiration=%s", expiryFormat.format(calendar.getTime())));
- ShellCommandUtil.Result result = executeCommand(command.toArray(new String[command.size()]));
- if (!result.isSuccessful()) {
- throw new KerberosOperationException("Failed to set password expiry");
- }
+ if ((stdErr != null) &&
+ ((service && stdErr.contains(String.format("service with name \"%s\" already exists", normalizedPrincipal))) ||
+ (!service && stdErr.contains(String.format("user with name \"%s\" already exists", deconstructedPrincipal.getPrimary()))))) {
+ throw new KerberosPrincipalAlreadyExistsException(principal);
} else {
- updatePassword(deconstructedPrincipal.getPrimary(), password);
+ throw new KerberosOperationException(String.format("Failed to create principal for %s\nSTDOUT: %s\nSTDERR: %s",
+ normalizedPrincipal, result.getStdout(), result.getStderr()));
}
- } else {
- ShellCommandUtil.Result result = invokeIpa(String.format("service-show %s", principal));
- // ignore the keytab but set the password for this principal
- if (result.isSuccessful() && result.getStdout().contains("Keytab: False")) {
- LOG.debug("Found service principal {} without password/keytab. Setting one", principal);
- createKeytab(principal, password, 0);
+ }
+
+ if ((!service) && !StringUtils.isEmpty(userPrincipalGroup)) {
+ result = invokeIpa(new String[]{"group-add-member", userPrincipalGroup, "--users", deconstructedPrincipal.getPrimary()});
+ if (!result.isSuccessful()) {
+ LOG.warn("Failed to add account for {} to group {}: \nSTDOUT: {}\nSTDERR: {}",
+ normalizedPrincipal, userPrincipalGroup, result.getStdout(), result.getStderr());
}
}
- return getKeyNumber(principal);
+
+ // Always return 0 since we do not have a key to get a key number for.
+ return 0;
}
/**
@@ -418,6 +225,7 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
* The implementation is specific to a particular type of KDC.
*
* @param principal a String containing the principal to remove
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal was successfully removed; otherwise false
* @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
* @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -425,696 +233,95 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
- if ((principal == null) || principal.isEmpty()) {
- throw new KerberosOperationException("Failed to remove new principal - no principal specified");
- } else {
- ShellCommandUtil.Result result = null;
- if (isServicePrincipal(principal)) {
- result = invokeIpa(String.format("service-del %s", principal));
- } else {
- DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
- result = invokeIpa(String.format("user-del %s", deconstructedPrincipal.getPrincipalName()));
- }
- return result.isSuccessful();
+ if (StringUtils.isEmpty(principal)) {
+ throw new KerberosOperationException("Failed to remove principal - no principal specified");
}
- }
- /**
- * Sets the name of the group where user principals should be members of
- *
- * @param userPrincipalGroup the name of the group
- */
- public void setUserPrincipalGroup(String userPrincipalGroup) {
- this.userPrincipalGroup = userPrincipalGroup;
- }
+ DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
- /**
- * Gets the name of the group where user principals should be members of
- *
- * @return name of the group where user principals should be members of
- */
- public String getUserPrincipalGroup() {
- return this.userPrincipalGroup;
- }
+ String[] ipaCommand = (service)
+ ? new String[]{"service-del", deconstructedPrincipal.getNormalizedPrincipal()}
+ : new String[]{"user-del", deconstructedPrincipal.getPrincipalName()};
- /**
- * Sets the KDC administrator server host address
- *
- * @param adminServerHost the ip address or FQDN of the IPA administrator server
- */
- public void setAdminServerHost(String adminServerHost) {
- this.adminServerHost = adminServerHost;
+ return invokeIpa(ipaCommand).isSuccessful();
}
- /**
- * Gets the IP address or FQDN of the IPA administrator server
- *
- * @return the IP address or FQDN of the IPA administrator server
- */
- public String getAdminServerHost() {
- return this.adminServerHost;
+ @Override
+ protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache) {
+ return new String[]{
+ executableKinit,
+ "-c",
+ credentialsCache,
+ credentials.getPrincipal()
+ };
}
- /**
- * Reads data from a stream without blocking and when available. Allows some time for the
- * stream to become ready.
- *
- * @param stdin the stdin BufferedReader to read from
- * @param stderr the stderr BufferedReader in case something goes wrong
- * @return a String with available data
- * @throws KerberosOperationException if a timeout happens
- * @throws IOException when somethings goes wrong with the underlying stream
- * @throws InterruptedException if the thread is interrupted
- */
- private String readData(BufferedReader stdin, BufferedReader stderr) throws KerberosOperationException, IOException, InterruptedException {
- char[] data = new char[1024];
- StringBuilder sb = new StringBuilder();
-
- int count = 0;
- while (!stdin.ready()) {
- Thread.sleep(1000L);
- if (count >= timeout) {
- char[] err_data = new char[1024];
- StringBuilder err = new StringBuilder();
- while (stderr.ready()) {
- stderr.read(err_data);
- err.append(err_data);
+ @Override
+ protected void exportKeytabFile(String principal, String keytabFileDestinationPath, Set<EncryptionType> keyEncryptionTypes) throws KerberosOperationException {
+ String encryptionTypeSpec = null;
+ if (!CollectionUtils.isEmpty(keyEncryptionTypes)) {
+ StringBuilder encryptionTypeSpecBuilder = new StringBuilder();
+ for (EncryptionType encryptionType : keyEncryptionTypes) {
+ if (encryptionTypeSpecBuilder.length() > 0) {
+ encryptionTypeSpecBuilder.append(',');
}
- throw new KerberosOperationException("No answer data available from stdin stream. STDERR: " + err);
+ encryptionTypeSpecBuilder.append(encryptionType.getName());
}
- count++;
- }
- while (stdin.ready()) {
- stdin.read(data);
- sb.append(data);
+ encryptionTypeSpec = encryptionTypeSpecBuilder.toString();
}
- return sb.toString();
- }
-
- /**
- * Updates a password for a (user) principal. This is done by first setting a random password and
- * then invoking kInit to directly set the password. This is done to circumvent issues with expired
- * password in IPA, as IPA needs passwords set by the admin to be set again by the user. Note that
- * this resets the current principal to the principal specified here. To invoke further administrative
- * commands a new kInit to admin is required.
- *
- * @param principal The principal user name that needs to be updated
- * @param password The new password
- * @throws KerberosOperationException if something is not as expected
- */
- private void updatePassword(String principal, String password) throws KerberosOperationException {
- BufferedReader reader = null;
- BufferedReader stderr = null;
- OutputStreamWriter out = null;
-
- LOG.debug("Updating password for: {}", principal);
-
- UUID uuid = UUID.randomUUID();
- String fileName = System.getProperty("java.io.tmpdir") +
- File.pathSeparator +
- "krb5cc_" + uuid;
-
- try {
- ShellCommandUtil.Result result = invokeIpa(String.format("user-mod %s --random", principal));
- if (!result.isSuccessful()) {
- throw new KerberosOperationException(result.getStderr());
- }
- Pattern pattern = Pattern.compile("password: (.*)");
- Matcher matcher = pattern.matcher(result.getStdout());
- if (!matcher.find()) {
- throw new KerberosOperationException("Unexpected response from ipa: " + result.getStdout());
- }
- String old_password = matcher.group(1);
-
- String credentialsCache = String.format("FILE:%s", fileName);
- Process process = Runtime.getRuntime().exec(new String[]{executableKinit, "-c", credentialsCache, principal});
- reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
- stderr = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
- out = new OutputStreamWriter(process.getOutputStream());
-
- String data = readData(reader, stderr);
- if (!data.startsWith("Password")) {
- process.destroy();
- throw new KerberosOperationException("Unexpected response from kinit while trying to password for "
- + principal + " got: " + data);
- }
- LOG.debug("Sending old password");
- out.write(old_password);
- out.write('\n');
- out.flush();
-
- data = readData(reader, stderr);
- if (!data.contains("Enter")) {
- process.destroy();
- throw new KerberosOperationException("Unexpected response from kinit while trying to password for "
- + principal + " got: " + data);
- }
- LOG.debug("Sending new password");
- out.write(password);
- out.write('\n');
- out.flush();
-
- data = readData(reader, stderr);
- if (!data.contains("again")) {
- process.destroy();
- throw new KerberosOperationException("Unexpected response from kinit while trying to password for "
- + principal + " got: " + data);
- }
- LOG.debug("Sending new password again");
- out.write(password);
- out.write('\n');
- out.flush();
+ String[] createKeytabFileCommand = (StringUtils.isEmpty(encryptionTypeSpec))
+ ? new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(), "-p", principal, "-k", keytabFileDestinationPath}
+ : new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(), "-e", encryptionTypeSpec, "-p", principal, "-k", keytabFileDestinationPath};
- process.waitFor();
- } catch (IOException e) {
- LOG.error("Cannot read stream: " + e);
- throw new KerberosOperationException(e.getMessage());
- } catch (InterruptedException e) {
- LOG.error("Process interrupted: " + e);
- throw new KerberosOperationException(e.getMessage());
- } finally {
- try {
- if (out != null)
- out.close();
- } catch (IOException e) {
- LOG.warn("Cannot close out stream: " + e);
- }
- try {
- if (reader != null)
- reader.close();
- } catch (IOException e) {
- LOG.warn("Cannot close stdin stream: " + e);
- }
- try {
- if (stderr != null)
- stderr.close();
- } catch (IOException e) {
- LOG.warn("Cannot close stderr stream: " + e);
- }
- File ccache = new File(fileName);
- ccache.delete();
+ ShellCommandUtil.Result result = executeCommand(createKeytabFileCommand);
+ if (!result.isSuccessful()) {
+ String message = String.format("Failed to export the keytab file for %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+ principal, result.getExitCode(), result.getStdout(), result.getStderr());
+ LOG.warn(message);
+ throw new KerberosOperationException(message);
}
-
}
/**
* Invokes the ipa shell command with administrative credentials to issue queries
*
- * @param query a String containing the query to send to the kdamin command
+ * @param query a String containing the query to send to the ipa command
* @return a ShellCommandUtil.Result containing the result of the operation
* @throws KerberosOperationException if an unexpected error occurred
*/
- protected ShellCommandUtil.Result invokeIpa(String query)
- throws KerberosOperationException {
- LOG.debug("Entering invokeipa");
+ private ShellCommandUtil.Result invokeIpa(String[] query) throws KerberosOperationException {
- ShellCommandUtil.Result result = null;
-
- if ((query == null) || query.isEmpty()) {
+ if ((query == null) || (query.length == 0)) {
throw new KerberosOperationException("Missing ipa query");
}
- PrincipalKeyCredential administratorCredentials = getAdministratorCredential();
- String defaultRealm = getDefaultRealm();
-
- List<String> command = new ArrayList<>();
- List<String> kinit = new ArrayList<>();
- String adminPrincipal = (administratorCredentials == null)
- ? null
- : administratorCredentials.getPrincipal();
-
- if ((adminPrincipal == null) || adminPrincipal.isEmpty()) {
- throw new KerberosOperationException("No admin principal for ipa available - " +
- "this KerberosOperationHandler may not have been opened.");
- }
-
- if ((executableIpa == null) || executableIpa.isEmpty()) {
- throw new KerberosOperationException("No path for ipa is available - " +
- "this KerberosOperationHandler may not have been opened.");
+ if (StringUtils.isEmpty(executableIpa)) {
+ throw new KerberosOperationException("No path for ipa is available - this KerberosOperationHandler may not have been opened.");
}
- // Set the ipa interface to be ipa
- command.add(executableIpa);
- command.add(query);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Executing: {}", createCleanCommand(command));
- }
+ String[] command = new String[query.length + 1];
+ command[0] = executableIpa;
+ System.arraycopy(query, 0, command, 1, query.length);
- List<String> fixedCommand = fixCommandList(command);
- result = executeCommand(fixedCommand.toArray(new String[fixedCommand.size()]));
-
-
- LOG.debug("Done invokeipa");
- return result;
- }
+ ShellCommandUtil.Result result = executeCommand(command);
- /**
- * Executes a shell command in a credentials context
- * <p/>
- * See {@link org.apache.ambari.server.utils.ShellCommandUtil#runCommand(String[])}
- *
- * @param command an array of String value representing the command and its arguments
- * @return a ShellCommandUtil.Result declaring the result of the operation
- * @throws KerberosOperationException
- */
- @Override
- protected ShellCommandUtil.Result executeCommand(String[] command)
- throws KerberosOperationException {
- return credentialsContext.executeCommand(command);
- }
-
- /**
- * Rebuilds the command line to make sure space are converted to arguments
- *
- * @param command a List of items making up the command
- * @return the fixed command
- */
- private List<String> fixCommandList(List<String> command) {
- List<String> fixedCommandList = new ArrayList<>();
- Iterator<String> iterator = command.iterator();
-
- if (iterator.hasNext()) {
- fixedCommandList.add(iterator.next());
- }
-
- while (iterator.hasNext()) {
- String part = iterator.next();
-
- // split arguments
- if (part.contains(" ")) {
- StringTokenizer st = new StringTokenizer(part, " ");
- while (st.hasMoreElements()) {
- fixedCommandList.add(st.nextToken());
- }
- } else {
- fixedCommandList.add(part);
- }
- }
-
- return fixedCommandList;
- }
-
- /**
- * Build the ipa command string, replacing administrator password with "********"
- *
- * @param command a List of items making up the command
- * @return the cleaned command string
- */
- private String createCleanCommand(List<String> command) {
- StringBuilder cleanedCommand = new StringBuilder();
- Iterator<String> iterator = command.iterator();
-
- if (iterator.hasNext()) {
- cleanedCommand.append(iterator.next());
- }
-
- while (iterator.hasNext()) {
- String part = iterator.next();
-
- cleanedCommand.append(' ');
- cleanedCommand.append(part);
-
- if ("--setattr".equals(part)) {
- // Skip the password and use "********" instead
- String arg= null;
- if (iterator.hasNext()) {
- arg = iterator.next();
- if (arg.contains("userPassword")) {
- cleanedCommand.append("userPassword=******");
- } else {
- cleanedCommand.append(arg);
- }
- }
- }
- }
-
- return cleanedCommand.toString();
- }
-
- /**
- * Determine is a principal is a service principal
- *
- * @param principal
- * @return true if the principal is a (existing) service principal
- * @throws KerberosOperationException
- */
- private boolean isServicePrincipal(String principal)
- throws KerberosOperationException {
-
- if ((principal == null) || principal.isEmpty()) {
- throw new KerberosOperationException("Failed to determine principal type- no principal specified");
- } else if (!principal.contains("/")) {
- return false;
- }
-
- try {
- ShellCommandUtil.Result result = invokeIpa(String.format("service-show %s", principal));
-
- // TODO: unfortunately we can be in limbo if the "Keytab: False" is present
- if (result.isSuccessful()) {
- return true;
+ if (result.isSuccessful()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Executed the following command:\n{}\nSTDOUT: {}\nSTDERR: {}",
+ StringUtils.join(command, " "), result.getStdout(), result.getStderr());
}
- } catch (KerberosOperationException e) {
- LOG.warn("Exception while invoking ipa service-show: " + e);
- return false;
- }
-
- return false;
- }
-
- /**
- * Retrieves the current key number assigned to the identity identified by the specified principal
- *
- * @param principal a String declaring the principal to look up
- * @return an Integer declaring the current key number
- * @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
- * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
- * @throws KerberosRealmException if the realm does not map to a KDC
- * @throws KerberosOperationException if an unexpected error occurred
- */
- private Integer getKeyNumber(String principal) throws KerberosOperationException {
- if (!isOpen()) {
- throw new KerberosOperationException("This operation handler has not been opened");
- }
-
- if ((principal == null) || principal.isEmpty()) {
- throw new KerberosOperationException("Failed to get key number for principal - no principal specified");
} else {
- // Create the kvno query: <principal>
- List<String> command = new ArrayList<>();
- command.add(executableKvno);
- command.add(principal);
-
- ShellCommandUtil.Result result = executeCommand(command.toArray(new String[command.size()]));
- String stdOut = result.getStdout();
- if (stdOut == null) {
- String message = String.format("Failed to get key number for %s:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
-
- Matcher matcher = PATTERN_GET_KEY_NUMBER.matcher(stdOut);
- if (matcher.matches()) {
- NumberFormat numberFormat = NumberFormat.getIntegerInstance();
- String keyNumber = matcher.group(1);
-
- numberFormat.setGroupingUsed(false);
- try {
- Number number = numberFormat.parse(keyNumber);
- return (number == null) ? 0 : number.intValue();
- } catch (ParseException e) {
- String message = String.format("Failed to get key number for %s - invalid key number value (%s):\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, keyNumber, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
- } else {
- String message = String.format("Failed to get key number for %s - unexpected STDOUT data:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
-
- }
- }
-
- /*
- * Creates a key tab by using the ipa commandline utilities.
- *
- * @param principal a String containing the principal to test
- * @param password a String containing the password to use when creating the principal
- * @return
- * @throws KerberosOperationException
- */
- /*private Keytab createKeytabCredentials(String principal, String password)
- throws KerberosOperationException {
-
- if ((principal == null) || principal.isEmpty()) {
- throw new KerberosOperationException("Failed to create keytab file, missing principal");
- }
-
- BufferedReader reader = null;
- BufferedReader stderr = null;
- OutputStreamWriter out = null;
-
- UUID uuid = UUID.randomUUID();
- String fileName = System.getProperty("java.io.tmpdir") +
- File.pathSeparator +
- "ambari." + uuid.toString();
-
- try {
- // TODO: add ciphers
- Process p = credentialsContext.exec(new String[]{executableIpaGetKeytab, "-s",
- getAdminServerHost(), "-p", principal, "-k", fileName, "-P"});
- reader = new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8));
- stderr = new BufferedReader(new InputStreamReader(p.getErrorStream(), StandardCharsets.UTF_8));
- out = new OutputStreamWriter(p.getOutputStream());
-
- String data = readData(reader, stderr);
- if (!data.startsWith("New")) {
- p.destroy();
- throw new KerberosOperationException("Unexpected response from ipa-getkeytab while trying to password for "
- + principal + " got: " + data);
- }
- LOG.debug("Sending password");
- out.write(password);
- out.write('\n');
- out.flush();
-
- data = readData(reader, stderr);
- if (!data.contains("Verify")) {
- p.destroy();
- throw new KerberosOperationException("Unexpected response from ipa-getkeytab while trying to password for "
- + principal + " got: " + data);
- }
- LOG.debug("Sending new password");
- out.write(password);
- out.write('\n');
- out.flush();
-
- p.waitFor();
- } catch (IOException e) {
- LOG.error("Cannot read stream: " + e);
- throw new KerberosOperationException(e.getMessage());
- } catch (InterruptedException e) {
- LOG.error("Process interrupted: " + e);
- throw new KerberosOperationException(e.getMessage());
- } finally {
- try {
- if (out != null)
- out.close();
- } catch (IOException e) {
- LOG.warn("Cannot close out stream: " + e);
- }
- try {
- if (reader != null)
- reader.close();
- } catch (IOException e) {
- LOG.warn("Cannot close stdin stream: " + e);
- }
- try {
- if (stderr != null)
- stderr.close();
- } catch (IOException e) {
- LOG.warn("Cannot close stderr stream: " + e);
- }
- }
-
- File keytabFile = new File(fileName);
- Keytab keytab = readKeytabFile(keytabFile);
- keytabFile.delete();
-
- return keytab;
- }*/
-
- /**
- * Creates a key tab by using the ipa commandline utilities. It ignores key number and password
- * as this will be handled by IPA
- *
- * @param principal a String containing the principal to test
- * @param password (IGNORED) a String containing the password to use when creating the principal
- * @param keyNumber (IGNORED) a Integer indicating the key number for the keytab entries
- * @return
- * @throws KerberosOperationException
- */
- @Override
- protected Keytab createKeytab(String principal, String password, Integer keyNumber)
- throws KerberosOperationException {
-
- if ((principal == null) || principal.isEmpty()) {
- throw new KerberosOperationException("Failed to create keytab file, missing principal");
- }
-
- // use cache if available
- if (cachedKeytabs.containsKey(principal)) {
- return cachedKeytabs.get(principal);
- }
-
- UUID uuid = UUID.randomUUID();
- String fileName = System.getProperty("java.io.tmpdir") +
- File.pathSeparator +
- "ambari." + uuid;
-
- // TODO: add ciphers
- List<String> command = new ArrayList<>();
- command.add(executableIpaGetKeytab);
- command.add("-s");
- command.add(getAdminServerHost());
- command.add("-p");
- command.add(principal);
- command.add("-k");
- command.add(fileName);
-
- // TODO: is it really required to set the password?
- ShellCommandUtil.Result result = executeCommand(command.toArray(new String[command.size()]));
- if (!result.isSuccessful()) {
- String message = String.format("Failed to get key number for %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
- principal, result.getExitCode(), result.getStdout(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
-
- File keytabFile = new File(fileName);
- Keytab keytab = readKeytabFile(keytabFile);
- keytabFile.delete();
-
- cachedKeytabs.put(principal, keytab);
- return keytab;
- }
-
-
- /**
- * Credentials context executes commands wrapped with kerberos credentials
- */
- class CredentialsContext {
- private PrincipalKeyCredential credentials;
- Map<String, String> env = new HashMap<>();
- private String fileName;
- private List<Process> processes = new ArrayList<>();
-
- public CredentialsContext(PrincipalKeyCredential credentials) throws KerberosOperationException {
- this.credentials = credentials;
-
- UUID uuid = UUID.randomUUID();
- fileName = System.getProperty("java.io.tmpdir") +
- File.pathSeparator +
- "krb5cc_" + uuid;
- env.put("KRB5CCNAME", String.format("FILE:%s", fileName));
-
- init(credentials, fileName);
- }
-
- protected ShellCommandUtil.Result executeCommand(String[] command)
- throws KerberosOperationException {
-
- if ((command == null) || (command.length == 0)) {
- return null;
- } else {
- try {
- return ShellCommandUtil.runCommand(command, env);
- } catch (IOException e) {
- String message = String.format("Failed to execute the command: %s", e.getLocalizedMessage());
- LOG.error(message, e);
- throw new KerberosOperationException(message, e);
- } catch (InterruptedException e) {
- String message = String.format("Failed to wait for the command to complete: %s", e.getLocalizedMessage());
- LOG.error(message, e);
- throw new KerberosOperationException(message, e);
- }
- }
- }
-
- /**
- * Does a kinit to obtain a ticket for the specified principal and stores it in the specified cache
- *
- * @param credentials Credentials to be used to obtain the ticket
- * @param fileName Filename where to store the credentials
- * @throws KerberosOperationException In case the ticket cannot be obtained
- */
- private void init(PrincipalKeyCredential credentials, String fileName) throws KerberosOperationException {
- Process process;
- BufferedReader reader = null;
- OutputStreamWriter osw = null;
-
- LOG.debug("Entering doKinit");
- try {
- String credentialsCache = String.format("FILE:%s", fileName);
-
- LOG.debug("start subprocess {} {}", executableKinit, credentials.getPrincipal());
- process = Runtime.getRuntime().exec(new String[]{executableKinit, "-c", credentialsCache, credentials.getPrincipal()});
- reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
- osw = new OutputStreamWriter(process.getOutputStream());
-
- char[] data = new char[1024];
- StringBuilder sb = new StringBuilder();
-
- int count = 0;
- while (!reader.ready()) {
- Thread.sleep(1000L);
- if (count >= 5) {
- process.destroy();
- throw new KerberosOperationException("No answer from kinit");
- }
- count++;
- }
-
- while (reader.ready()) {
- reader.read(data);
- sb.append(data);
- }
-
- String line = sb.toString();
- LOG.debug("Reading a line: {}", line);
- if (!line.startsWith("Password")) {
- throw new KerberosOperationException("Unexpected response from kinit while trying to get ticket for "
- + credentials.getPrincipal() + " got: " + line);
- }
- osw.write(credentials.getKey());
- osw.write('\n');
- osw.close();
-
- process.waitFor();
-
- LOG.debug("done subprocess");
- } catch (IOException | InterruptedException e) {
- String message = String.format("Failed to execute the command: %s", e.getLocalizedMessage());
- LOG.error(message, e);
- throw new KerberosOperationException(message, e);
- } finally {
- Closeables.closeSilently(osw);
- Closeables.closeSilently(reader);
- }
-
- if (process.exitValue() != 0) {
- throw new KerberosOperationException("kinit failed for " + credentials.getPrincipal() + ". Wrong password?");
- }
-
- }
-
- public Process exec(String[] args) throws IOException {
- Process process = Runtime.getRuntime().exec(args);
- processes.add(process);
-
- return process;
- }
-
- public void delete() {
- File ccache = new File(fileName);
- ccache.delete();
- for (Process p : processes) {
- p.destroy();
- }
+ LOG.error("Failed to execute the following command:\n{}\nSTDOUT: {}\nSTDERR: {}",
+ StringUtils.join(command, " "), result.getStdout(), result.getStderr());
}
+ return result;
}
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
new file mode 100644
index 0000000..e5696cd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
@@ -0,0 +1,391 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ambari.server.serveraction.kerberos;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
+import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.collections.MapUtils;
+import org.apache.directory.server.kerberos.shared.keytab.Keytab;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * KDCKerberosOperationHandler is an implementation of a KerberosOperationHandler providing
+ * functionality KDC-based Kerberos providers.
+ * <p>
+ * This implementation provides kinit functionality and keytab file caching utilities for classes.
+ */
+abstract class KDCKerberosOperationHandler extends KerberosOperationHandler {
+ private static Logger LOG = LoggerFactory.getLogger(KDCKerberosOperationHandler.class);
+
+ /**
+ * The FQDN of the host where KDC administration server is
+ */
+ private String adminServerHost = null;
+
+ /**
+ * A map of principal names to {@link Keytab} entries to ensure a Keyab file is not created/exported
+ * for the same principal more than once.
+ */
+ private HashMap<String, Keytab> cachedKeytabs = null;
+
+ /**
+ * A String containing the resolved path to the kinit executable
+ */
+ private String executableKinit = null;
+
+ /**
+ * The absolute path to the KDC administrator's Kerberos ticket cache.
+ * <p>
+ * This path is created as as temporary file with a randomized name when this {@link KerberosOperationHandler}
+ * is open. It is destoryed when this {@link KerberosOperationHandler} is closed.
+ */
+ private File credentialsCacheFile = null;
+
+ /**
+ * A Map of environmet values to send to system command invocations.
+ * <p>
+ * This map is to be appened to any map of environment values passed in when
+ * invoking {@link KerberosOperationHandler#executeCommand(String[], Map, ShellCommandUtil.InteractiveHandler)}
+ */
+ private Map<String, String> environmentMap = null;
+
+ @Override
+ public void open(PrincipalKeyCredential administratorCredentials, String realm, Map<String, String> kerberosConfiguration)
+ throws KerberosOperationException {
+
+ super.open(administratorCredentials, realm, kerberosConfiguration);
+
+ if (kerberosConfiguration != null) {
+ adminServerHost = kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST);
+ }
+
+ // Pre-determine the paths to relevant Kerberos executables
+ executableKinit = getExecutable("kinit");
+
+ setOpen(init());
+ }
+
+ @Override
+ public void close() throws KerberosOperationException {
+
+ if (credentialsCacheFile != null) {
+ if (credentialsCacheFile.delete()) {
+ LOG.debug("Failed to remove the cache file, {}", credentialsCacheFile.getAbsolutePath());
+ }
+ credentialsCacheFile = null;
+ }
+
+ environmentMap = null;
+ executableKinit = null;
+ cachedKeytabs = null;
+ adminServerHost = null;
+
+ super.close();
+ }
+
+ /**
+ * Updates the password for an existing user principal in a previously configured IPA KDC
+ * <p/>
+ * This implementation creates a query to send to the ipa shell command and then interrogates
+ * the exit code to determine if the operation executed successfully.
+ *
+ * @param principal a String containing the principal to update
+ * @param password a String containing the password to set
+ * @param service a boolean value indicating whether the principal is for a service or not
+ * @return an Integer declaring the new key number
+ * @throws KerberosOperationException if an unexpected error occurred
+ */
+ @Override
+ public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
+ if (!isOpen()) {
+ throw new KerberosOperationException("This operation handler has not been opened");
+ }
+
+ // It is expected that KerberosPrincipalDoesNotExistException is thrown if the principal does not exist.
+ // The caller expects so that it can attempt to set the password for a principal without checking
+ // to see if it exists first. If the principal does not exist and is required, the caller will
+ // create it. This saves a potentially unnecessary round trip to the KDC and back.
+ if(!principalExists(principal, service)) {
+ throw new KerberosPrincipalDoesNotExistException(String.format("Principal does not exist while attempting to set its password: %s", principal));
+ }
+
+ // This operation does nothing since a new key will be created when exporting the keytab file...
+ return 0;
+ }
+
+ /**
+ * Creates a key tab by using the ipa commandline utilities. It ignores key number and password
+ * as this will be handled by IPA
+ *
+ * @param principal a String containing the principal to test
+ * @param password (IGNORED) a String containing the password to use when creating the principal
+ * @param keyNumber (IGNORED) a Integer indicating the key number for the keytab entries
+ * @return the created Keytab
+ * @throws KerberosOperationException
+ */
+ @Override
+ protected Keytab createKeytab(String principal, String password, Integer keyNumber)
+ throws KerberosOperationException {
+
+ if ((principal == null) || principal.isEmpty()) {
+ throw new KerberosOperationException("Failed to create keytab file, missing principal");
+ }
+
+ // use cache if available
+ if (cachedKeytabs.containsKey(principal)) {
+ return cachedKeytabs.get(principal);
+ }
+
+ File keytabFile = null;
+
+ try {
+ try {
+ keytabFile = File.createTempFile("ambari_tmp", ".keytab");
+
+ // Remove the file else the command will fail...
+ if (!keytabFile.delete()) {
+ LOG.warn("Failed to remove temporary file to hold keytab. Exporting the keytab file for {} may fail.", principal);
+ }
+ } catch (IOException e) {
+ throw new KerberosOperationException(String.format("Failed to create the temporary file needed to hold the exported keytab file for %s: %s", principal, e.getLocalizedMessage()), e);
+ }
+
+
+ exportKeytabFile(principal, keytabFile.getAbsolutePath(), getKeyEncryptionTypes());
+
+ Keytab keytab = readKeytabFile(keytabFile);
+ cachedKeytabs.put(principal, keytab);
+ return keytab;
+ } finally {
+ if ((keytabFile != null) && keytabFile.exists()) {
+ if (!keytabFile.delete()) {
+ LOG.debug("Failed to remove the temporary keytab file, {}", keytabFile.getAbsolutePath());
+ }
+ }
+ }
+ }
+
+ /**
+ * Executes a shell command in a credentials context
+ * <p/>
+ * See {@link ShellCommandUtil#runCommand(String[])}
+ * <p>
+ * This implementation sets the proper environment for the custom <code>KRB5CCNAME </code> value.
+ *
+ * @param command an array of String value representing the command and its arguments
+ * @param envp a map of string, string of environment variables
+ * @param interactiveHandler a handler to provide responses to queries from the command,
+ * or null if no queries are expected
+ * @return a ShellCommandUtil.Result declaring the result of the operation
+ * @throws KerberosOperationException
+ */
+ @Override
+ protected ShellCommandUtil.Result executeCommand(String[] command, Map<String, String> envp, ShellCommandUtil.InteractiveHandler interactiveHandler)
+ throws KerberosOperationException {
+
+ Map<String, String> _envp;
+
+ if (MapUtils.isEmpty(environmentMap)) {
+ _envp = envp;
+ } else if (MapUtils.isEmpty(envp)) {
+ _envp = environmentMap;
+ } else {
+ _envp = new HashMap<>();
+ _envp.putAll(envp);
+ _envp.putAll(environmentMap);
+ }
+
+ return super.executeCommand(command, _envp, interactiveHandler);
+ }
+
+ String getAdminServerHost() {
+ return adminServerHost;
+ }
+
+ String getCredentialCacheFilePath() {
+ return (credentialsCacheFile == null) ? null : credentialsCacheFile.getAbsolutePath();
+ }
+
+ /**
+ * Return an array of Strings containing the command and the relavant arguments needed authenticate
+ * with the KDC and create the Kerberos ticket/credential cache.
+ *
+ * @param executableKinit the absolute path to the kinit executable
+ * @param credentials the KDC adminisrator's credentials
+ * @param credentialsCache the absolute path to the expected location of the Kerberos ticket/credential cache file
+ * @return an array of Strings containing the command to execute
+ */
+ protected abstract String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache);
+
+ /**
+ * Export the requested keytab entries for a given principal into the specified file.
+ *
+ * @param principal the principal name
+ * @param keytabFileDestinationPath the absolute path to the keytab file
+ * @param keyEncryptionTypes a collection of encrption algorithm types indicating which ketyab entries are requested
+ * @throws KerberosOperationException
+ */
+ protected abstract void exportKeytabFile(String principal, String keytabFileDestinationPath, Set<EncryptionType> keyEncryptionTypes) throws KerberosOperationException;
+
+ /**
+ * Initialize the Kerberos ticket cache using the supplied KDC administrator's credentials.
+ * <p>
+ * A randomly named temporary file is created to store the Kerberos ticket cache for this {@link KerberosOperationHandler}'s
+ * session. The file will be removed upon closing when the session is complete. The geneated ticket cache
+ * filename is set in the environment variable map using the variable name "KRB5CCNAME". This will be passed
+ * in for all relevant-system commands.
+ *
+ * @return
+ * @throws KerberosOperationException
+ */
+ protected boolean init() throws KerberosOperationException {
+ if (credentialsCacheFile != null) {
+ if (!credentialsCacheFile.delete()) {
+ LOG.debug("Failed to remove the orphaned cache file, {}", credentialsCacheFile.getAbsolutePath());
+ }
+ credentialsCacheFile = null;
+ }
+
+ try {
+ credentialsCacheFile = File.createTempFile("ambari_krb_", "cc");
+ credentialsCacheFile.deleteOnExit();
+ ensureAmbariOnlyAccess(credentialsCacheFile);
+ } catch (IOException e) {
+ throw new KerberosOperationException(String.format("Failed to create the temporary file needed to hold the administrator ticket cache: %s", e.getLocalizedMessage()), e);
+ }
+
+ String credentialsCache = String.format("FILE:%s", credentialsCacheFile.getAbsolutePath());
+
+ environmentMap = new HashMap<>();
+ environmentMap.put("KRB5CCNAME", credentialsCache);
+
+ PrincipalKeyCredential credentials = getAdministratorCredential();
+
+ ShellCommandUtil.Result result = executeCommand(getKinitCommand(executableKinit, credentials, credentialsCache),
+ environmentMap,
+ new InteractivePasswordHandler(String.valueOf(credentials.getKey()), null));
+
+ if (!result.isSuccessful()) {
+ String message = String.format("Failed to kinit as the KDC administrator user, %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+ credentials.getPrincipal(), result.getExitCode(), result.getStdout(), result.getStderr());
+ LOG.warn(message);
+ throw new KerberosAdminAuthenticationException(message);
+ }
+
+ cachedKeytabs = new HashMap<>();
+
+ return true;
+ }
+
+ /**
+ * Ensures that the owner of the Ambari server process is the only local user account able to
+ * read and write to the specified file or read, write to, and execute the specified directory.
+ *
+ * @param file the file or directory for which to modify access
+ */
+ private void ensureAmbariOnlyAccess(File file) throws AmbariException {
+ if (file.exists()) {
+ if (!file.setReadable(false, false) || !file.setReadable(true, true)) {
+ String message = String.format("Failed to set %s readable only by Ambari", file.getAbsolutePath());
+ LOG.warn(message);
+ throw new AmbariException(message);
+ }
+
+ if (!file.setWritable(false, false) || !file.setWritable(true, true)) {
+ String message = String.format("Failed to set %s writable only by Ambari", file.getAbsolutePath());
+ LOG.warn(message);
+ throw new AmbariException(message);
+ }
+
+ if (file.isDirectory()) {
+ if (!file.setExecutable(false, false) || !file.setExecutable(true, true)) {
+ String message = String.format("Failed to set %s executable by Ambari", file.getAbsolutePath());
+ LOG.warn(message);
+ throw new AmbariException(message);
+ }
+ } else {
+ if (!file.setExecutable(false, false)) {
+ String message = String.format("Failed to set %s not executable", file.getAbsolutePath());
+ LOG.warn(message);
+ throw new AmbariException(message);
+ }
+ }
+ }
+ }
+
+ /**
+ * InteractivePasswordHandler is a {@link ShellCommandUtil.InteractiveHandler}
+ * implementation that answers queries from kadmin or kdamin.local command for the admin and/or user
+ * passwords.
+ */
+ protected static class InteractivePasswordHandler implements ShellCommandUtil.InteractiveHandler {
+ /**
+ * The queue of responses to return
+ */
+ private LinkedList<String> responses;
+ private Queue<String> currentResponses;
+
+ /**
+ * Constructor.
+ *
+ * @param adminPassword the KDC administrator's password (optional)
+ * @param userPassword the user's password (optional)
+ */
+ InteractivePasswordHandler(String adminPassword, String userPassword) {
+ responses = new LinkedList<>();
+
+ if (adminPassword != null) {
+ responses.offer(adminPassword);
+ }
+
+ if (userPassword != null) {
+ responses.offer(userPassword);
+ responses.offer(userPassword); // Add a 2nd time for the password "confirmation" request
+ }
+
+ currentResponses = new LinkedList<>(responses);
+ }
+
+ @Override
+ public boolean done() {
+ return currentResponses.size() == 0;
+ }
+
+ @Override
+ public String getResponse(String query) {
+ return currentResponses.poll();
+ }
+
+ @Override
+ public void start() {
+ currentResponses = new LinkedList<>(responses);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
index 8749f81..948fd60 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
@@ -67,22 +67,7 @@ public abstract class KerberosOperationHandler {
/**
* Kerberos-env configuration property name: group
*/
- public final static String KERBEROS_ENV_USER_PRINCIPAL_GROUP = "group";
-
- /**
- * Kerberos-env configuration property name: password_chat_timeout
- */
- public final static String KERBEROS_ENV_PASSWORD_CHAT_TIMEOUT = "password_chat_timeout";
-
- /**
- * Default timeout for password chat
- */
- public final static int DEFAULT_PASSWORD_CHAT_TIMEOUT = 5;
-
- /**
- * Kerberos-env configuration property name: set_password_expiry
- */
- public final static String KERBEROS_ENV_SET_PASSWORD_EXPIRY = "set_password_expiry";
+ public final static String KERBEROS_ENV_USER_PRINCIPAL_GROUP = "ipa_user_group";
/**
* Kerberos-env configuration property name: ad_create_attributes_template
@@ -232,16 +217,26 @@ public abstract class KerberosOperationHandler {
* @param defaultRealm a String declaring the default Kerberos realm (or domain)
* @param kerberosConfiguration a Map of key/value pairs containing data from the kerberos-env configuration set
*/
- public abstract void open(PrincipalKeyCredential administratorCredential, String defaultRealm, Map<String, String> kerberosConfiguration)
- throws KerberosOperationException;
+ public void open(PrincipalKeyCredential administratorCredential, String defaultRealm, Map<String, String> kerberosConfiguration)
+ throws KerberosOperationException {
+
+ setAdministratorCredential(administratorCredential);
+ setDefaultRealm(defaultRealm);
+
+ if (kerberosConfiguration != null) {
+ setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
+ setExecutableSearchPaths(kerberosConfiguration.get(KERBEROS_ENV_EXECUTABLE_SEARCH_PATHS));
+ }
+ }
/**
* Closes and cleans up any resources used by this KerberosOperationHandler
* <p/>
* It is expected that this KerberosOperationHandler will not be used after this call.
*/
- public abstract void close()
- throws KerberosOperationException;
+ public void close() throws KerberosOperationException {
+ setOpen(false);
+ }
/**
* Test to see if the specified principal exists in a previously configured KDC
@@ -249,10 +244,11 @@ public abstract class KerberosOperationHandler {
* The implementation is specific to a particular type of KDC.
*
* @param principal a String containing the principal to test
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal exists; false otherwise
* @throws KerberosOperationException
*/
- public abstract boolean principalExists(String principal)
+ public abstract boolean principalExists(String principal, boolean service)
throws KerberosOperationException;
/**
@@ -277,11 +273,12 @@ public abstract class KerberosOperationHandler {
*
* @param principal a String containing the principal to update
* @param password a String containing the password to set
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return an Integer declaring the new key number
* @throws KerberosOperationException
* @throws KerberosPrincipalDoesNotExistException if the principal does not exist
*/
- public abstract Integer setPrincipalPassword(String principal, String password)
+ public abstract Integer setPrincipalPassword(String principal, String password, boolean service)
throws KerberosOperationException;
/**
@@ -290,10 +287,11 @@ public abstract class KerberosOperationHandler {
* The implementation is specific to a particular type of KDC.
*
* @param principal a String containing the principal to remove
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal was successfully removed; otherwise false
* @throws KerberosOperationException
*/
- public abstract boolean removePrincipal(String principal)
+ public abstract boolean removePrincipal(String principal, boolean service)
throws KerberosOperationException;
/**
@@ -313,7 +311,7 @@ public abstract class KerberosOperationHandler {
if (credential == null) {
throw new KerberosOperationException("Missing KDC administrator credential");
} else {
- return principalExists(credential.getPrincipal());
+ return principalExists(credential.getPrincipal(), false);
}
}
@@ -568,11 +566,11 @@ public abstract class KerberosOperationHandler {
* @param keyEncryptionTypes a Set of EncryptionKey values or null to indicate the default set
*/
public void setKeyEncryptionTypes(Set<EncryptionType> keyEncryptionTypes) {
- this.keyEncryptionTypes = new HashSet<>(
- (keyEncryptionTypes == null)
- ? DEFAULT_CIPHERS
- : keyEncryptionTypes
- );
+ this.keyEncryptionTypes = Collections.unmodifiableSet(new HashSet<>(
+ (keyEncryptionTypes == null)
+ ? DEFAULT_CIPHERS
+ : keyEncryptionTypes
+ ));
}
@@ -713,8 +711,8 @@ public abstract class KerberosOperationHandler {
* <p/>
* See {@link org.apache.ambari.server.utils.ShellCommandUtil#runCommand(String[], Map<String,String>)}
*
- * @param command an array of String value representing the command and its arguments
- * @param envp a map of string, string of environment variables
+ * @param command an array of String value representing the command and its arguments
+ * @param envp a map of string, string of environment variables
* @param interactiveHandler a handler to provide responses to queries from the command,
* or null if no queries are expected
* @return a ShellCommandUtil.Result declaring the result of the operation
@@ -751,7 +749,7 @@ public abstract class KerberosOperationHandler {
* @see #executeCommand(String[], Map, ShellCommandUtil.InteractiveHandler)
*/
protected ShellCommandUtil.Result executeCommand(String[] command)
- throws KerberosOperationException {
+ throws KerberosOperationException {
return executeCommand(command, null);
}
@@ -760,7 +758,7 @@ public abstract class KerberosOperationHandler {
* <p/>
* See {@link org.apache.ambari.server.utils.ShellCommandUtil#runCommand(String[])}
*
- * @param command an array of String value representing the command and its arguments
+ * @param command an array of String value representing the command and its arguments
* @param interactiveHandler a handler to provide responses to queries from the command,
* or null if no queries are expected
* @return a ShellCommandUtil.Result declaring the result of the operation
[25/51] [abbrv] ambari git commit: AMBARI-22377 Ambari 3.0: Implement
new design for Admin View: Views page. (atkach)
Posted by nc...@apache.org.
AMBARI-22377 Ambari 3.0: Implement new design for Admin View: Views page. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/dd0421a2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/dd0421a2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/dd0421a2
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: dd0421a214f2f9b6c2546bad6d2bc5d743094a40
Parents: 654404d
Author: Andrii Tkach <at...@apache.org>
Authored: Tue Nov 7 18:17:20 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Tue Nov 7 19:52:10 2017 +0200
----------------------------------------------------------------------
.../main/resources/ui/admin-web/app/index.html | 1 +
.../ambariViews/CloneViewInstanceCtrl.js | 274 ++++++++++++++
.../ambariViews/CreateViewInstanceCtrl.js | 353 +++++++-----------
.../controllers/ambariViews/ViewsListCtrl.js | 360 +++++++------------
.../ui/admin-web/app/scripts/i18n.config.js | 14 +-
.../ui/admin-web/app/scripts/routes.js | 34 +-
.../ui/admin-web/app/scripts/services/View.js | 32 +-
.../resources/ui/admin-web/app/styles/main.css | 45 ++-
.../resources/ui/admin-web/app/styles/views.css | 49 +++
.../app/views/ambariViews/listTable.html | 110 ------
.../app/views/ambariViews/listUrls.html | 117 ------
.../app/views/ambariViews/modals/create.html | 238 +++++++-----
.../app/views/ambariViews/modals/edit.html | 138 -------
.../app/views/ambariViews/viewsList.html | 134 +++++++
.../ui/admin-web/app/views/urls/create.html | 4 +-
.../ui/admin-web/app/views/urls/edit.html | 4 +-
.../unit/controllers/CloneViewInstanceCtrl.js | 135 +++++++
.../unit/controllers/CreateViewInstanceCtrl.js | 135 -------
18 files changed, 1050 insertions(+), 1127 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index e9983aa..41cc60f 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -139,6 +139,7 @@
<script src="scripts/controllers/ambariViews/ViewUrlCtrl.js"></script>
<script src="scripts/controllers/ambariViews/ViewUrlEditCtrl.js"></script>
<script src="scripts/controllers/ambariViews/CreateViewInstanceCtrl.js"></script>
+<script src="scripts/controllers/ambariViews/CloneViewInstanceCtrl.js"></script>
<script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
<script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script>
<script src="scripts/controllers/clusters/ExportBlueprintCtrl.js"></script>
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
new file mode 100644
index 0000000..cb37e63
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
@@ -0,0 +1,274 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('CloneViewInstanceCtrl',['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate) {
+ var $t = $translate.instant;
+ $scope.form = {};
+ $scope.constants = {
+ props: $t('views.properties')
+ };
+ $scope.isClone = $routeParams.instanceId ? true : false;
+ var targetUrl = '';
+
+ function loadMeta(){
+ View.getMeta($routeParams.viewId, $scope.version).then(function(data) {
+ var viewVersion = data.data,
+ parameters;
+
+ $scope.view = viewVersion;
+ parameters = viewVersion.ViewVersionInfo.parameters;
+
+ angular.forEach(parameters, function (item) {
+ item.value = item['defaultValue'];
+ item.clusterConfig = !!item.clusterConfig;
+ item.displayName = item.name.replace(/\./g, '\.\u200B');
+ item.clusterConfig ? $scope.numberOfClusterConfigs++ : $scope.numberOfSettingConfigs++;
+ });
+
+ $scope.clusterConfigurable = viewVersion.ViewVersionInfo.cluster_configurable;
+ $scope.clusterConfigurableErrorMsg = $scope.clusterConfigurable ? "" : $t('views.alerts.cannotUseOption');
+
+ $scope.instance = {
+ view_name: viewVersion.ViewVersionInfo.view_name,
+ version: viewVersion.ViewVersionInfo.version,
+ instance_name: '',
+ label: '',
+ visible: true,
+ icon_path: '',
+ icon64_path: '',
+ properties: parameters,
+ description: '',
+ clusterType: 'NONE'
+ };
+
+ //if cloning view instance, then get the instance data and populate settings and properties
+ if($scope.isClone) {
+ View.getInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId)
+ .then(function(instance) {
+ $scope.instanceClone = instance;
+ $scope.instance.version = instance.ViewInstanceInfo.version;
+ $scope.version = instance.ViewInstanceInfo.version;
+ $scope.instance.instance_name = instance.ViewInstanceInfo.instance_name + $t('common.copy');
+ $scope.instance.label = instance.ViewInstanceInfo.label + $t('common.copy');
+ $scope.instance.visible = instance.ViewInstanceInfo.visible;
+ $scope.instance.description = instance.ViewInstanceInfo.description;
+ $scope.instance.clusterType=instance.ViewInstanceInfo.cluster_type;
+
+ initConfigurations(parameters);
+ })
+ .catch(function(data) {
+ Alert.error($t('views.alerts.cannotLoadInstanceInfo'), data.data.message);
+ });
+ }
+
+ loadClusters();
+ loadRemoteClusters();
+
+ });
+ }
+
+ function initConfigurations(parameters) {
+ var configuration = angular.copy($scope.instanceClone.ViewInstanceInfo.properties);
+
+ //iterate through the view parameters and get the values from the instance being cloned
+ for (var i = 0; i < parameters.length; i++) {
+ parameters[i].value = configuration[parameters[i].name];
+ parameters[i].clusterConfig = !!parameters[i].clusterConfig;
+ }
+ }
+
+ $scope.$watch(function(scope) {
+ return scope.version;
+ }, function(version) {
+ if( version ){
+ loadMeta();
+ }
+ });
+
+ $scope.enableLocalCluster = function () {
+ if($scope.errorKeys.length > 0) {
+ $scope.errorKeys.forEach( function (key) {
+ try {
+ $scope.form.instanceCreateForm[key].validationError = false;
+ $scope.form.instanceCreateForm[key].validationMessage = '';
+ } catch (e) {
+ console.log($t('views.alerts.unableToResetErrorMessage', {key: key}));
+ }
+ });
+ $scope.errorKeys = [];
+ }
+ };
+
+ // $scope.view = viewVersion;
+ $scope.isAdvancedClosed = true;
+ $scope.instanceExists = false;
+ $scope.errorKeys = [];
+
+ $scope.clusterConfigurable = false;
+ $scope.clusterConfigurableErrorMsg = "";
+ $scope.clusters = [];
+ $scope.remoteClusters = [];
+ $scope.noLocalClusterAvailible = true;
+ $scope.noRemoteClusterAvailible = true;
+ $scope.cluster = null;
+ $scope.data = {};
+ $scope.data.remoteCluster = null;
+ $scope.numberOfClusterConfigs = 0;
+ $scope.numberOfSettingConfigs = 0;
+
+ function loadClusters() {
+ Cluster.getAllClusters().then(function (clusters) {
+ if(clusters.length >0){
+ clusters.forEach(function(cluster) {
+ $scope.clusters.push({
+ "name" : cluster.Clusters.cluster_name,
+ "id" : cluster.Clusters.cluster_id
+ })
+ });
+ $scope.noLocalClusterAvailible = false;
+ //do not set to default Local Cluster configuration when cloning instance
+ if($scope.clusterConfigurable && !$scope.isClone){
+ $scope.instance.clusterType = "LOCAL_AMBARI";
+ }
+ }else{
+ $scope.clusters.push($t('common.noClusters'));
+ }
+ $scope.cluster = $scope.clusters[0];
+ });
+ }
+
+ function loadRemoteClusters() {
+ RemoteCluster.listAll().then(function (clusters) {
+ if(clusters.length >0){
+ clusters.forEach(function(cluster) {
+ $scope.remoteClusters.push({
+ "name" : cluster.ClusterInfo.name,
+ "id" : cluster.ClusterInfo.cluster_id
+ })
+ });
+ $scope.noRemoteClusterAvailible = false;
+ }else{
+ $scope.remoteClusters.push($t('common.noClusters'));
+ }
+ $scope.data.remoteCluster = $scope.remoteClusters[0];
+ });
+ }
+
+
+ $scope.versions = [];
+ $scope.version = null;
+
+ View.getVersions($routeParams.viewId).then(function(versions) {
+ $scope.versions = versions;
+ $scope.version = $scope.versions[$scope.versions.length-1];
+ });
+
+
+ $scope.nameValidationPattern = /^\s*\w*\s*$/;
+
+ $scope.save = function() {
+ if (!$scope.form.instanceCreateForm.isSaving) {
+ $scope.form.instanceCreateForm.submitted = true;
+ if($scope.form.instanceCreateForm.$valid){
+ $scope.form.instanceCreateForm.isSaving = true;
+
+ switch($scope.instance.clusterType) {
+ case 'LOCAL_AMBARI':
+ console.log($scope.cluster);
+ $scope.instance.clusterId = $scope.cluster.id;
+ break;
+ case 'REMOTE_AMBARI':
+ console.log($scope.data.remoteCluster);
+ $scope.instance.clusterId = $scope.data.remoteCluster.id;
+
+ break;
+ default:
+ $scope.instance.clusterId = null;
+ }
+ console.log($scope.instance.clusterId);
+ View.createInstance($scope.instance)
+ .then(function(data) {
+ Alert.success($t('views.alerts.instanceCreated', {instanceName: $scope.instance.instance_name}));
+ $scope.form.instanceCreateForm.$setPristine();
+ if( targetUrl ){
+ $location.path(targetUrl);
+ } else {
+ $location.path('/views/' + $scope.instance.view_name + '/versions/' + $scope.instance.version + '/instances/' + $scope.instance.instance_name + '/edit');
+ }
+ $scope.form.instanceCreateForm.isSaving = false;
+ $scope.$root.$emit('instancesUpdate');
+ })
+ .catch(function (data) {
+ var errorMessage = data.message;
+ var showGeneralError = true;
+
+ if (data.status >= 400 && $scope.instance.clusterType == 'NONE') {
+ try {
+ var errorObject = JSON.parse(errorMessage);
+ errorMessage = errorObject.detail;
+ angular.forEach(errorObject.propertyResults, function (item, key) {
+ $scope.form.instanceCreateForm[key].validationError = !item.valid;
+ if (!item.valid) {
+ showGeneralError = false;
+ $scope.form.instanceCreateForm[key].validationMessage = item.detail;
+ $scope.errorKeys.push(key);
+ }
+ });
+
+ if (showGeneralError) {
+ $scope.form.instanceCreateForm.generalValidationError = errorMessage;
+ }
+ } catch (e) {
+ console.error($t('views.alerts.unableToParseError', {message: data.message}));
+ }
+ }
+ Alert.error($t('views.alerts.cannotCreateInstance'), errorMessage);
+ $scope.form.instanceCreateForm.isSaving = false;
+ });
+ }
+ }
+ };
+
+ $scope.cancel = function() {
+ $scope.form.instanceCreateForm.$setPristine();
+ $location.path('/views');
+ };
+
+ $scope.$on('$locationChangeStart', function(event, __targetUrl) {
+ if( $scope.form.instanceCreateForm.$dirty ){
+ UnsavedDialog().then(function(action) {
+ targetUrl = __targetUrl.split('#').pop();
+ switch(action){
+ case 'save':
+ $scope.save();
+ break;
+ case 'discard':
+ $scope.form.instanceCreateForm.$setPristine();
+ $location.path(targetUrl);
+ break;
+ case 'cancel':
+ targetUrl = '';
+ break;
+ }
+ });
+ event.preventDefault();
+ }
+ });
+}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
index 94b8cc1..d5e3758 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
@@ -18,263 +18,170 @@
'use strict';
angular.module('ambariAdminConsole')
-.controller('CreateViewInstanceCtrl',['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate) {
+.controller('CreateViewInstanceCtrl',
+['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', '$modalInstance', 'views', '$q',
+function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate, $modalInstance, views, $q) {
+
var $t = $translate.instant;
+ var viewToVersionMap = {};
+ var instances = {};
$scope.form = {};
- $scope.constants = {
- props: $t('views.properties')
+ $scope.nameValidationPattern = /^\s*\w*\s*$/;
+ $scope.isLoading = false;
+ $scope.isLocalTypeChosen = true;
+ $scope.views = views;
+ $scope.viewOptions = [];
+ $scope.versionOptions = [];
+ $scope.localClusters = [];
+ $scope.remoteClusters = [];
+ $scope.clusterOptions = [];
+ $scope.isInstanceExists = false;
+ $scope.formData = {
+ view: null,
+ version: null,
+ instanceName: '',
+ displayName: '',
+ description: '',
+ clusterName: null,
+ visible: true
};
- $scope.isClone = $routeParams.instanceId ? true : false;
- var targetUrl = '';
-
- function loadMeta(){
- View.getMeta($routeParams.viewId, $scope.version).then(function(data) {
- var viewVersion = data.data,
- parameters;
-
- $scope.view = viewVersion;
- parameters = viewVersion.ViewVersionInfo.parameters;
-
- angular.forEach(parameters, function (item) {
- item.value = item['defaultValue'];
- item.clusterConfig = !!item.clusterConfig;
- item.displayName = item.name.replace(/\./g, '\.\u200B');
- item.clusterConfig ? $scope.numberOfClusterConfigs++ : $scope.numberOfSettingConfigs++;
- });
-
- $scope.clusterConfigurable = viewVersion.ViewVersionInfo.cluster_configurable;
- $scope.clusterConfigurableErrorMsg = $scope.clusterConfigurable ? "" : $t('views.alerts.cannotUseOption');
-
- $scope.instance = {
- view_name: viewVersion.ViewVersionInfo.view_name,
- version: viewVersion.ViewVersionInfo.version,
- instance_name: '',
- label: '',
- visible: true,
- icon_path: '',
- icon64_path: '',
- properties: parameters,
- description: '',
- clusterType: 'NONE'
- };
-
- //if cloning view instance, then get the instance data and populate settings and properties
- if($scope.isClone) {
- View.getInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId)
- .then(function(instance) {
- $scope.instanceClone = instance;
- $scope.instance.version = instance.ViewInstanceInfo.version;
- $scope.version = instance.ViewInstanceInfo.version;
- $scope.instance.instance_name = instance.ViewInstanceInfo.instance_name + $t('common.copy');
- $scope.instance.label = instance.ViewInstanceInfo.label + $t('common.copy');
- $scope.instance.visible = instance.ViewInstanceInfo.visible;
- $scope.instance.description = instance.ViewInstanceInfo.description;
- $scope.instance.clusterType=instance.ViewInstanceInfo.cluster_type;
-
- initConfigurations(parameters);
- })
- .catch(function(data) {
- Alert.error($t('views.alerts.cannotLoadInstanceInfo'), data.data.message);
- });
- }
-
- loadClusters();
- loadRemoteClusters();
-
- });
- }
- function initConfigurations(parameters) {
- var configuration = angular.copy($scope.instanceClone.ViewInstanceInfo.properties);
-
- //iterate through the view parameters and get the values from the instance being cloned
- for (var i = 0; i < parameters.length; i++) {
- parameters[i].value = configuration[parameters[i].name];
- parameters[i].clusterConfig = !!parameters[i].clusterConfig;
- }
+ $scope.updateVersionOptions = function () {
+ if (viewToVersionMap[$scope.formData.view.value]) {
+ $scope.versionOptions = viewToVersionMap[$scope.formData.view.value];
+ $scope.formData.version = $scope.versionOptions[0];
}
+ };
- $scope.$watch(function(scope) {
- return scope.version;
- }, function(version) {
- if( version ){
- loadMeta();
- }
- });
-
- $scope.enableLocalCluster = function () {
- if($scope.errorKeys.length > 0) {
- $scope.errorKeys.forEach( function (key) {
- try {
- $scope.form.instanceCreateForm[key].validationError = false;
- $scope.form.instanceCreateForm[key].validationMessage = '';
- } catch (e) {
- console.log($t('views.alerts.unableToResetErrorMessage', {key: key}));
- }
- });
- $scope.errorKeys = [];
+ $scope.switchClusterType = function(bool) {
+ $scope.isLocalTypeChosen = bool;
+ if ($scope.isLocalTypeChosen) {
+ $scope.clusterOptions = $scope.localClusters;
+ } else {
+ $scope.clusterOptions = $scope.remoteClusters;
}
+ $scope.formData.clusterName = $scope.clusterOptions[0];
};
- // $scope.view = viewVersion;
- $scope.isAdvancedClosed = true;
- $scope.instanceExists = false;
- $scope.errorKeys = [];
-
- $scope.clusterConfigurable = false;
- $scope.clusterConfigurableErrorMsg = "";
- $scope.clusters = [];
- $scope.remoteClusters = [];
- $scope.noLocalClusterAvailible = true;
- $scope.noRemoteClusterAvailible = true;
- $scope.cluster = null;
- $scope.data = {};
- $scope.data.remoteCluster = null;
- $scope.numberOfClusterConfigs = 0;
- $scope.numberOfSettingConfigs = 0;
-
- function loadClusters() {
- Cluster.getAllClusters().then(function (clusters) {
- if(clusters.length >0){
- clusters.forEach(function(cluster) {
- $scope.clusters.push({
- "name" : cluster.Clusters.cluster_name,
- "id" : cluster.Clusters.cluster_id
- })
- });
- $scope.noLocalClusterAvailible = false;
- //do not set to default Local Cluster configuration when cloning instance
- if($scope.clusterConfigurable && !$scope.isClone){
- $scope.instance.clusterType = "LOCAL_AMBARI";
- }
- }else{
- $scope.clusters.push($t('common.noClusters'));
- }
- $scope.cluster = $scope.clusters[0];
- });
- }
-
- function loadRemoteClusters() {
- RemoteCluster.listAll().then(function (clusters) {
- if(clusters.length >0){
- clusters.forEach(function(cluster) {
- $scope.remoteClusters.push({
- "name" : cluster.ClusterInfo.name,
- "id" : cluster.ClusterInfo.cluster_id
- })
- });
- $scope.noRemoteClusterAvailible = false;
- }else{
- $scope.remoteClusters.push($t('common.noClusters'));
- }
- $scope.data.remoteCluster = $scope.remoteClusters[0];
- });
- }
-
-
- $scope.versions = [];
- $scope.version = null;
-
- View.getVersions($routeParams.viewId).then(function(versions) {
- $scope.versions = versions;
- $scope.version = $scope.versions[$scope.versions.length-1];
- });
-
-
- $scope.nameValidationPattern = /^\s*\w*\s*$/;
-
- $scope.save = function() {
- if (!$scope.form.instanceCreateForm.isSaving) {
+ $scope.save = function () {
+ var instanceName = $scope.form.instanceCreateForm.instanceName.$viewValue;
$scope.form.instanceCreateForm.submitted = true;
- if($scope.form.instanceCreateForm.$valid){
- $scope.form.instanceCreateForm.isSaving = true;
-
- switch($scope.instance.clusterType) {
- case 'LOCAL_AMBARI':
- console.log($scope.cluster);
- $scope.instance.clusterId = $scope.cluster.id;
- break;
- case 'REMOTE_AMBARI':
- console.log($scope.data.remoteCluster);
- $scope.instance.clusterId = $scope.data.remoteCluster.id;
-
- break;
- default:
- $scope.instance.clusterId = null;
- }
- console.log($scope.instance.clusterId);
- View.createInstance($scope.instance)
- .then(function(data) {
- Alert.success($t('views.alerts.instanceCreated', {instanceName: $scope.instance.instance_name}));
- $scope.form.instanceCreateForm.$setPristine();
- if( targetUrl ){
- $location.path(targetUrl);
- } else {
- $location.path('/views/' + $scope.instance.view_name + '/versions/' + $scope.instance.version + '/instances/' + $scope.instance.instance_name + '/edit');
- }
- $scope.form.instanceCreateForm.isSaving = false;
- $scope.$root.$emit('instancesUpdate');
+ if ($scope.form.instanceCreateForm.$valid) {
+ View.createInstance({
+ instance_name: instanceName,
+ label: $scope.form.instanceCreateForm.displayName.$viewValue,
+ visible: $scope.form.instanceCreateForm.visible.$viewValue,
+ icon_path: '',
+ icon64_path: '',
+ description: $scope.form.instanceCreateForm.description.$viewValue,
+ view_name: $scope.form.instanceCreateForm.view.$viewValue.value,
+ version: $scope.form.instanceCreateForm.version.$viewValue.value,
+ properties: [],
+ clusterId: $scope.form.instanceCreateForm.clusterName.$viewValue.id,
+ clusterType: $scope.isLocalTypeChosen ? 'LOCAL_AMBARI': 'REMOTE_AMBARI'
+ })
+ .then(function () {
+ $modalInstance.dismiss('created');
+ Alert.success($t('views.alerts.instanceCreated', {instanceName: instanceName}));
+ $location.path('/views/' + $scope.form.instanceCreateForm.view.$viewValue.value +
+ '/versions/' + $scope.form.instanceCreateForm.version.$viewValue.value +
+ '/instances/' + instanceName + '/edit');
})
.catch(function (data) {
var errorMessage = data.message;
- var showGeneralError = true;
- if (data.status >= 400 && $scope.instance.clusterType == 'NONE') {
+ if (data.status >= 400) {
try {
- var errorObject = JSON.parse(errorMessage);
- errorMessage = errorObject.detail;
- angular.forEach(errorObject.propertyResults, function (item, key) {
- $scope.form.instanceCreateForm[key].validationError = !item.valid;
- if (!item.valid) {
- showGeneralError = false;
- $scope.form.instanceCreateForm[key].validationMessage = item.detail;
- $scope.errorKeys.push(key);
- }
- });
-
- if (showGeneralError) {
- $scope.form.instanceCreateForm.generalValidationError = errorMessage;
- }
+ errorMessage = JSON.parse(errorMessage).detail;
} catch (e) {
- console.error($t('views.alerts.unableToParseError', {message: data.message}));
+ console.warn(data.message, e);
}
}
Alert.error($t('views.alerts.cannotCreateInstance'), errorMessage);
- $scope.form.instanceCreateForm.isSaving = false;
});
- }
}
};
- $scope.cancel = function() {
- $scope.form.instanceCreateForm.$setPristine();
- $location.path('/views');
+ $scope.cancel = function () {
+ unsavedChangesCheck();
+ };
+
+ $scope.checkIfInstanceExist = function() {
+ $scope.isInstanceExists = Boolean(instances[$scope.formData.instanceName]);
};
- $scope.$on('$locationChangeStart', function(event, __targetUrl) {
- if( $scope.form.instanceCreateForm.$dirty ){
- UnsavedDialog().then(function(action) {
- targetUrl = __targetUrl.split('#').pop();
- switch(action){
+ function initViewAndVersionSelect () {
+ $scope.viewOptions = [];
+ angular.forEach($scope.views, function(view) {
+ $scope.viewOptions.push({
+ label: view.view_name,
+ value: view.view_name
+ });
+ viewToVersionMap[view.view_name] = view.versionsList.map(function(version) {
+ angular.forEach(version.instances, function(instance) {
+ instances[instance.ViewInstanceInfo.instance_name] = true;
+ });
+ return {
+ label: version.ViewVersionInfo.version,
+ value: version.ViewVersionInfo.version
+ }
+ });
+ });
+ $scope.formData.view = $scope.viewOptions[0];
+ $scope.updateVersionOptions();
+ }
+
+ function loadClusters() {
+ return Cluster.getAllClusters().then(function (clusters) {
+ clusters.forEach(function (cluster) {
+ $scope.localClusters.push({
+ label: cluster.Clusters.cluster_name,
+ value: cluster.Clusters.cluster_name,
+ id: cluster.Clusters.cluster_id
+ });
+ });
+ });
+ }
+
+ function loadRemoteClusters() {
+ return RemoteCluster.listAll().then(function (clusters) {
+ clusters.forEach(function (cluster) {
+ $scope.remoteClusters.push({
+ label: cluster.ClusterInfo.name,
+ value: cluster.ClusterInfo.name,
+ id: cluster.ClusterInfo.cluster_id
+ });
+ });
+ });
+ }
+
+ function loadFormData () {
+ $scope.isLoading = true;
+ initViewAndVersionSelect();
+ $q.all(loadClusters(), loadRemoteClusters()).then(function() {
+ $scope.isLoading = false;
+ $scope.switchClusterType(true);
+ });
+ }
+
+ function unsavedChangesCheck() {
+ if ($scope.form.instanceCreateForm.$dirty) {
+ UnsavedDialog().then(function (action) {
+ switch (action) {
case 'save':
$scope.save();
break;
case 'discard':
- $scope.form.instanceCreateForm.$setPristine();
- $location.path(targetUrl);
+ $modalInstance.close('discard');
break;
case 'cancel':
- targetUrl = '';
break;
}
});
- event.preventDefault();
+ } else {
+ $modalInstance.close('discard');
}
- });
-
-
-
-
-
+ }
+ loadFormData();
}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
index 4e7bae3..aba5702 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
@@ -18,272 +18,186 @@
'use strict';
angular.module('ambariAdminConsole')
-.controller('ViewsListCtrl',['$scope', 'View','$modal', 'Alert', 'ConfirmationModal', '$location', '$translate', function($scope, View, $modal, Alert, ConfirmationModal, $location, $translate) {
- var deferredList = [],
- $t = $translate.instant;
- $scope.isLoadingViews = false;
- $scope.isLoadingUrls = false;
- $scope.constants = {
- unable: $t('views.alerts.unableToCreate'),
- views: $t('common.views').toLowerCase()
- };
- $scope.$on('$locationChangeStart', function() {
- deferredList.forEach(function(def) {
- def.reject();
- })
- });
-
- $scope.createUrlDisabled = false;
+.controller('ViewsListCtrl',['$scope', 'View','$modal', 'Alert', 'ConfirmationModal', '$translate', function($scope, View, $modal, Alert, ConfirmationModal, $translate) {
+ var $t = $translate.instant;
+ var VIEWS_VERSION_STATUS_TIMEOUT = 5000;
+ $scope.isLoading = false;
+ $scope.minInstanceForPagination = 10;
- function checkViewVersionStatus(view, versionObj, versionNumber){
+ function checkViewVersionStatus(view, versionObj, versionNumber) {
var deferred = View.checkViewVersionStatus(view.view_name, versionNumber);
- deferredList.push(deferred);
- deferred.promise.then(function(status) {
- deferredList.splice(deferredList.indexOf(deferred), 1);
- if (status !== 'DEPLOYED' && status !== 'ERROR') {
- checkViewVersionStatus(view, versionObj, versionNumber);
+ deferred.promise.then(function (status) {
+ if (versionNeedStatusUpdate(status)) {
+ setTimeout(function() {
+ checkViewVersionStatus(view, versionObj, versionNumber);
+ }, VIEWS_VERSION_STATUS_TIMEOUT);
} else {
- $scope.$evalAsync(function() {
- versionObj.status = status;
- angular.forEach(view.versions, function(version) {
- if(version.status === 'DEPLOYED'){
- view.canCreateInstance = true;
- }
- })
- });
+ versionObj.status = status;
+ angular.forEach(view.versions, function (version) {
+ if (version.status === 'DEPLOYED') {
+ view.canCreateInstance = true;
+ }
+ })
}
});
}
- function loadViews(){
- $scope.isLoadingViews = true;
- View.all().then(function(views) {
- $scope.isLoadingViews = false;
+ function versionNeedStatusUpdate(status) {
+ return status !== 'DEPLOYED' && status !== 'ERROR';
+ }
+
+ function loadViews() {
+ $scope.isLoading = true;
+ View.all().then(function (views) {
+ $scope.isLoading = false;
$scope.views = views;
- $scope.getFilteredViews();
- angular.forEach(views, function(view) {
- angular.forEach(view.versions, function(versionObj, versionNumber) {
- if (versionObj.status !== 'DEPLOYED' || versionObj.status !== 'ERROR'){
- checkViewVersionStatus(view, versionObj, versionNumber);
- }
+ $scope.instances = [];
+ angular.forEach(views, function (view) {
+ // TODO uncomment if view need status update
+ // angular.forEach(view.versions, function (versionObj, versionNumber) {
+ // if (versionNeedStatusUpdate(versionObj.status)) {
+ // checkViewVersionStatus(view, versionObj, versionNumber);
+ // }
+ // });
+ angular.forEach(view.instances, function (instance) {
+ instance.ViewInstanceInfo.short_url_name = instance.ViewInstanceInfo.short_url_name || '';
+ instance.ViewInstanceInfo.short_url = instance.ViewInstanceInfo.short_url || '';
+ $scope.instances.push(instance.ViewInstanceInfo);
});
- })
- }).catch(function(data) {
+ });
+ initTypeFilter();
+ $scope.filterInstances();
+ }).catch(function (data) {
Alert.error($t('views.alerts.cannotLoadViews'), data.data.message);
});
}
- loadViews();
+ function initTypeFilter() {
+ var uniqTypes = $.unique($scope.instances.map(function(instance) {
+ return instance.view_name;
+ }));
+ $scope.typeFilterOptions = [ { label: $t('common.all'), value: '*'} ]
+ .concat(uniqTypes.map(function(type) {
+ return {
+ label: type,
+ value: type
+ };
+ }));
+ $scope.instanceTypeFilter = $scope.typeFilterOptions[0];
+ }
- $scope.createInstance = function(view) {
- var modalInstance = $modal.open({
- templateUrl: 'views/ambariViews/modals/create.html',
- size: 'lg',
- controller: 'CreateViewInstanceCtrl',
- resolve: {
- viewVersion: function(){
- return view.versionsList[ view.versionsList.length-1];
+ function showInstancesOnPage() {
+ var startIndex = ($scope.currentPage - 1) * $scope.instancesPerPage + 1;
+ var endIndex = $scope.currentPage * $scope.instancesPerPage;
+ var showedCount = 0;
+ var filteredCount = 0;
+
+ angular.forEach($scope.instances, function(instance) {
+ instance.isShowed = false;
+ if (instance.isFiltered) {
+ filteredCount++;
+ if (filteredCount >= startIndex && filteredCount <= endIndex) {
+ instance.isShowed = true;
+ showedCount++;
}
}
});
+ $scope.tableInfo.showed = showedCount;
+ }
- modalInstance.result.then(loadViews);
- };
-
- $scope.viewsFilter = '';
- $scope.filteredViews = [];
- $scope.getFilteredViews = function(views) {
- var result = [];
- var filter = $scope.viewsFilter.toLowerCase();
- if(!filter){ // if no filter return all views
- result = $scope.views.map(function(view) {
- view.isOpened = false;
- return view;
- });
- } else {
- result = $scope.views.map(function(view) {
- view.isOpened = true;
- if(view.view_name.toLowerCase().indexOf(filter) >= 0){
- return view; // if filter matched with view name -- return whole view
- } else {
- var instances = [];
- angular.forEach(view.instances, function(instance) {
- if(instance.ViewInstanceInfo.label.toLowerCase().indexOf(filter) >= 0){
- instances.push(instance);
- }
- });
- if( instances.length ){ // If inside view exists instances with matched filter - show only this instances
- var v = angular.copy(view);
- v.instances = instances;
- return v;
- }
- }
- }).filter(function(view) {
- return !!view; // Remove 'undefined'
- });
- }
- $scope.filteredViews = result;
- };
-
- $scope.gotoCreate = function(viewName, isAllowed) {
- if(isAllowed){
- $location.path('/views/'+viewName+'/new');
- }
- };
-
- $scope.deleteInstance = function(instance) {
- ConfirmationModal.show(
- $t('common.delete', {
- term: $t('views.viewInstance')
- }),
- $t('common.deleteConfirmation', {
- instanceType: $t('views.viewInstance'),
- instanceName: instance.ViewInstanceInfo.label
- })
- ).then(function() {
- View.deleteInstance(instance.ViewInstanceInfo.view_name, instance.ViewInstanceInfo.version, instance.ViewInstanceInfo.instance_name)
- .then(function() {
- loadViews();
- })
- .catch(function(data) {
- Alert.error($t('views.alerts.cannotDeleteInstance'), data.data.message);
- });
- });
- };
-
- $scope.reloadViews = function () {
- loadViews();
- };
-
- /**
- * Url listing
- */
-
- $scope.loadedUrls = [];
- $scope.urlsPerPage = 10;
+ $scope.views = [];
+ $scope.instances = [];
+ $scope.instancesPerPage = 10;
$scope.currentPage = 1;
- $scope.totalUrls = 1;
- $scope.urlNameFilter = '';
- $scope.urlSuffixfilter = '';
- $scope.maxVisiblePages=20;
+ $scope.instanceNameFilter = '';
+ $scope.instanceUrlFilter = '';
+ $scope.maxVisiblePages = 10;
+ $scope.isNotEmptyFilter = true;
+ $scope.instanceTypeFilter = '';
$scope.tableInfo = {
- total: 0,
+ filtered: 0,
showed: 0
};
- $scope.isNotEmptyFilter = true;
-
-
- $scope.pageChanged = function() {
- $scope.listViewUrls();
- };
+ loadViews();
- $scope.urlsPerPageChanged = function() {
+ $scope.filterInstances = function() {
+ var filteredCount = 0;
+ angular.forEach($scope.instances, function(instance) {
+ if ($scope.instanceNameFilter && instance.short_url_name.indexOf($scope.instanceNameFilter) === -1) {
+ return instance.isFiltered = false;
+ }
+ if ($scope.instanceUrlFilter && ('/main/view/'+ instance.view_name + '/' + instance.short_url).indexOf($scope.instanceUrlFilter) === -1) {
+ return instance.isFiltered = false;
+ }
+ if ($scope.instanceTypeFilter.value !== '*' && instance.view_name.indexOf($scope.instanceTypeFilter.value) === -1) {
+ return instance.isFiltered = false;
+ }
+ filteredCount++;
+ instance.isFiltered = true;
+ });
+ $scope.tableInfo.filtered = filteredCount;
$scope.resetPagination();
};
+ $scope.pageChanged = function() {
+ showInstancesOnPage();
+ };
$scope.resetPagination = function() {
$scope.currentPage = 1;
- $scope.listViewUrls();
+ showInstancesOnPage();
};
-
- $scope.getVersions = function(instances) {
- var names = [];
-
- instances.map(function(view){
- var name = view.view_name;
- names.push(name);
- });
-
- var output = [],
- keys = [];
-
- angular.forEach(names, function(item) {
- var key = item;
- if(keys.indexOf(key) === -1) {
- keys.push(key);
- output.push(item);
- }
- });
- return output;
- };
-
-
-
$scope.clearFilters = function () {
- $scope.urlNameFilter = '';
- $scope.urlSuffixfilter = '';
+ $scope.instanceNameFilter = '';
+ $scope.instanceUrlFilter = '';
$scope.instanceTypeFilter = $scope.typeFilterOptions[0];
$scope.resetPagination();
};
-
-
$scope.$watch(
- function (scope) {
- return Boolean(scope.urlNameFilter || scope.urlSuffixfilter || (scope.instanceTypeFilter && scope.instanceTypeFilter.value !== '*'));
- },
- function (newValue, oldValue, scope) {
- scope.isNotEmptyFilter = newValue;
- }
+ function (scope) {
+ return Boolean(scope.instanceNameFilter || scope.instanceUrlFilter || (scope.instanceTypeFilter && scope.instanceTypeFilter.value !== '*'));
+ },
+ function (newValue, oldValue, scope) {
+ scope.isNotEmptyFilter = newValue;
+ }
);
-
-
-
- $scope.listViewUrls = function(){
- $scope.isLoadingUrls = true;
- View.allUrls({
- currentPage: $scope.currentPage,
- urlsPerPage: $scope.urlsPerPage,
- searchString: $scope.urlNameFilter,
- suffixSearch: $scope.urlSuffixfilter,
- instanceType: $scope.instanceTypeFilter?$scope.instanceTypeFilter.value:'*'
- }).then(function(urls) {
- $scope.isLoadingUrls = false;
- $scope.urls = urls;
- $scope.ViewNameFilterOptions = urls.items.map(function(url){
- return url.ViewUrlInfo.view_instance_common_name;
- });
-
- $scope.totalUrls = urls.itemTotal;
- $scope.tableInfo.showed = urls.items.length;
- $scope.tableInfo.total = urls.itemTotal;
-
- // get all view instances to enable/disable creation if empty
-
- }).catch(function(data) {
- Alert.error($t('views.alerts.cannotLoadViewUrls'), data.message);
+ $scope.createInstance = function () {
+ var modalInstance = $modal.open({
+ templateUrl: 'views/ambariViews/modals/create.html',
+ controller: 'CreateViewInstanceCtrl',
+ resolve: {
+ views: function() {
+ return $scope.views;
+ }
+ },
+ backdrop: 'static'
});
- };
+ modalInstance.result.then(loadViews);
+ };
- $scope.initViewUrls = function(){
- $scope.listViewUrls();
- View.getAllVisibleInstance().then(function(instances){
- // if no instances then disable the create button
- if(!instances.length){
- $scope.createUrlDisabled = true;
- } else {
- $scope.typeFilterOptions = [{ label: $t('common.all'), value: '*'}]
- .concat($scope.getVersions(instances).map(function(key) {
- return {
- label: key,
- value: key
- };
- }));
-
- $scope.instanceTypeFilter = $scope.typeFilterOptions[0];
- }
-
- }).catch(function(data) {
- // Make the create button enabled, and swallow the error
- $scope.createUrlDisabled = false;
+ $scope.deleteInstance = function (instance) {
+ ConfirmationModal.show(
+ $t('common.delete', {
+ term: $t('views.viewInstance')
+ }),
+ $t('common.deleteConfirmation', {
+ instanceType: $t('views.viewInstance'),
+ instanceName: instance.label
+ })
+ ).then(function () {
+ View.deleteInstance(instance.view_name, instance.version, instance.instance_name)
+ .then(function () {
+ loadViews();
+ })
+ .catch(function (data) {
+ Alert.error($t('views.alerts.cannotDeleteInstance'), data.data.message);
+ });
});
-
};
-
-}]);
\ No newline at end of file
+}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
index cb52df1..73ab064 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
@@ -32,7 +32,6 @@ angular.module('ambariAdminConsole')
'common.register': 'Register',
'common.clusters': 'Clusters',
'common.views': 'Views',
- 'common.viewUrls': 'View URLs',
'common.roles': 'Roles',
'common.users': 'Users',
'common.groups': 'Groups',
@@ -80,6 +79,7 @@ angular.module('ambariAdminConsole')
'common.remoteClusterDelConfirmation': 'Are you sure you want to delete {{instanceType}} {{instanceName}}? This operation cannot be undone.',
'common.messageInstanceAffected': 'The following View Instances are using this Remote Cluster for configuration, and will need to be reconfigured:',
'common.local': 'Local',
+ 'common.remote': 'Remote',
'common.pam': 'PAM',
'common.ldap': 'LDAP',
'common.jwt': 'JWT',
@@ -100,6 +100,7 @@ angular.module('ambariAdminConsole')
'common.clusterManagement': 'Cluster Management',
'common.userManagement': 'User Management',
'common.admin': 'Admin',
+ 'common.actions': 'Actions',
'common.clusterNameChangeConfirmation.title': 'Confirm Cluster Name Change',
'common.clusterNameChangeConfirmation.message': 'Are you sure you want to change the cluster name to {{clusterName}}?',
@@ -191,7 +192,7 @@ angular.module('ambariAdminConsole')
'views.viewInstance': 'View Instance',
'views.create': 'Create Instance',
'views.clone': 'Clone Instance',
- 'views.createViewInstance': 'Create View Instance',
+ 'views.createViewInstance': 'Create Instance',
'views.edit': 'Edit',
'views.viewName': 'View Name',
'views.instances': 'Instances',
@@ -239,7 +240,6 @@ angular.module('ambariAdminConsole')
'views.alerts.cannotEditInstance': 'Cannot Edit Static Instances',
'views.alerts.cannotDeleteStaticInstance': 'Cannot Delete Static Instances',
'views.alerts.deployError': 'Error deploying. Check Ambari Server log.',
- 'views.alerts.unableToCreate': 'Unable to create view instances',
'views.alerts.cannotUseOption': 'This view cannot use this option',
'views.alerts.unableToResetErrorMessage': 'Unable to reset error message for prop: {{key}}',
'views.alerts.instanceCreated': 'Created View Instance {{instanceName}}',
@@ -256,7 +256,12 @@ angular.module('ambariAdminConsole')
'views.alerts.savedRemoteClusterInformation': 'Remote cluster information is saved.',
'views.alerts.credentialsUpdated': 'Credentials Updated.',
- 'urls.name': 'Name',
+ 'views.table.viewType': 'View Type',
+ 'views.emptyTable': 'No Views to display',
+ 'views.createInstance.selectView': 'Select View',
+ 'views.createInstance.selectVersion': 'Select Version',
+ 'views.createInstance.clusterType': 'Cluster Type',
+
'urls.url': 'URL',
'urls.viewUrls': 'View URLs',
'urls.createNewUrl': 'Create New URL',
@@ -267,7 +272,6 @@ angular.module('ambariAdminConsole')
'urls.step1': 'Create URL',
'urls.step2': 'Select instance',
'urls.step3': 'Assign URL',
- 'urls.noUrlsToDisplay': 'No URLs to display.',
'urls.noViewInstances': 'No view instances',
'urls.none': 'None',
'urls.change': 'Change',
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index d2d8253..2cb077a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -93,14 +93,20 @@ angular.module('ambariAdminConsole')
views: {
list: {
url: '/views',
- templateUrl: 'views/ambariViews/listTable.html',
+ templateUrl: 'views/ambariViews/viewsList.html',
controller: 'ViewsListCtrl',
label: 'Views'
},
- listViewUrls: {
- url: '/viewUrls',
- templateUrl: 'views/ambariViews/listUrls.html',
- controller: 'ViewsListCtrl',
+ clone: {
+ url: '/views/:viewId/versions/:version/instances/:instanceId/clone',
+ templateUrl: 'views/ambariViews/create.html',
+ controller: 'CloneViewInstanceCtrl',
+ label: 'Views'
+ },
+ edit: {
+ url: '/views/:viewId/versions/:version/instances/:instanceId/edit',
+ templateUrl: 'views/ambariViews/edit.html',
+ controller: 'ViewsEditCtrl',
label: 'Views'
},
createViewUrl:{
@@ -120,24 +126,6 @@ angular.module('ambariAdminConsole')
templateUrl: 'views/urls/edit.html',
controller: 'ViewUrlEditCtrl',
label: 'Views'
- },
- clone: {
- url: '/views/:viewId/versions/:version/instances/:instanceId/clone',
- templateUrl: 'views/ambariViews/create.html',
- controller: 'CreateViewInstanceCtrl',
- label: 'Views'
- },
- edit: {
- url: '/views/:viewId/versions/:version/instances/:instanceId/edit',
- templateUrl: 'views/ambariViews/edit.html',
- controller: 'ViewsEditCtrl',
- label: 'Views'
- },
- create: {
- url: '/views/:viewId/new',
- templateUrl: 'views/ambariViews/create.html',
- controller: 'CreateViewInstanceCtrl',
- label: 'Views'
}
},
stackVersions: {
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
index f549b29..b38b0c2 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
@@ -61,32 +61,6 @@ angular.module('ambariAdminConsole')
angular.element(this,item);
}
- ViewUrl.all = function(params) {
- var deferred = $q.defer();
-
- $http({
- method: 'GET',
- dataType: "json",
- url: Settings.baseUrl + '/view/urls?'
- + 'ViewUrlInfo/url_name.matches(.*'+params.searchString+'.*)'
- + '&ViewUrlInfo/url_suffix.matches(.*'+params.suffixSearch+'.*)'
- + '&fields=*'
- + '&from=' + (params.currentPage-1)*params.urlsPerPage
- + '&page_size=' + params.urlsPerPage
- + (params.instanceType === '*' ? '' : '&ViewUrlInfo/view_instance_common_name=' + params.instanceType)
-
- })
- .success(function(data) {
- deferred.resolve(new ViewUrl(data));
- })
- .error(function(data) {
- deferred.reject(data);
- });
-
- return deferred.promise;
- };
-
-
ViewUrl.updateShortUrl = function(payload){
var deferred = $q.defer();
@@ -176,7 +150,7 @@ angular.module('ambariAdminConsole')
var versions = {};
angular.forEach(item.versions, function(version) {
versions[version.ViewVersionInfo.version] = {count: version.instances.length, status: version.ViewVersionInfo.status};
- if(version.ViewVersionInfo.status === 'DEPLOYED'){ // if atelast one version is deployed
+ if (version.ViewVersionInfo.status === 'DEPLOYED'){ // if at least one version is deployed
self.canCreateInstance = true;
}
@@ -203,10 +177,6 @@ angular.module('ambariAdminConsole')
return ViewInstance.find(viewName, version, instanceName);
};
- View.allUrls = function(req){
- return ViewUrl.all(req)
- };
-
View.getUrlInfo = function(urlName){
return ViewUrl.urlInfo(urlName);
};
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index 66f23af..bd06bc0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -367,10 +367,6 @@ a.gotoinstance{
width: 14px;
}
-.namefilter {
- font-weight: normal;
-}
-
.settings-edit-toggle.disabled, .properties-toggle.disabled{
color: #999;
cursor: not-allowed;
@@ -480,25 +476,18 @@ a.gotoinstance{
.search-container{
position: relative;
}
-.search-container .close{
+.search-container .close {
position: absolute;
right: 10px;
- top: 32px;
+ top: 8px;
+}
+.search-container input {
+ font-weight: normal;
}
.groups-pane .search-container .close{
top: 32px;
}
-.views-urls-table .search-container .close{
- top: 7px;
- right: 10px;
- z-index: 10;
-}
-.views-list-table .search-container .close{
- right: 50px;
- top: 7px;
- z-index: 10;
-}
.groups-pane table thead th{
border-top: 0;
}
@@ -563,9 +552,7 @@ table.no-border tr td{
.no-border{
border: none !important;
}
-.top-margin-4{
- margin-top: 4px;
-}
+
.table > thead > tr > th.vertical-top{
vertical-align: top;
}
@@ -647,10 +634,14 @@ button.btn.btn-xs{
border-radius: 3px;
}
-a.btn-primary {
+a.btn-primary, a.btn-primary:focus {
color: #fff;
}
+a.btn-default, a.btn-default:focus {
+ color: #666;
+}
+
.clusterDisplayName {
display:inline-block;
width:90%;
@@ -686,6 +677,12 @@ a.alert-link, a.alert-link:hover, a.alert-link:visited{
color: #666;
}
+.empty-table-alert {
+ background-color: #f0f0f0;
+ text-align: center;
+ text-transform: uppercase;
+}
+
.alert-container {
position: fixed;
top: 50px;
@@ -1475,10 +1472,6 @@ legend {
text-overflow: ellipsis;
}
-.pull-right {
- float: right;
-}
-
body {
height: 100%;
background-color: #f0f0f0;
@@ -1498,3 +1491,7 @@ body {
background-color: #fff;
padding: 15px;
}
+
+.navigation-bar-fit-height {
+ z-index: 1001;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
new file mode 100644
index 0000000..9ab66f5
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+.view-instance-actions>a {
+ color: inherit;
+ font-size: 16px;
+ cursor: pointer;
+ padding: 0 5px;
+}
+
+td.view-instance-actions,
+th.view-instance-actions {
+ width: 10%;
+}
+
+.view-instance-actions>a:hover,
+.view-instance-actions>a:visited:hover,
+.view-instance-actions>a:focus:hover {
+ text-decoration: none;
+}
+
+#create-instance-form i {
+ cursor: pointer;
+}
+
+#create-instance-form button.active {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+
+input[type="checkbox"] + label {
+ line-height: 18px;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html
deleted file mode 100644
index 91b9a93..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html
+++ /dev/null
@@ -1,110 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you 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.
--->
-
-<div class="views-list-table">
- <div class="clearfix">
- <ol class="breadcrumb pull-left">
- <li class="active">{{'common.views' | translate}}</li>
- <button ng-click="reloadViews()"
- class="btn btn-xs">
- <i class="glyphicon glyphicon-refresh"></i>
- </button>
- </ol>
- <div class="pull-right col-sm-4">
- <div class="input-group search-container">
- <input type="text" class="form-control search-input" placeholder="{{'common.search' | translate}}" ng-model="viewsFilter" ng-change="getFilteredViews()">
- <button type="button" class="close clear-search" ng-show="viewsFilter" ng-click="viewsFilter=''; getFilteredViews()"><span aria-hidden="true">×</span><span class="sr-only">{{"common.controls.close" | translate}}</span></button>
- <span class="input-group-addon">
- <span class="glyphicon glyphicon-search"></span>
- </span>
- </div>
- </div>
- </div>
- <hr>
- <div class="row">
- <div class="col-sm-3 padding-left-30"><h4>{{'views.viewName' | translate}}</h4></div>
- <div class="col-sm-3"><h4>{{'views.instances' | translate}}</h4></div>
- <div class="col-sm-6"><h4></h4></div>
- </div>
- <accordion close-others="false">
- <accordion-group ng-repeat="view in filteredViews" is-open="view.isOpened">
- <accordion-heading>
- <div class="row">
- <div class="col-sm-4">
- <i class="glyphicon glyphicon-chevron-right" ng-class="{'opened': view.isOpened}"></i>
- {{view.view_name}}
- </div>
- <div class="col-sm-3">
- <span ng-repeat="(version, vData) in view.versions">
- {{version}}
- <span ng-switch="vData.status">
- <span ng-switch-when="PENDING" class="viewstatus pending" ng-switch-when="true" tooltip="{{'views.pending' | translate}}"></span>
- <div class="viewstatus deploying" ng-switch-when="DEPLOYING" tooltip="{{'views.deploying' | translate}}">
- <div class="rect1"></div>
- <div class="rect2"></div>
- <div class="rect3"></div>
- </div>
- <span ng-switch-when="DEPLOYED">({{vData.count}})</span>
- <span ng-switch-when="ERROR" tooltip="{{'views.alerts.deployError' | translate}}"><i class="fa fa-exclamation-triangle"></i></span>
- </span>
- {{$last ? '' : ', '}}
- </span>
- </div>
- <div class="col-sm-6">{{view.description}}</div>
- </div>
- </accordion-heading>
- <table class="table instances-table">
- <tbody>
- <tr ng-repeat="instance in view.instances">
- <td class="col-sm-1"></td>
- <td class="col-sm-5">
- <a href="#/views/{{view.view_name}}/versions/{{instance.ViewInstanceInfo.version}}/instances/{{instance.ViewInstanceInfo.instance_name}}/edit" class="instance-link">{{instance.label}}</a>
- </td>
- <td class="col-sm-5">{{instance.ViewInstanceInfo.version}}</td>
- <td class="col-sm-5 " ><div class="description-column" tooltip="{{instance.ViewInstanceInfo.description}}">{{instance.ViewInstanceInfo.description || 'No description'}}</div>
- </td>
- <td class="col-sm-1">
- <a class="instance-link ng-scope ng-binding" href="#/views/{{view.view_name}}/versions/{{instance.ViewInstanceInfo.version}}/instances/{{instance.ViewInstanceInfo.instance_name}}/clone"><i class="fa fa-copy"></i></a>
- </td>
- <td class="col-sm-1">
- <a class="instance-link ng-scope ng-binding" href ng-click="deleteInstance(instance)"><i class="fa fa-trash-o"></i></a>
- </td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td class="col-sm-4"></td>
- <td class="col-sm-3 padding-left-30">
- <a tooltip="{{view.canCreateInstance ? '' : constants.unable}}" class="btn btn-default createisntance-btn {{view.canCreateInstance ? '' : 'disabled'}}" href ng-click="gotoCreate(view.view_name, view.canCreateInstance);"><span class="glyphicon glyphicon-plus"></span> {{'views.create' | translate}}</a>
- </td>
- <td class="col-sm-3"></td>
- <td class="col-sm-3">
- </td>
- </tr>
- </tfoot>
- </table>
- </accordion-group>
- <div ng-if="isLoadingViews" class="spinner-container">
- <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
- </div>
- <div class="alert alert-info" ng-show="views && !filteredViews.length && !isLoadingViews">
- {{'common.alerts.nothingToDisplay' | translate: '{term: constants.views}'}}
- </div>
-
- </accordion>
-</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html
deleted file mode 100644
index 13ff311..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you 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.
--->
-
-<div class="views-urls-table" data-ng-init="initViewUrls()">
-
-
- <div class="clearfix">
- <ol class="breadcrumb pull-left">
- <li class="active">{{'common.viewUrls' | translate}}</li>
- </ol>
- <div class="pull-right top-margin-4">
- <div class="tooltip-wrapper" tooltip="{{(createUrlDisabled)? ('urls.noViewInstances' | translate) : ''}}">
- <link-to ng-disabled="createUrlDisabled" route="views.createViewUrl" class="btn btn-primary createuser-btn"><span class="glyphicon glyphicon-plus"></span> {{'urls.createNewUrl' | translate}}</link-to>
- </div>
- </div>
- </div>
- <hr>
- <table class="table table-striped table-hover">
- <thead>
- <tr class="fix-bottom">
-
- <th class="fix-bottom col-md-2">
- <span>{{'urls.name' | translate}}</span>
- </th>
- <th class="fix-bottom col-md-3">
- <span>{{'urls.url' | translate}}</span>
- </th>
- <th class="fix-bottom col-md-2">
- <span >{{'urls.view' | translate}}</span>
- </th>
- <th class="fix-bottom col-md-2">
- <span>{{'urls.viewInstance' | translate}}</span>
- </th>
- </tr>
-
- <tr>
-
- <th class="fix-top">
- <div class="search-container">
- <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="urlNameFilter" ng-change="resetPagination()">
- <button type="button" class="close clearfilter" ng-show="urlNameFilter" ng-click="urlNameFilter=''; resetPagination()"><span class="pull-right" aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
- </div>
- </th>
- <th class="fix-top">
- <div class="search-container">
- <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="urlSuffixfilter" ng-change="resetPagination()">
- <button type="button" class="close clearfilter" ng-show="urlSuffixfilter" ng-click="urlSuffixfilter=''; resetPagination()"><span class="pull-right" aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
- </div>
- </th>
- <th class="fix-top">
- <select class="form-control typefilter v-small-input"
- ng-model="instanceTypeFilter"
- ng-options="item.label for item in typeFilterOptions"
- ng-change="resetPagination()">
- </select>
- </th>
- <th class="fix-top">
- </th>
- </tr>
-
- </thead>
- <tbody>
- <tr ng-repeat="url in urls.items">
-
- <td>
- <a href="#/urls/edit/{{url.ViewUrlInfo.url_name}}">{{url.ViewUrlInfo.url_name}}</a>
- </td>
- <td>
- <a target="_blank" href="{{fromSiteRoot('/#/main/view/' + url.ViewUrlInfo.view_instance_common_name + '/' + url.ViewUrlInfo.url_suffix)}}">/main/view/{{url.ViewUrlInfo.view_instance_common_name}}/{{url.ViewUrlInfo.url_suffix}}
- <i class="fa fa-external-link" aria-hidden="true"></i></a>
-
- </td>
- <td>
- <span>{{url.ViewUrlInfo.view_instance_common_name}} {{"{"+url.ViewUrlInfo.view_instance_version+"}"}} </span>
- </td>
- <td>
- <span>{{url.ViewUrlInfo.view_instance_name}}</span>
- </td>
-
- </tr>
- </tbody>
- </table>
- <div ng-if="isLoadingUrls" class="spinner-container">
- <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
- </div>
- <div class="alert alert-info col-sm-12" ng-show="!urls.items.length && !isLoadingUrls">
- {{'urls.noUrlsToDisplay'| translate}}
- </div>
- <div class="col-sm-12 table-bar">
- <div class="pull-left filtered-info">
- <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: urs.urls}'}}</span>
- <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
- </div>
- <div class="pull-right left-margin">
- <pagination class="paginator" total-items="totalUrls" max-size="maxVisiblePages" items-per-page="urlsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
- </div>
- <div class="pull-right">
- <select class="form-control" ng-model="urlsPerPage" ng-change="urlsPerPageChanged()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
- </div>
- </div>
-
-</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
index c5410c1..48757d4 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
@@ -15,110 +15,160 @@
* See the License for the specific language governing permissions and
* limitations under the License.
-->
-<form class="form-horizontal" role="form" name="form.instanceCreateForm" novalidate>
+<form role="form" id="create-instance-form" name="form.instanceCreateForm" novalidate>
<div class="modal-header">
<h3 class="modal-title">{{'views.createViewInstance' | translate}}</h3>
</div>
-<div class="modal-body createViewModal">
- <div class="view-header">
- <img src="http://placehold.it/64x64" alt="" class="icon-big">
- <img src="http://placehold.it/32x32" alt="" class="icon-small">
- <div class="description">
- <h3>{{view.ViewVersionInfo.view_name}}</h3>
- <span>{{view.ViewVersionInfo.label}} | Version: {{view.ViewVersionInfo.version}}</span>
+<div class="modal-body" ng-hide="isLoading">
+
+ <div class="row">
+
+ <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.view.$error.required && form.instanceCreateForm.submitted }">
+ <label for="view">
+ {{'views.createInstance.selectView' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <select
+ class="form-control"
+ id="view"
+ name="view"
+ ng-model="formData.view"
+ ng-change="updateVersionOptions()"
+ ng-options="item.label for item in viewOptions"
+ required>
+ </select>
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.view.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
+
+ <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.version.$error.required && form.instanceCreateForm.submitted }">
+ <label for="version">
+ {{'views.createInstance.selectVersion' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <select
+ class="form-control"
+ id="version"
+ name="version"
+ ng-model="formData.version"
+ ng-options="item.label for item in versionOptions">
+ </select>
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.version.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
</div>
</div>
-
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">{{'common.details' | translate}}</h3>
- </div>
- <div class="panel-body">
- <div class="form-group"
- ng-class="{'has-error' : ( (form.instanceCreateForm.instanceNameInput.$error.required || form.instanceCreateForm.instanceNameInput.$error.pattern) && form.instanceCreateForm.submitted) || instanceExists }"
- >
- <label for="" class="control-labe col-sm-2">{{'views.instanceName' | translate}}</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" name="instanceNameInput" ng-pattern="nameValidationPattern" required ng-model="instance.instance_name">
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.instanceNameInput.$error.required && form.instanceCreateForm.submitted'>
- {{'common.alerts.fieldRequired' | translate}}
- </div>
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.instanceNameInput.$error.pattern && form.instanceCreateForm.submitted'>
- {{'common.alerts.noSpecialChars' | translate}}
- </div>
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='instanceExists'>
- {{'views.alerts.instanceExists' | translate}}
- </div>
- </div>
- </div>
- <div class="form-group"
- ng-class="{'has-error' : ( (form.instanceCreateForm.displayLabel.$error.required || form.instanceCreateForm.displayLabel.$error.pattern) && form.instanceCreateForm.submitted)}">
- <label for="" class="control-labe col-sm-2">{{'common.displayLabel' | translate}}</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" name="displayLabel" ng-model="instance.label" required ng-pattern="nameValidationPattern">
+ <div class="h4">{{'common.details' | translate}}</div>
+ <div class="form-group"
+ ng-class="{ 'has-error': (form.instanceCreateForm.instanceName.$error.required || form.instanceCreateForm.instanceName.$error.pattern || isInstanceExists) && form.instanceCreateForm.submitted }">
+ <label for="instanceName">
+ {{'views.instanceName' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <input type="text" class="form-control"
+ ng-model="formData.instanceName"
+ name="instanceName"
+ id="instanceName"
+ ng-change="checkIfInstanceExist()"
+ ng-pattern="nameValidationPattern" required>
+ <span class="help-block validation-block"
+ ng-show='form.instanceCreateForm.instanceName.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ <span class="help-block validation-block"
+ ng-show='form.instanceCreateForm.instanceName.$error.pattern && form.instanceCreateForm.submitted'>
+ {{'common.alerts.noSpecialChars' | translate}}
+ </span>
+ <span class="help-block validation-block"
+ ng-show='isInstanceExists && form.instanceCreateForm.submitted'>
+ {{'views.alerts.instanceExists' | translate}}
+ </span>
+ </div>
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.displayLabel.$error.required && form.instanceCreateForm.submitted'>
- {{'common.alerts.fieldRequired' | translate}}
- </div>
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.displayLabel.$error.pattern && form.instanceCreateForm.submitted'>
- {{'common.alerts.noSpecialChars' | translate}}
- </div>
- </div>
- </div>
- </div>
- <div class="form-group">
- <div class="col-sm-10 col-sm-offset-2">
- <button class="btn btn-default" ng-click="isAdvancedClosed = !isAdvancedClosed">{{'views.advanced' | translate}}</button>
- </div>
- </div>
- <div collapse="isAdvancedClosed">
- <div class="form-group">
- <div class="col-sm-10 col-sm-offset-2">
- <div class="checkbox">
- <label>
- <input type="checkbox" ng-model='instance.visible'> {{'views.visible' | translate}}
- </label>
- </div>
- </div>
- </div>
- <div class="form-group">
- <div class="col-sm-10 col-sm-offset-2">
- <label for="" class="control-label col-sm-2">{{'views.icon' | translate}}</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" name="iconUrl" ng-model="instance.icon_path">
- </div>
- </div>
- </div>
- <div class="form-group">
- <div class="col-sm-10 col-sm-offset-2">
- <label for="" class="control-label col-sm-2">{{'views.icon64' | translate}}</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" name="icon64Url" ng-model="instance.icon64_path">
- </div>
- </div>
- </div>
- </div>
- </div>
+ <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted }">
+ <label for="displayName">
+ {{'views.displayName' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <input type="text" class="form-control" required
+ name="displayName"
+ ng-model="formData.displayName"
+ id="displayName">
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">{{'views.configuration' | translate}}</h3>
- </div>
- <div class="panel-body">
- <div class="form-group" ng-repeat="parameter in instance.properties"
- ng-class="{'has-error' : (form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted)}" >
- <label for="" class="col-sm-3 control-label">{{parameter.description}}</label>
- <div class="col-sm-9">
- <input type="text" class="form-control" name="{{parameter.name}}" ng-required="parameter.required" ng-model="parameter.value">
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted'>
- {{'common.alerts.fieldRequired' | translate}}
- </div>
- </div>
- </div>
+ <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted }">
+ <label for="description">
+ {{'views.description' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <input type="text" class="form-control" required
+ name="description"
+ ng-model="formData.description"
+ id="description">
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
+
+ <div class="form-group checkbox">
+ <input type="checkbox" class="form-control"
+ name="visible"
+ ng-model="formData.visible"
+ id="visible">
+ <label for="visible">
+ {{'views.visible' | translate}}
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ </div>
+
+ <div class="h4">{{'views.clusterConfiguration' | translate}}</div>
+ <div class="form-group">
+ <label for="clusterType">
+ {{'views.createInstance.clusterType' | translate}}?
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <div>
+ <div class="btn-group" role="group" id="clusterType">
+ <button type="button" class="btn btn-default"
+ ng-class="isLocalTypeChosen && 'active'"
+ ng-click="switchClusterType(true)">
+ {{'common.local' | translate}}
+ </button>
+ <button type="button" class="btn btn-default"
+ ng-class="!isLocalTypeChosen && 'active'"
+ ng-click="switchClusterType(false)">
+ {{'common.remote' | translate}}
+ </button>
</div>
</div>
-
+ </div>
+ <div class="row">
+ <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted }">
+ <label for="clusterName">
+ {{'views.clusterName' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <select
+ required
+ name="clusterName"
+ ng-options="item.label for item in clusterOptions"
+ class="form-control"
+ ng-model="formData.clusterName"
+ id="clusterName">
+ </select>
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
+ </div>
+</div>
+<div ng-if="isLoading" class="spinner-container">
+ <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
</div>
<div class="modal-footer">
<button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html
deleted file mode 100644
index aab526e..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html
+++ /dev/null
@@ -1,138 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you 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.
--->
-
-<div class="modal-header">
- <h3 class="modal-title">{{'views.edit' | translate}} {{instance.ViewInstanceInfo.view_name}}: {{instance.ViewInstanceInfo.label}}</h3>
-</div>
-<div class="modal-body">
- <div class="panel panel-default">
- <div class="panel-heading clearfix">
- <h3 class="panel-title pull-left">{{'views.settings' | translate}}</h3>
- <div class="pull-right">
- <a href ng-click="edit.editSettingsDisabled = !edit.editSettingsDisabled" ng-show="edit.editSettingsDisabled"> <span class="glyphicon glyphicon-cog"></span> {{'views.edit' | translate}}</a>
- </div>
- </div>
- <div class="panel-body">
- <form class="form-horizontal">
- <fieldset ng-disabled="edit.editSettingsDisabled">
- <div class="form-group">
- <label for="" class="col-sm-2 control-label">{{'views.instanceId' | translate}}</label>
- <label for="" class="col-sm-10 control-label text-left">{{instance.ViewInstanceInfo.instance_name}}</label>
- </div>
- <div class="form-group">
- <label for="" class="col-sm-2 control-label">{{'views.displayName' | translate}}</label>
- <div class="col-sm-10"><input type="text" class="form-control" placeholder="{{'views.displayName' | translate}}" ng-model="settings.label"></div>
- </div>
- <div class="form-group">
- <div class="col-sm-offset-2 col-sm-10">
- <div class="checkbox">
- <label>
- <input type="checkbox" ng-model="settings.visible"> {{'views.visible' | translate}}
- </label>
- </div>
- </div>
- </div>
- <div class="form-group" ng-hide="edit.editSettingsDisabled">
- <div class="col-sm-offset-2 col-sm-10">
- <button class="btn btn-default pull-right left-margin" ng-click="cancelSettings()">{{'common.controls.cancel' | translate}}</button>
- <button class="btn btn-primary pull-right" ng-click="saveSettings()">{{'common.controls.save' | translate}}</button>
- </div>
- </div>
- </fieldset>
- </form>
- </div>
- </div>
-
- <div class="panel panel-default views-permissions-panel" style="">
- <div class="panel-heading clearfix">
- <h3 class="panel-title pull-left">{{'views.permissions' | translate}}</h3>
- <div class="pull-right">
- <a href ng-click="edit.editPermissionDisabled = !edit.editPermissionDisabled" ng-show="edit.editPermissionDisabled"> <span class="glyphicon glyphicon-cog"></span> {{'views.edit' | translate}}</a>
- </div>
- </div>
- <div class="panel-body">
- <form class="form-horizontal">
- <div class="form-group">
- <div class="col-sm-2"></div>
- <label class="col-sm-5 control-label text-left">{{'common.users' | translate}}</label>
- <label class="col-sm-5 control-label text-left">{{'common.groups' | translate}}</label>
- </div>
- <div class="form-group" ng-repeat="permission in permissions">
- <label class="col-sm-2 control-label">{{permission.PermissionInfo.permission_name}}</label>
- <div class="col-sm-5" ng-switch="edit.editPermissionDisabled">
- <textarea name="" id="" cols="30" rows="4" class="form-control" ng-model="permissionsEdit[permission.PermissionInfo.permission_name].USER" ng-switch-when="false"></textarea>
- <div class="well" ng-switch-when="true">
- <span ng-repeat="user in permission.USER">
- <link-to route="users.show" id="{{user}}">{{user}}</link-to>
- <button type="button" class="close remove-button"
- ng-click="removePermission(permission.name, 'USER', user)"><span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
- {{$last ? '' :', '}}
- </span>
- </div>
- </div>
- <div class="col-sm-5" ng-switch="edit.editPermissionDisabled">
- <textarea name="" id="" cols="30" rows="4" class="form-control" ng-model="permissionsEdit[permission.PermissionInfo.permission_name].GROUP" ng-switch-when="false"></textarea>
- <div class="well" ng-switch-when="true">
- <span ng-repeat="group in permission.GROUP">
- <link-to route="groups.edit" id="{{group}}" >{{group}}</link-to>
- <button type="button" class="close remove-button"
- ng-click="removePermission(permission.name, 'GROUP', group)"><span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
- {{$last ? '' :', '}}
- </span>
- </div>
- </div>
- </div>
- <div class="form-group" ng-hide="edit.editPermissionDisabled">
- <div class="col-sm-offset-2 col-sm-10">
- <button class="btn btn-default pull-right left-margin" ng-click="cancelPermissions()">{{'common.controls.cancel' | translate}}</button>
- <button class="btn btn-primary pull-right" ng-click="savePermissions()">{{'common.controls.save' | translate}}</button>
- </div>
- </div>
- </form>
-
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading clearfix">
- <h3 class="panel-title pull-left">{{'views.configuration' | translate}}</h3>
- <div class="pull-right">
- <a href ng-click="edit.editConfigurationDisabled = !edit.editConfigurationDisabled" ng-show="edit.editConfigurationDisabled"> <span class="glyphicon glyphicon-cog"></span> {{'views.edit' | translate}}</a>
- </div>
- </div>
- <div class="panel-body">
- <form action="" class="form-horizontal">
- <fieldset ng-disabled="edit.editConfigurationDisabled">
- <div class="form-group" ng-repeat="(propertyName, propertyValue) in configuration">
- <label for="" class="control-label col-sm-3">{{propertyName}}</label>
- <div class="col-sm-9"><input type="text" class="form-control" ng-model="configuration[propertyName]"></div>
- </div>
- <div class="form-group" ng-hide="edit.editConfigurationDisabled">
- <div class="col-sm-offset-2 col-sm-10">
- <button class="btn btn-default pull-right left-margin" ng-click="cancelConfiguration()">{{'common.controls.cancel' | translate}}</button>
- <button class="btn btn-primary pull-right" ng-click="saveConfiguration()">{{'common.controls.save' | translate}}</button>
- </div>
- </div>
- </fieldset>
- </form>
- </div>
- </div>
-</div>
-<div class="modal-footer">
- <button class="btn btn-default" ng-click="close()">{{'common.controls.save' | translate}}</button>
-</div>
[14/51] [abbrv] ambari git commit: AMBARI-22301. HOU: Service desired
repo versions are not being set (ncole)
Posted by nc...@apache.org.
AMBARI-22301. HOU: Service desired repo versions are not being set (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0c6cf814
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0c6cf814
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0c6cf814
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 0c6cf8147d657923fec1c4f5fe8a234117689052
Parents: afb9a66
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Nov 3 16:18:45 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Nov 3 16:18:45 2017 -0400
----------------------------------------------------------------------
.../server/controller/internal/UpgradeResourceProvider.java | 4 ++--
.../controller/internal/UpgradeResourceProviderTest.java | 8 ++++++++
2 files changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/0c6cf814/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index a1ec98a..14b1b86 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -762,11 +762,11 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
The Upgrade Pack is responsible for calling {@link org.apache.ambari.server.serveraction.upgrades.UpdateDesiredRepositoryAction}
at the appropriate moment during the orchestration.
*/
- if (pack.getType() == UpgradeType.ROLLING) {
+ if (pack.getType() == UpgradeType.ROLLING || pack.getType() == UpgradeType.HOST_ORDERED) {
s_upgradeHelper.updateDesiredRepositoriesAndConfigs(upgradeContext);
}
- @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES, comment = "This is wrong")
+ @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES, comment = "This is SO VERY wrong")
StackId configurationPackSourceStackId = upgradeContext.getSourceVersions().values().iterator().next().getStackId();
// resolve or build a proper config upgrade pack - always start out with the config pack
http://git-wip-us.apache.org/repos/asf/ambari/blob/0c6cf814/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
index d6b1ab3..64d416f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
@@ -1443,6 +1443,14 @@ public class UpgradeResourceProviderTest extends EasyMockSupport {
requestProps.put(UpgradeResourceProvider.UPGRADE_HOST_ORDERED_HOSTS, hostsOrder);
upgradeResourceProvider.createResources(request);
+
+
+ // make sure that the desired versions are updated
+ Cluster cluster = clusters.getCluster("c1");
+ assertNotNull(cluster);
+
+ Service service = cluster.getService("ZOOKEEPER");
+ assertEquals(repoVersionEntity2200, service.getDesiredRepositoryVersion());
}
/**
[40/51] [abbrv] ambari git commit: AMBARI-22386 - Patch Upgrades
Broken For Clients Due To Versioned LD Library (jonathanhurley)
Posted by nc...@apache.org.
AMBARI-22386 - Patch Upgrades Broken For Clients Due To Versioned LD Library (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/feccebcb
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/feccebcb
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/feccebcb
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: feccebcb9b4cf56d8ea0cc021d5250a711f37596
Parents: c693de3
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Nov 8 16:20:30 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Nov 9 16:36:49 2017 -0500
----------------------------------------------------------------------
.../TEZ/0.9.0.3.0/configuration/tez-site.xml | 2 +-
.../configuration-mapred/mapred-site.xml | 2 +-
.../configuration-mapred/mapred-site.xml | 2 +-
.../2.2/services/TEZ/configuration/tez-site.xml | 4 ++--
.../YARN/configuration-mapred/mapred-site.xml | 2 +-
.../resources/stacks/HDP/2.6/repos/repoinfo.xml | 2 +-
.../stacks/HDP/2.6/upgrades/config-upgrade.xml | 23 ++++++++++++++++++++
.../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml | 9 ++++++++
.../stacks/HDP/2.6/upgrades/upgrade-2.6.xml | 4 ++++
.../YARN/configuration-mapred/mapred-site.xml | 2 +-
10 files changed, 44 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
index 5c17044..58558af 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
@@ -78,7 +78,7 @@
</property>
<property>
<name>tez.am.launch.env</name>
- <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+ <value>LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
<description>
Additional execution environment entries for tez. This is not an additive property. You must preserve the original value if
you want to have access to native libraries.
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
index a7d8cd6..3438c45 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
@@ -438,7 +438,7 @@
</property>
<property>
<name>mapreduce.admin.user.env</name>
- <value>LD_LIBRARY_PATH={{hadoop_lib_home}}/native/Linux-{{architecture}}-64</value>
+ <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:{{hadoop_lib_home}}/native/Linux-{{architecture}}-64</value>
<description>
Additional execution environment entries for map and reduce task processes.
This is not an additive property. You must preserve the original value if
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
index 705763f..882cf83 100644
--- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
@@ -438,7 +438,7 @@
</property>
<property>
<name>mapreduce.admin.user.env</name>
- <value>LD_LIBRARY_PATH=/usr/lib/hadoop/lib/native:/usr/lib/hadoop/lib/native/Linux-amd64-64</value>
+ <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:/usr/lib/hadoop/lib/native:/usr/lib/hadoop/lib/native/Linux-amd64-64</value>
<description>
Additional execution environment entries for map and reduce task processes.
This is not an additive property. You must preserve the original value if
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
index 1427a6f..4ffb7a4 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
@@ -78,7 +78,7 @@
</property>
<property>
<name>tez.am.launch.env</name>
- <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+ <value>LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
<description>
Additional execution environment entries for tez. This is not an additive property. You must preserve the original value if
you want to have access to native libraries.
@@ -124,7 +124,7 @@
</property>
<property>
<name>tez.task.launch.env</name>
- <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+ <value>LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
<description>
Additional execution environment entries for tez. This is not an additive property. You must preserve the original value if
you want to have access to native libraries.
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
index 4ad08ce..084e912 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
@@ -20,7 +20,7 @@
<configuration xmlns:xi="http://www.w3.org/2001/XInclude" supports_final="true">
<property>
<name>mapreduce.admin.user.env</name>
- <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+ <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
<description>
Additional execution environment entries for map and reduce task processes.
This is not an additive property. You must preserve the original value if
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
index ff132aa..eb0b0ef 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
@@ -33,7 +33,7 @@
</os>
<os family="redhat-ppc7">
<repo>
- <baseurl>http://public-repo-1.hortonworks.com/HDP/centos7/2.x/updates/2.6.0.3</baseurl>
+ <baseurl>http://public-repo-1.hortonworks.com/HDP/centos7-ppc/2.x/updates/2.6.0.3</baseurl>
<repoid>HDP-2.6</repoid>
<reponame>HDP</reponame>
<unique>true</unique>
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
index 63624d6..45b1707 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
@@ -258,5 +258,28 @@
</component>
</service>
+ <service name="TEZ">
+ <component name="TEZ_CLIENT">
+ <changes>
+ <definition xsi:type="configure" id="hdp_2_6_tez_tarball_ld_library">
+ <type>tez-site</type>
+ <set key="tez.am.launch.env" value="LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64"/>
+ <set key="tez.task.launch.env" value="LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64"/>
+ </definition>
+ </changes>
+ </component>
+ </service>
+
+ <service name="MAPREDUCE2">
+ <component name="MAPREDUCE2_CLIENT">
+ <changes>
+ <definition xsi:type="configure" id="hdp_2_6_mapreduce_tarball_ld_library">
+ <type>mapred-site</type>
+ <set key="mapreduce.admin.user.env" value="LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:{{hadoop_lib_home}}/native/Linux-{{architecture}}-64"/>
+ </definition>
+ </changes>
+ </component>
+ </service>
+
</services>
</upgrade-config-changes>
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
index c9e90a9..ae2a855 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
@@ -409,6 +409,15 @@
</task>
</execute-stage>
+ <!-- TEZ -->
+ <execute-stage service="TEZ" component="TEZ_CLIENT" title="Updating LD Library Classpath for Tarball" >
+ <task xsi:type="configure" id="hdp_2_6_tez_tarball_ld_library" supports-patch="true"/>
+ </execute-stage>
+
+ <!-- MapR -->
+ <execute-stage service="MAPREDUCE2" component="MAPREDUCE2_CLIENT" title="Updating LD Library Classpath for Tarball">
+ <task xsi:type="configure" id="hdp_2_6_mapreduce_tarball_ld_library" supports-patch="true"/>
+ </execute-stage>
</group>
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
index 176143c..37847a2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
@@ -675,6 +675,8 @@
<task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.FixLzoCodecPath">
<summary>Verifying LZO codec path for mapreduce</summary>
</task>
+
+ <task xsi:type="configure" id="hdp_2_6_mapreduce_tarball_ld_library" supports-patch="true"/>
</pre-upgrade>
<pre-downgrade copy-upgrade="true" />
@@ -757,6 +759,8 @@
<task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.FixLzoCodecPath">
<summary>Verifying LZO codec path for Tez</summary>
</task>
+
+ <task xsi:type="configure" id="hdp_2_6_tez_tarball_ld_library" supports-patch="true"/>
</pre-upgrade>
<pre-downgrade copy-upgrade="true" />
http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
index 6ce4d72..489754f 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
@@ -31,7 +31,7 @@
<!-- These configs were inherited from HDP 2.2 -->
<property>
<name>mapreduce.admin.user.env</name>
- <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+ <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
<description>
Additional execution environment entries for map and reduce task processes.
This is not an additive property. You must preserve the original value if
[34/51] [abbrv] ambari git commit: AMBARI-22388 Log Search UI:
restyle logs list. (Istvan Tobias via ababiichuk)
Posted by nc...@apache.org.
AMBARI-22388 Log Search UI: restyle logs list. (Istvan Tobias via ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/38476f7a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/38476f7a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/38476f7a
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 38476f7a1a7a371fd0f57af2f931427f1e276d27
Parents: 5f714ce
Author: Istvan Tobias <to...@gmail.com>
Authored: Thu Nov 9 13:24:16 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Thu Nov 9 13:24:16 2017 +0200
----------------------------------------------------------------------
.../ambari-logsearch-web/src/app/app.module.ts | 4 +
.../log-level/log-level.component.html | 18 +++
.../log-level/log-level.component.spec.ts | 73 +++++++++++
.../components/log-level/log-level.component.ts | 52 ++++++++
.../log-message/log-message.component.html | 24 ++++
.../log-message/log-message.component.less | 69 ++++++++++
.../log-message/log-message.component.spec.ts | 64 +++++++++
.../log-message/log-message.component.ts | 129 ++++++++++++++++++
.../logs-list/logs-list.component.html | 92 +++++++------
.../logs-list/logs-list.component.less | 130 +++++++++----------
.../ambari-logsearch-web/webpack.config.js | 15 ++-
11 files changed, 550 insertions(+), 120 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index 488437e..56562df 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -68,6 +68,8 @@ import {FilterButtonComponent} from '@app/components/filter-button/filter-button
import {AccordionPanelComponent} from '@app/components/accordion-panel/accordion-panel.component';
import {CollapsiblePanelComponent} from '@app/components/collapsible-panel/collapsible-panel.component';
import {LogsListComponent} from '@app/components/logs-list/logs-list.component';
+import {LogMessageComponent} from '@app/components/log-message/log-message.component';
+import {LogLevelComponent} from '@app/components/log-level/log-level.component';
import {DropdownButtonComponent} from '@app/components/dropdown-button/dropdown-button.component';
import {PaginationComponent} from '@app/components/pagination/pagination.component';
import {PaginationControlsComponent} from '@app/components/pagination-controls/pagination-controls.component';
@@ -121,6 +123,8 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
AccordionPanelComponent,
CollapsiblePanelComponent,
LogsListComponent,
+ LogLevelComponent,
+ LogMessageComponent,
DropdownButtonComponent,
PaginationComponent,
PaginationControlsComponent,
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html
new file mode 100644
index 0000000..d72c9d33
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html
@@ -0,0 +1,18 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<i class="fa {{cssClass}}"></i>
+{{logEntry.level}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts
new file mode 100644
index 0000000..c13d373
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+import {DebugElement} from '@angular/core';
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {LogLevelComponent} from './log-level.component';
+import {By} from '@angular/platform-browser';
+
+describe('LogLevelComponent', () => {
+ let component: LogLevelComponent;
+ let fixture: ComponentFixture<LogLevelComponent>;
+ let de: DebugElement;
+ let el: HTMLElement;
+ let logLevelMap = {
+ warn: 'fa-exclamation-triangle',
+ fatal: 'fa-exclamation-circle',
+ error: 'fa-exclamation-circle',
+ info: 'fa-info-circle',
+ debug: 'fa-bug',
+ trace: 'fa-random',
+ unknown: 'fa-question-circle'
+ };
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ LogLevelComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LogLevelComponent);
+ component = fixture.componentInstance;
+ component.logEntry = {level: 'unknown'};
+ fixture.detectChanges();
+ de = fixture.debugElement.query(By.css('i.fa'));
+ el = de.nativeElement;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ Object.keys(logLevelMap).forEach((level) => {
+ describe(level, () => {
+ beforeEach(() => {
+ component.logEntry = {level: level};
+ fixture.detectChanges();
+ });
+ it(`should return with the ${logLevelMap[level]} css class for ${level} log level`, () => {
+ expect(component.cssClass).toEqual(logLevelMap[level]);
+ });
+ it(`should set the ${logLevelMap[level]} css class on the icon element`, () => {
+ expect(el.classList).toContain(logLevelMap[level]);
+ });
+ });
+ });
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts
new file mode 100644
index 0000000..8542770
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+import {Component, Input} from '@angular/core';
+
+/**
+ * This is a simple UI component to display the log message. The goal is to be able to show one line and be collapsile
+ * to show the full log message with new lines.
+ * @class LogMessageComponent
+ */
+@Component({
+ selector: 'log-level',
+ templateUrl: './log-level.component.html',
+ styleUrls: []
+})
+export class LogLevelComponent {
+
+ /**
+ * This is the log entry object
+ * @type {object}
+ */
+ @Input()
+ logEntry: any;
+
+ private classMap: object = {
+ warn: 'fa-exclamation-triangle',
+ fatal: 'fa-exclamation-circle',
+ error: 'fa-exclamation-circle',
+ info: 'fa-info-circle',
+ debug: 'fa-bug',
+ trace: 'fa-random',
+ unknown: 'fa-question-circle'
+ };
+
+ get cssClass() {
+ return this.classMap[((this.logEntry && this.logEntry.level) || 'unknown').toLowerCase()];
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html
new file mode 100644
index 0000000..d4c2902
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html
@@ -0,0 +1,24 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<div [ngClass]="{
+ 'log-message-container': true,
+ 'log-message-container-collapsible': addCaret,
+ 'log-message-container-open': isOpen
+ }">
+ <button *ngIf="addCaret" (click)="onCaretClick($event)"><i class="caret"></i></button>
+ <div #content class="log-message-content"><ng-content></ng-content></div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less
new file mode 100644
index 0000000..602d7bd
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+@import '../variables';
+:host {
+ .log-message-container {
+ display: block;
+ margin: 0;
+ padding: 0;
+
+ .caret {
+ margin-top: -3px;
+ transition: transform 250ms;
+ transform: rotate(-90deg);
+ }
+ &.log-message-container-open .caret {
+ transform: rotate(0deg);
+ }
+
+ .log-message-content {
+ max-height: calc(20em/14); // from Bootstrap
+ overflow: hidden;
+ padding-left: 1em;
+ position: relative;
+ }
+ &.log-message-container-open .log-message-content {
+ max-height: none;
+ white-space: pre-wrap;
+ &:before {
+ display: none;
+ }
+ }
+ &.log-message-container-collapsible {
+ .log-message-content {
+ padding-left: 0;
+ &:before {
+ content: "...";
+ float: right;
+ margin-left: 1em;
+ }
+ }
+
+ }
+
+ button, button:active {
+ background: none transparent;
+ border: none transparent;
+ color: @base-font-color;
+ cursor: pointer;
+ float: left;
+ height: 1em;
+ outline: none;
+ padding: 0 .15em;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts
new file mode 100644
index 0000000..edc2515
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {LogMessageComponent} from './log-message.component';
+
+describe('LogMessageComponent', () => {
+ let component: LogMessageComponent;
+ let fixture: ComponentFixture<LogMessageComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ LogMessageComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LogMessageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('event handler should call the toggleOpen method', () => {
+ let mockEvent: MouseEvent = document.createEvent('MouseEvent');
+ mockEvent.initEvent('click', true, true);
+ spyOn(component,'toggleOpen');
+ component.onCaretClick(mockEvent);
+ expect(component.toggleOpen).toHaveBeenCalled();
+ });
+
+ it('event handler should prevent the default behaviour of the action', () => {
+ let mockEvent: MouseEvent = document.createEvent('MouseEvent');
+ mockEvent.initEvent('click', true, true);
+ spyOn(mockEvent,'preventDefault');
+ component.onCaretClick(mockEvent);
+ expect(mockEvent.preventDefault).toHaveBeenCalled();
+ });
+
+ it('calling the toggleOpen method should negate the isOpen property', () => {
+ let currentState = component.isOpen;
+ component.toggleOpen();
+ expect(component.isOpen).toEqual(!currentState);
+ });
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts
new file mode 100644
index 0000000..b8be61b
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts
@@ -0,0 +1,129 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+import {Component, Input, AfterViewInit, ElementRef, ViewChild, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef} from '@angular/core';
+
+/**
+ * This is a simple UI component to display the log message. The goal is to be able to show one line and be collapsile
+ * to show the full log message with new lines.
+ * @class LogMessageComponent
+ */
+@Component({
+ selector: 'log-message',
+ templateUrl: './log-message.component.html',
+ styleUrls: ['./log-message.component.less']
+})
+export class LogMessageComponent implements AfterViewInit, OnChanges {
+
+ /**
+ * This is the element reference to the message log container element. So that we can calculate if the caret should be
+ * displayed or not.
+ * @type ElementRef
+ */
+ @ViewChild('content') content: ElementRef;
+
+ /**
+ * This is the flag property to indicate if the content container is open or not.
+ * @type {boolean}
+ */
+ @Input()
+ isOpen: boolean = false;
+
+ /**
+ * This is a helper property to handle the changes on the parent component. The goal of this input is to be able to
+ * react when the parent component (currently the log-list component) has changed (its size) in a way that the
+ * LogMessageComponent should check if the caret should be visible or not.
+ */
+ @Input()
+ listenChangesOn: any;
+
+ /**
+ * This is a private flag to check if it should display the caret or not, it depends on the size of the size of
+ * the content container element. Handled by the @checkAddCaret method
+ * @type {boolean}
+ */
+ private addCaret: boolean = false;
+
+ /**
+ * This is a primary check if the message content does contain new line (/n) characters. If so than we display the
+ * caret to give a possibility to the user to see the message as it is (pre-wrapped).
+ * @type {boolean}
+ */
+ private isMultiLineMessage: boolean = false;
+
+ constructor(private cdRef:ChangeDetectorRef) {}
+
+ /**
+ * This change handler's goal is to check if we should add the caret or not. Mainly it is because currently we have
+ * the LogListComponent where columns can be added or removed and we have to recheck the visibility of the caret every
+ * changes of the displayed columns.
+ * @param {SimpleChanges} changes
+ */
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.listenChangesOn !== undefined) {
+ this.checkAddCaret();
+ }
+ }
+
+ /**
+ * The goal is to perform a initial caret display check when the component has been initialized.
+ */
+ ngAfterViewInit(): void {
+ let text = this.content.nativeElement.textContent;
+ let newLinePos = text.indexOf('\n');
+ this.isMultiLineMessage = ((text.length - 1) > newLinePos) && (newLinePos > 0);
+ this.checkAddCaret();
+ }
+
+ /**
+ * Since the size of the column is depends on the window size we have to listen the resize event and show/hide the
+ * caret corresponding the new size of the content container element.
+ * Using the arrow function will keep the instance scope.
+ */
+ @HostListener('window:resize', ['$event'])
+ onWindowResize = (): void => {
+ this.isMultiLineMessage || this.checkAddCaret();
+ };
+
+ /**
+ * The goal is to perform a height check on the content container element. It is based on the comparison of the
+ * scrollHeight and the clientHeight.
+ */
+ checkAddCaret = (): void => {
+ let el = this.content.nativeElement;
+ this.addCaret = this.isMultiLineMessage || (el.scrollHeight > el.clientHeight);
+ this.cdRef.detectChanges();
+ };
+
+ /**
+ * This is the click event handler of the caret button element. It will only toggle the isOpen property so that the
+ * component element css classes will follow its state.
+ * @param ev {MouseEvent}
+ */
+ onCaretClick(ev:MouseEvent) {
+ ev.preventDefault();
+ this.toggleOpen();
+ }
+
+ /**
+ * This is a simple property toggle method of the @isOpen property.
+ * The goal is to separate this logic from the event handling and give a way to call it from anywhere.
+ */
+ toggleOpen():void {
+ this.isOpen = !this.isOpen;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
index 1e0f49c..10f4af1 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
@@ -20,46 +20,54 @@
[defaultLabel]="filters.sorting.defaultLabel" [isRightAlign]="true"
class="col-md-12"></filter-dropdown>
</form>
-<div *ngFor="let log of logs; let i = index" class="row">
- <div class="logs-header col-md-12"
- *ngIf="!isServiceLogsFileView && (i === 0 || isDifferentDates(log.logtime, logs[i - 1].logtime))">
- <div class="col-md-12">{{log.logtime | amTz: timeZone | amDateFormat: dateFormat}}</div>
- </div>
- <accordion-panel *ngIf="!isServiceLogsFileView" [toggleId]="'details-' + i" class="col-md-12">
- <ng-template>
- <div *ngIf="isColumnDisplayed('level')" [ngClass]="'hexagon ' + (log.level ? log.level.toLowerCase() : '')"></div>
- <div class="col-md-1">
- <dropdown-button iconClass="fa fa-ellipsis-h" [hideCaret]="true" [options]="logActions"
- [additionalArgs]="[log]"></dropdown-button>
- </div>
- <div *ngIf="isColumnDisplayed('level')" [ngClass]="'col-md-1 log-status ' + (log.level ? log.level.toLowerCase() : '')">
- {{log.level}}
- </div>
- <div *ngIf="isColumnDisplayed('type') || isColumnDisplayed('logtime')" class="col-md-3">
- <div *ngIf="isColumnDisplayed('type')" class="log-type">{{log.type}}</div>
- <time *ngIf="isColumnDisplayed('logtime')" class="log-time">
- {{log.logtime | amTz: timeZone | amDateFormat: timeFormat}}
- </time>
- </div>
- <div class="col-md-6 log-content-wrapper">
- <div class="collapse log-actions" attr.id="details-{{i}}">
- <!-- TODO remove after restyling the table -->
- </div>
- <div class="log-content-inner-wrapper">
- <div class="log-content" *ngIf="isColumnDisplayed('log_message')"
- (contextmenu)="openMessageContextMenu($event)">{{log.log_message}}</div>
- </div>
- </div>
- <div *ngFor="let column of displayedColumns">
- <div *ngIf="customStyledColumns.indexOf(column.name) === -1" [innerHTML]="log[column.name]"
- class="col-md-1"></div>
- </div>
- </ng-template>
- </accordion-panel>
- <log-file-entry *ngIf="isServiceLogsFileView" [time]="log.logtime" [level]="log.level"
- [fileName]="log.file" [lineNumber]="log.line_number" [message]="log.log_message"></log-file-entry>
+<div class="panel panel-default">
+ <div class="panel-body">
+ <table class="table table-hover">
+ <tbody>
+ <ng-container *ngFor="let log of logs; let i = index">
+ <tr *ngIf="!isServiceLogsFileView && (i === 0 || isDifferentDates(log.logtime, logs[i - 1].logtime))"
+ class="log-date-row" >
+ <th attr.colspan="{{displayedColumns.length + 1}}">
+ {{log.logtime | amTz: timeZone | amDateFormat: dateFormat}}
+ </th>
+ </tr>
+ <tr class="log-item-row">
+ <td class="log-action">
+ <dropdown-button iconClass="fa fa-ellipsis-h action" [hideCaret]="true" [options]="logActions"
+ [additionalArgs]="[log]"></dropdown-button>
+ </td>
+ <td *ngIf="isColumnDisplayed('logtime')" class="log-time">
+ <time>
+ {{log.logtime | amTz: timeZone | amDateFormat: timeFormat}}
+ </time>
+ </td>
+ <td *ngIf="isColumnDisplayed('level')" [ngClass]="'log-level ' + log.level.toLowerCase()">
+ <log-level [logEntry]="log"></log-level>
+ </td>
+ <td *ngIf="isColumnDisplayed('type')" [ngClass]="'log-type'">
+ {{log.type}}
+ </td>
+ <td *ngIf="isColumnDisplayed('log_message')" [ngClass]="'log-message'" width="*"
+ (contextmenu)="openMessageContextMenu($event)">
+ <log-message [listenChangesOn]="displayedColumns">{{log.log_message}}</log-message>
+ </td>
+ <ng-container *ngFor="let column of displayedColumns">
+ <td *ngIf="customStyledColumns.indexOf(column.name) === -1"
+ [ngClass]="'log-' + column.name">{{log[column.name]}}</td>
+ </ng-container>
+ </tr>
+ </ng-container>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td attr.colspan="{{displayedColumns.length + 1}}">
+ <pagination class="col-md-12" *ngIf="logs && logs.length" [totalCount]="totalCount"
+ [filtersForm]="filtersForm" [filterInstance]="filters.pageSize" [currentCount]="logs.length"></pagination>
+ </td>
+ </tr>
+ </tfoot>
+ </table>
+ <ul #contextmenu data-component="dropdown-list" class="dropdown-menu context-menu" [items]="contextMenuItems"
+ (selectedItemChange)="updateQuery($event)"></ul>
+ </div>
</div>
-<ul #contextmenu *ngIf="!isServiceLogsFileView" data-component="dropdown-list" class="dropdown-menu context-menu"
- [items]="contextMenuItems" (selectedItemChange)="updateQuery($event)"></ul>
-<pagination class="pull-right" *ngIf="logs && logs.length" [totalCount]="totalCount" [filtersForm]="filtersForm"
- [filterInstance]="filters.pageSize" [currentCount]="logs.length"></pagination>
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
index 67d0615..c5c4c5a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
@@ -17,93 +17,81 @@
@import '../mixins';
-.logs-header {
- // TODO get rid of magic numbers, base on actual design
- margin: 10px 0;
- padding: 5px 0;
- background-color: @list-header-background-color; // TODO implement actual color
- overflow: hidden;
-}
-
-/deep/ filter-dropdown {
- justify-content: flex-end;
-}
-
-.hexagon {
- // TODO remove, since it's not a part of updated design
- left: -7.5px;
-
- &.fatal {
- .common-hexagon(15px, @fatal-color);
- }
-
- &.error {
- .common-hexagon(15px, @error-color);
+:host {
+ /deep/ filter-dropdown {
+ justify-content: flex-end;
}
- &.warn {
- .common-hexagon(15px, @warning-color);
+ .panel-body {
+ overflow: hidden;
+ width: 100%;
}
- &.info {
- .common-hexagon(15px, @info-color);
+ table {
+ width: 100%;
}
- &.debug {
- .common-hexagon(15px, @debug-color);
+ tr.log-date-row, tr.log-date-row:hover {
+ background: @list-header-background-color;
+ border: none transparent;
+ th {
+ border: none transparent;
+ }
}
-
- &.trace {
- .common-hexagon(15px, @trace-color);
+ tr.log-item-row td {
+ background: none transparent;
}
- &.unknown {
- .common-hexagon(15px, @unknown-color);
+ td {
+ &.log-action {
+ min-width: 3em;
+ /deep/ .btn, /deep/ .filter-label {
+ font-size: 1em;
+ height: auto;
+ line-height: 1em;
+ padding: 0;
+ }
+ }
+ &.log-time {
+ color: @grey-color;
+ min-width: 7em;
+ text-align: right;
+ }
+ &.log-level {
+ text-transform: uppercase;
+ min-width: 8em;
+ .log-colors;
+ }
+ &.log-type {
+ color: @link-color;
+ }
+ &.log-message, &.log-path {
+ width: 100%;
+ }
}
-}
-
-.log-status {
- text-transform: uppercase;
- .log-colors;
-}
-
-.log-type {
- color: @link-color;
-}
-
-.log-time {
- color: @grey-color;
-}
-
-.log-content-wrapper {
- position: relative;
- // TODO get rid of magic numbers, base on actual design
- .log-content-inner-wrapper {
- overflow: hidden;
- max-height: @default-line-height * 2em;
- padding-right: 65px;
-
- .log-content {
- white-space: pre-wrap;
+ tr:hover td.log-action {
+ /deep/ .btn {
+ display: inline-block;
}
}
- .log-actions {
- &.collapsing + .log-content-inner-wrapper, &.collapse.in + .log-content-inner-wrapper {
- min-height: 6em;
- max-height: none;
- overflow-x: auto;
+ .table.table-hover>tbody>tr{
+ box-sizing: border-box;
+ border-width: 1px;
+ >td {
+ border-top: 0 none;
}
-
- .action-icon {
- .clickable-item;
- display: block;
- padding: 5px;
+ &:first-of-type {
+ border-top-color: transparent;
+ }
+ &:last-of-type {
+ border-bottom-color: transparent;
}
}
-}
-.context-menu {
- position: fixed;
+ .context-menu {
+ position: fixed;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/webpack.config.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/webpack.config.js b/ambari-logsearch/ambari-logsearch-web/webpack.config.js
index 7a60df2..75d6aee 100644
--- a/ambari-logsearch/ambari-logsearch-web/webpack.config.js
+++ b/ambari-logsearch/ambari-logsearch-web/webpack.config.js
@@ -81,18 +81,17 @@ module.exports = {
"resolve": {
"extensions": [
".ts",
- ".js"
+ ".js",
+ ".less"
],
"modules": [
- "./node_modules",
- "./node_modules"
+ "node_modules"
],
"symlinks": true
},
"resolveLoader": {
"modules": [
- "./node_modules",
- "./node_modules"
+ "node_modules"
]
},
"entry": {
@@ -229,7 +228,9 @@ module.exports = {
"loader": "less-loader",
"options": {
"sourceMap": false,
- "paths": []
+ "paths": [
+ "./node_modules"
+ ]
}
}
]
@@ -359,7 +360,7 @@ module.exports = {
"loader": "less-loader",
"options": {
"sourceMap": false,
- "paths": []
+ "paths": ["./node_modules"]
}
}
]
[30/51] [abbrv] ambari git commit: AMBARI-22379 :
get_phoenix_query_server_hosts is undefined in hbase service_advisor. (Ted Yu
via avijayan)
Posted by nc...@apache.org.
AMBARI-22379 : get_phoenix_query_server_hosts is undefined in hbase service_advisor. (Ted Yu via avijayan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b04e142b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b04e142b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b04e142b
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: b04e142b3f80d4713ed154e17c0ab877d46500a4
Parents: 08d3826
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Wed Nov 8 11:14:54 2017 -0800
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Wed Nov 8 11:14:54 2017 -0800
----------------------------------------------------------------------
.../common-services/HBASE/2.0.0.3.0/service_advisor.py | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b04e142b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
index f9d1a59..9dc5708 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
@@ -461,6 +461,16 @@ class HBASERecommender(service_advisor.ServiceAdvisor):
else:
putHbaseSiteProperty('hbase.master.ui.readonly', 'false')
+ """
+ Returns the list of Phoenix Query Server host names, or None.
+ """
+ def get_phoenix_query_server_hosts(self, services, hosts):
+ if len(hosts['items']) > 0:
+ phoenix_query_server_hosts = self.getHostsWithComponent("HBASE", "PHOENIX_QUERY_SERVER", services, hosts)
+ if phoenix_query_server_hosts is None:
+ return []
+ return [host['Hosts']['host_name'] for host in phoenix_query_server_hosts]
+
def recommendHBASEConfigurationsFromHDP26(self, configurations, clusterData, services, hosts):
if 'hbase-env' in services['configurations'] and 'hbase_user' in services['configurations']['hbase-env']['properties']:
@@ -672,4 +682,4 @@ class HBASEValidator(service_advisor.ServiceAdvisor):
" {0} needs to contain {1} instead of {2}".format(prop_name,prop_val,exclude_val))})
validationProblems = self.toConfigurationValidationProblems(validationItems, "hbase-site")
- return validationProblems
\ No newline at end of file
+ return validationProblems
[51/51] [abbrv] ambari git commit: Merge branch 'trunk' into
branch-feature-AMBARI-21674
Posted by nc...@apache.org.
Merge branch 'trunk' into branch-feature-AMBARI-21674
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ff8f686f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ff8f686f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ff8f686f
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: ff8f686f85e7a97f1fee87646686b02b296a5481
Parents: c839dbf 6e706d4
Author: Nate Cole <nc...@hortonworks.com>
Authored: Mon Nov 13 11:56:52 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Nov 13 11:56:52 2017 -0500
----------------------------------------------------------------------
ambari-admin/pom.xml | 2 +-
.../app/assets/fonts/Roboto-Regular-webfont.eot | Bin 0 -> 79547 bytes
.../app/assets/fonts/Roboto-Regular-webfont.svg | 7606 ++++++++++++++++++
.../app/assets/fonts/Roboto-Regular-webfont.ttf | Bin 0 -> 234464 bytes
.../assets/fonts/Roboto-Regular-webfont.woff | Bin 0 -> 105700 bytes
.../main/resources/ui/admin-web/app/index.html | 82 +-
.../app/scripts/controllers/AppCtrl.js | 177 +
.../controllers/ClusterInformationCtrl.js | 65 +
.../app/scripts/controllers/NavbarCtrl.js | 106 -
.../app/scripts/controllers/SideNavCtrl.js | 68 +
.../ambariViews/CloneViewInstanceCtrl.js | 274 +
.../ambariViews/CreateViewInstanceCtrl.js | 353 +-
.../controllers/ambariViews/ViewsListCtrl.js | 360 +-
.../controllers/clusters/ExportBlueprintCtrl.js | 58 -
.../app/scripts/controllers/mainCtrl.js | 183 -
.../ui/admin-web/app/scripts/i18n.config.js | 38 +-
.../ui/admin-web/app/scripts/routes.js | 134 +-
.../ui/admin-web/app/scripts/services/View.js | 32 +-
.../app/scripts/theme/bootstrap-ambari.js | 269 +
.../app/styles/cluster-information.css | 59 +
.../resources/ui/admin-web/app/styles/main.css | 566 +-
.../app/styles/theme/bootstrap-ambari.css | 1518 ++++
.../ui/admin-web/app/styles/top-nav.css | 197 +
.../resources/ui/admin-web/app/styles/views.css | 49 +
.../app/views/ambariViews/listTable.html | 110 -
.../app/views/ambariViews/listUrls.html | 117 -
.../app/views/ambariViews/modals/create.html | 238 +-
.../app/views/ambariViews/modals/edit.html | 138 -
.../app/views/ambariViews/viewsList.html | 134 +
.../admin-web/app/views/clusterInformation.html | 66 +
.../app/views/clusters/exportBlueprint.html | 40 -
.../ui/admin-web/app/views/groups/list.html | 7 +-
.../ui/admin-web/app/views/leftNavbar.html | 126 -
.../resources/ui/admin-web/app/views/main.html | 96 -
.../app/views/remoteClusters/list.html | 6 +-
.../ui/admin-web/app/views/sideNav.html | 113 +
.../admin-web/app/views/stackVersions/list.html | 8 +-
.../ui/admin-web/app/views/urls/create.html | 4 +-
.../ui/admin-web/app/views/urls/edit.html | 4 +-
.../ui/admin-web/app/views/users/list.html | 7 +-
.../src/main/resources/ui/admin-web/bower.json | 2 +-
.../src/main/resources/ui/admin-web/gulpfile.js | 10 +-
.../main/resources/ui/admin-web/package.json | 6 +-
.../test/unit/controllers/AppCtrl_test.js | 211 +
.../unit/controllers/CloneViewInstanceCtrl.js | 135 +
.../unit/controllers/CreateViewInstanceCtrl.js | 135 -
.../test/unit/controllers/mainCtrl_test.js | 215 -
.../test/unit/services/Utility_test.js | 3 +-
.../src/main/python/ambari_agent/AmbariAgent.py | 3 -
.../python/ambari_agent/alerts/base_alert.py | 2 +-
.../libraries/functions/__init__.py | 1 -
.../libraries/functions/conf_select.py | 58 +
.../libraries/functions/curl_krb_request.py | 22 +-
.../libraries/functions/get_lzo_packages.py | 50 -
.../libraries/functions/package_conditions.py | 14 +-
.../libraries/functions/stack_select.py | 3 +-
ambari-logsearch/README.md | 26 +-
.../ambari-logsearch-logfeeder/README.md | 17 +-
.../ambari-logsearch-logfeeder/pom.xml | 6 +-
.../src/main/resources/log-samples/.gitignore | 4 +
.../log-samples/logs/service_sample.txt | 3 +
.../log-samples/shipper-conf/global.config.json | 10 +
.../shipper-conf/input.config-sample.json | 31 +
.../shipper-conf/output.config-sample.json | 34 +
.../src/main/resources/log4j.xml | 4 +-
.../src/main/resources/logfeeder.properties | 31 +-
.../ambari-logsearch-server/.gitignore | 1 +
.../ambari-logsearch-server/README.md | 44 +-
.../ambari-logsearch-server/pom.xml | 2 +-
ambari-logsearch/ambari-logsearch-server/run.sh | 2 +-
.../ambari/logsearch/conf/AuthPropsConfig.java | 18 +
.../ambari/logsearch/conf/SecurityConfig.java | 6 +-
.../LogsearchAuthenticationEntryPoint.java | 2 +-
.../src/main/resources/logsearch.properties | 54 +-
.../ambari-logsearch-web/src/app/app.module.ts | 8 +-
.../src/app/classes/filtering.ts | 355 +-
.../src/app/classes/models/app-state.ts | 6 +-
.../src/app/classes/models/node-item.ts | 30 +
.../src/app/classes/models/node.ts | 30 -
.../src/app/classes/models/store.ts | 6 +-
.../src/app/classes/models/tab.ts | 12 +-
.../action-menu/action-menu.component.html | 20 +
.../action-menu/action-menu.component.less | 27 +
.../action-menu/action-menu.component.spec.ts | 47 +
.../action-menu/action-menu.component.ts | 105 +
.../src/app/components/app.component.html | 4 +-
.../src/app/components/app.component.less | 5 +-
.../src/app/components/app.component.ts | 6 +-
.../dropdown-button.component.html | 4 +-
.../dropdown-button.component.spec.ts | 2 -
.../dropdown-button.component.ts | 55 +-
.../dropdown-list/dropdown-list.component.html | 2 +-
.../dropdown-list.component.spec.ts | 6 +-
.../filter-button.component.spec.ts | 2 -
.../filter-button/filter-button.component.ts | 35 +-
.../filter-dropdown.component.spec.ts | 14 +-
.../filter-dropdown.component.ts | 22 +-
.../filters-panel/filters-panel.component.html | 6 +-
.../filters-panel.component.spec.ts | 6 +-
.../filters-panel/filters-panel.component.ts | 18 +-
.../log-context/log-context.component.spec.ts | 4 +-
.../log-level/log-level.component.html | 18 +
.../log-level/log-level.component.spec.ts | 73 +
.../components/log-level/log-level.component.ts | 52 +
.../log-message/log-message.component.html | 24 +
.../log-message/log-message.component.less | 69 +
.../log-message/log-message.component.spec.ts | 64 +
.../log-message/log-message.component.ts | 129 +
.../logs-container.component.html | 58 +-
.../logs-container.component.less | 3 +
.../logs-container.component.spec.ts | 2 -
.../logs-container/logs-container.component.ts | 26 +-
.../logs-list/logs-list.component.html | 95 +-
.../logs-list/logs-list.component.less | 130 +-
.../logs-list/logs-list.component.spec.ts | 21 +-
.../components/logs-list/logs-list.component.ts | 10 +-
.../main-container.component.html | 2 +-
.../menu-button/menu-button.component.html | 17 +-
.../menu-button/menu-button.component.less | 22 +-
.../menu-button/menu-button.component.spec.ts | 2 -
.../menu-button/menu-button.component.ts | 146 +-
.../src/app/components/mixins.less | 5 +
.../pagination-controls.component.html | 15 +-
.../pagination-controls.component.spec.ts | 101 +
.../pagination-controls.component.ts | 76 +-
.../pagination/pagination.component.html | 2 +-
.../pagination/pagination.component.spec.ts | 9 +-
.../pagination/pagination.component.ts | 10 +-
.../search-box/search-box.component.ts | 12 +-
.../time-range-picker.component.html | 3 +-
.../time-range-picker.component.spec.ts | 29 +-
.../time-range-picker.component.ts | 47 +-
.../timezone-picker.component.spec.ts | 2 -
.../components/top-menu/top-menu.component.html | 10 +-
.../components/top-menu/top-menu.component.less | 1 +
.../components/top-menu/top-menu.component.ts | 83 +-
.../src/app/components/variables.less | 3 +
.../services/component-actions.service.spec.ts | 2 -
.../app/services/component-actions.service.ts | 24 +-
.../component-generator.service.spec.ts | 2 -
.../src/app/services/filtering.service.spec.ts | 97 -
.../src/app/services/filtering.service.ts | 253 -
.../app/services/logs-container.service.spec.ts | 31 +-
.../src/app/services/logs-container.service.ts | 678 +-
.../src/app/services/utils.service.spec.ts | 285 +-
.../src/app/services/utils.service.ts | 65 +-
.../ambari-logsearch-web/webpack.config.js | 15 +-
ambari-logsearch/docker/Dockerfile | 6 -
ambari-logsearch/docker/docker-compose.yml | 4 +-
ambari-logsearch/docker/logsearch-docker.sh | 1 +
.../docs/security/kerberos/kerberos_service.md | 22 +-
ambari-server/pom.xml | 12 +
.../ambari/server/agent/ExecutionCommand.java | 34 +-
.../ambari/server/agent/HeartbeatProcessor.java | 72 +-
.../ambari/server/checks/CheckDescription.java | 9 +
.../apache/ambari/server/checks/LZOCheck.java | 76 +
.../AmbariCustomCommandExecutionHelper.java | 23 +-
.../AmbariManagementControllerImpl.java | 60 +-
.../controller/DeleteIdentityHandler.java | 3 +-
.../server/controller/KerberosHelper.java | 21 +-
.../server/controller/KerberosHelperImpl.java | 138 +-
.../ClusterStackVersionResourceProvider.java | 41 +-
.../HostKerberosIdentityResourceProvider.java | 16 +-
.../HostStackVersionResourceProvider.java | 2 +-
.../internal/UpgradeResourceProvider.java | 12 +-
.../ServiceComponentUninstalledEvent.java | 11 +-
.../server/orm/dao/KerberosKeytabDAO.java | 110 +
.../server/orm/dao/KerberosPrincipalDAO.java | 7 +
.../orm/dao/KerberosPrincipalHostDAO.java | 40 +-
.../orm/entities/KerberosKeytabEntity.java | 86 +
.../entities/KerberosPrincipalHostEntity.java | 57 +-
.../entities/KerberosPrincipalHostEntityPK.java | 19 +-
.../serveraction/ServerActionExecutor.java | 147 +-
.../kerberos/ADKerberosOperationHandler.java | 22 +-
.../AbstractPrepareKerberosServerAction.java | 29 +-
.../kerberos/CleanupServerAction.java | 14 +-
.../server/serveraction/kerberos/Component.java | 13 +-
.../ConfigureAmbariIdentitiesServerAction.java | 31 +-
.../kerberos/CreateKeytabFilesServerAction.java | 65 +-
.../kerberos/CreatePrincipalsServerAction.java | 52 +-
.../kerberos/DestroyPrincipalsServerAction.java | 3 +-
.../kerberos/IPAKerberosOperationHandler.java | 1067 +--
.../kerberos/KDCKerberosOperationHandler.java | 391 +
.../kerberos/KerberosIdentityDataFile.java | 2 -
.../KerberosIdentityDataFileWriter.java | 9 +-
.../kerberos/KerberosOperationHandler.java | 64 +-
.../kerberos/KerberosServerAction.java | 27 +-
.../kerberos/MITKerberosOperationHandler.java | 406 +-
.../PrepareDisableKerberosServerAction.java | 2 +-
.../PrepareEnableKerberosServerAction.java | 2 +-
.../PrepareKerberosIdentitiesServerAction.java | 3 +-
.../stageutils/ResolvedKerberosKeytab.java | 257 +
.../upgrades/PreconfigureKerberosAction.java | 48 +-
.../ambari/server/stack/ServiceDirectory.java | 29 +
.../ambari/server/stack/ServiceModule.java | 8 +
.../apache/ambari/server/state/ServiceImpl.java | 2 +-
.../apache/ambari/server/state/ServiceInfo.java | 14 +
.../state/repository/ClusterVersionSummary.java | 3 +
.../state/repository/ServiceVersionSummary.java | 11 +-
.../state/repository/VersionDefinitionXml.java | 25 +-
.../stack/upgrade/RepositoryVersionHelper.java | 28 +-
.../svccomphost/ServiceComponentHostImpl.java | 2 +-
.../server/upgrade/UpgradeCatalog300.java | 30 +-
.../ambari/server/utils/VersionUtils.java | 46 +-
.../main/resources/Ambari-DDL-Derby-CREATE.sql | 15 +-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 13 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 13 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 11 +-
.../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 13 +-
.../resources/Ambari-DDL-SQLServer-CREATE.sql | 13 +-
.../src/main/resources/META-INF/persistence.xml | 1 +
.../ATLAS/0.1.0.2.3/package/scripts/params.py | 2 +-
.../ATLAS/0.7.0.3.0/package/scripts/params.py | 2 +-
.../DRUID/0.10.1/package/scripts/druid.py | 3 +-
.../DRUID/0.10.1/package/scripts/params.py | 3 +-
.../FALCON/0.5.0.2.1/package/scripts/falcon.py | 11 +-
.../HBASE/2.0.0.3.0/service_advisor.py | 12 +-
.../common-services/HDFS/2.1.0.2.0/metainfo.xml | 30 -
.../HDFS/2.1.0.2.0/package/scripts/datanode.py | 1 -
.../HDFS/2.1.0.2.0/package/scripts/hdfs.py | 7 -
.../2.1.0.2.0/package/scripts/hdfs_client.py | 1 -
.../2.1.0.2.0/package/scripts/install_params.py | 1 +
.../2.1.0.2.0/package/scripts/journalnode.py | 1 -
.../HDFS/2.1.0.2.0/package/scripts/namenode.py | 1 -
.../common-services/HDFS/3.0.0.3.0/metainfo.xml | 30 -
.../HDFS/3.0.0.3.0/package/scripts/hdfs.py | 7 -
.../HIVE/0.12.0.2.0/configuration/hive-site.xml | 38 +
.../HIVE/0.12.0.2.0/metainfo.xml | 5 -
.../package/alerts/alert_hive_thrift_port.py | 3 +-
.../0.12.0.2.0/package/files/startMetastore.sh | 4 +-
.../0.12.0.2.0/package/scripts/hive_service.py | 10 +-
.../package/scripts/hive_service_interactive.py | 5 +-
.../0.12.0.2.0/package/scripts/params_linux.py | 3 +-
.../0.12.0.2.0/package/scripts/service_check.py | 6 +-
.../package/scripts/webhcat_service.py | 19 +-
.../common-services/HIVE/2.1.0.3.0/metainfo.xml | 10 -
.../2.1.0.3.0/package/files/startMetastore.sh | 4 +-
.../2.1.0.3.0/package/scripts/hive_service.py | 8 +-
.../package/scripts/hive_service_interactive.py | 5 +-
.../2.1.0.3.0/package/scripts/params_linux.py | 10 +-
.../2.1.0.3.0/package/scripts/service_check.py | 6 +-
.../package/scripts/webhcat_service.py | 19 +-
.../1.10.3-10/configuration/kerberos-env.xml | 36 +-
.../package/scripts/kerberos_common.py | 7 +-
.../1.10.3-30/configuration/kerberos-env.xml | 36 +-
.../package/scripts/kerberos_common.py | 7 +-
.../LOGSEARCH/0.5.0/metainfo.xml | 6 +-
.../1.0.0.2.3/package/scripts/service_check.py | 3 +-
.../OOZIE/4.0.0.2.0/package/scripts/oozie.py | 6 +-
.../package/scripts/oozie_server_upgrade.py | 7 +-
.../4.0.0.2.0/package/scripts/params_linux.py | 1 +
.../OOZIE/4.2.0.2.3/metainfo.xml | 5 -
.../OOZIE/4.2.0.3.0/metainfo.xml | 5 -
.../OOZIE/4.2.0.3.0/package/scripts/oozie.py | 4 -
.../package/scripts/oozie_server_upgrade.py | 5 +
.../scripts/alerts/alert_spark_thrift_port.py | 8 +-
.../SPARK/1.2.1/package/scripts/setup_spark.py | 3 +-
.../scripts/alerts/alert_spark2_thrift_port.py | 8 +-
.../SPARK2/2.0.0/package/scripts/setup_spark.py | 3 +-
.../SQOOP/1.4.4.2.0/metainfo.xml | 5 -
.../1.4.4.2.0/package/scripts/params_linux.py | 4 +-
.../SQOOP/1.4.4.3.0/metainfo.xml | 10 -
.../1.4.4.3.0/package/scripts/params_linux.py | 4 +-
.../0.4.0.2.1/package/scripts/params_linux.py | 2 +-
.../TEZ/0.4.0.2.1/package/scripts/tez_client.py | 32 -
.../TEZ/0.9.0.3.0/configuration/tez-site.xml | 2 +-
.../0.9.0.3.0/package/scripts/params_linux.py | 2 +-
.../TEZ/0.9.0.3.0/package/scripts/tez_client.py | 26 -
.../configuration-mapred/mapred-site.xml | 2 +-
.../2.1.0.2.0/package/scripts/params_linux.py | 2 +-
.../configuration-mapred/mapred-site.xml | 2 +-
.../3.0.0.3.0/package/scripts/params_linux.py | 2 +-
.../ZEPPELIN/0.7.0/package/scripts/master.py | 11 +-
.../custom_actions/scripts/install_packages.py | 12 +-
.../custom_actions/scripts/remove_bits.py | 2 +-
.../BIGTOP/0.8/services/HDFS/metainfo.xml | 16 -
.../0.8/services/HDFS/package/scripts/params.py | 6 +-
.../BIGTOP/0.8/services/HIVE/metainfo.xml | 4 -
.../BIGTOP/0.8/services/OOZIE/metainfo.xml | 4 -
.../2.0.6.GlusterFS/services/HIVE/metainfo.xml | 4 -
.../2.0.6.GlusterFS/services/OOZIE/metainfo.xml | 4 -
.../HDP/2.0.6/properties/stack_features.json | 5 +
.../HDP/2.0.6/properties/stack_packages.json | 104 +-
.../2.1.GlusterFS/services/HIVE/metainfo.xml | 4 -
.../2.1.GlusterFS/services/OOZIE/metainfo.xml | 4 -
.../stacks/HDP/2.1/services/HIVE/metainfo.xml | 5 -
.../stacks/HDP/2.2/services/HDFS/metainfo.xml | 35 -
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 10 -
.../stacks/HDP/2.2/services/OOZIE/metainfo.xml | 5 -
.../stacks/HDP/2.2/services/SQOOP/metainfo.xml | 10 -
.../2.2/services/TEZ/configuration/tez-site.xml | 4 +-
.../YARN/configuration-mapred/mapred-site.xml | 2 +-
.../2.3.GlusterFS/services/HDFS/metainfo.xml | 10 -
.../2.3.GlusterFS/services/HIVE/metainfo.xml | 9 -
.../2.3.GlusterFS/services/SQOOP/metainfo.xml | 9 -
.../main/resources/stacks/HDP/2.3/metainfo.xml | 2 +-
.../stacks/HDP/2.3/services/HDFS/metainfo.xml | 30 -
.../stacks/HDP/2.3/services/HIVE/metainfo.xml | 10 -
.../HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml | 1 +
.../stacks/HDP/2.3/upgrades/upgrade-2.6.xml | 1 +
.../HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml | 1 +
.../stacks/HDP/2.4/upgrades/upgrade-2.6.xml | 1 +
.../stacks/HDP/2.5/services/FALCON/metainfo.xml | 4 +-
.../stacks/HDP/2.5/services/HIVE/metainfo.xml | 10 -
.../HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml | 1 +
.../stacks/HDP/2.5/upgrades/upgrade-2.6.xml | 1 +
.../resources/stacks/HDP/2.6/repos/repoinfo.xml | 2 +-
.../stacks/HDP/2.6/upgrades/config-upgrade.xml | 23 +
.../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml | 10 +
.../stacks/HDP/2.6/upgrades/upgrade-2.6.xml | 5 +
.../HDP/3.0/properties/stack_packages.json | 108 +-
.../stacks/HDP/3.0/services/HDFS/metainfo.xml | 30 -
.../YARN/configuration-mapred/mapred-site.xml | 2 +-
.../resources/stacks/PERF/1.0/hdp_urlinfo.json | 12 +
.../stacks/PERF/1.0/repos/repoinfo.xml | 1 +
.../KERBEROS/configuration/kerberos-env.xml | 36 +-
.../src/main/resources/stacks/PERF/1.0/vdf.xml | 73 +
.../resources/stacks/PERF/2.0/hdp_urlinfo.json | 12 +
.../stacks/PERF/2.0/repos/repoinfo.xml | 1 +
.../src/main/resources/stacks/PERF/2.0/vdf.xml | 74 +
.../server/agent/TestHeartbeatHandler.java | 2 +-
.../ambari/server/checks/LZOCheckTest.java | 145 +
.../AmbariManagementControllerImplTest.java | 2 +-
.../server/controller/KerberosHelperTest.java | 12 +-
...ClusterStackVersionResourceProviderTest.java | 239 +
...ostKerberosIdentityResourceProviderTest.java | 12 +-
.../internal/UpgradeResourceProviderTest.java | 8 +
.../utilities/KerberosIdentityCleanerTest.java | 10 +-
.../HostVersionOutOfSyncListenerTest.java | 2 +-
.../ADKerberosOperationHandlerTest.java | 261 +-
...AbstractPrepareKerberosServerActionTest.java | 11 +-
...nfigureAmbariIdentitiesServerActionTest.java | 11 +-
.../FinalizeKerberosServerActionTest.java | 5 +
.../IPAKerberosOperationHandlerTest.java | 147 +-
.../KDCKerberosOperationHandlerTest.java | 168 +
.../kerberos/KerberosIdentityDataFileTest.java | 8 +-
.../kerberos/KerberosOperationHandlerTest.java | 152 +-
.../kerberos/KerberosServerActionTest.java | 137 +-
.../MITKerberosOperationHandlerTest.java | 633 +-
.../PreconfigureKerberosActionTest.java | 10 +
.../ambari/server/stack/ServiceModuleTest.java | 30 +
.../server/stack/StackManagerExtensionTest.java | 6 +
.../state/repository/VersionDefinitionTest.java | 42 +
.../server/upgrade/UpgradeCatalog300Test.java | 152 +-
.../ambari/server/utils/TestVersionUtils.java | 4 +
.../python/custom_actions/TestRemoveBits.py | 5 +-
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 8 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 18 +-
.../2.0.6/HIVE/test_hive_service_check.py | 2 +-
.../stacks/2.0.6/HIVE/test_webhcat_server.py | 4 -
.../stacks/2.1/FALCON/test_falcon_server.py | 10 +-
.../stacks/2.1/HIVE/test_hive_metastore.py | 9 +-
.../python/stacks/2.1/TEZ/test_tez_client.py | 2 +-
.../stacks/2.2/SPARK/test_job_history_server.py | 12 +-
.../stacks/2.2/SPARK/test_spark_client.py | 12 +-
.../stacks/2.2/common/test_conf_select.py | 14 +-
.../2.3/MAHOUT/test_mahout_service_check.py | 4 +-
.../2.3/SPARK/test_spark_thrift_server.py | 6 +-
.../stacks/2.5/HIVE/test_hive_server_int.py | 15 +-
.../2.5/configs/ranger-admin-secured.json | 2 -
.../stacks/2.5/configs/ranger-kms-secured.json | 2 -
.../2.6/configs/ranger-admin-secured.json | 2 -
.../PreconfigureActionTest_cluster_config.json | 4 +-
ambari-web/app/config.js | 1 -
.../app/controllers/global/update_controller.js | 2 +-
.../main/admin/kerberos/step1_controller.js | 52 +-
.../main/admin/kerberos/step2_controller.js | 2 +-
.../main/host/bulk_operations_controller.js | 14 +-
ambari-web/app/controllers/main/service/item.js | 13 +-
.../app/mappers/components_state_mapper.js | 1 +
ambari-web/app/messages.js | 3 +-
ambari-web/app/models/client_component.js | 1 +
.../app/styles/theme/bootstrap-ambari.css | 35 +-
.../admin/kerberos/step1_controller_test.js | 17 -
.../admin/kerberos/step2_controller_test.js | 2 +-
.../test/controllers/main/service/item_test.js | 49 +-
.../vendor/scripts/theme/bootstrap-ambari.js | 7 -
.../stacks/ODPi/2.0/services/HIVE/metainfo.xml | 10 -
378 files changed, 18632 insertions(+), 7207 deletions(-)
----------------------------------------------------------------------
[12/51] [abbrv] ambari git commit: AMBARI-22292. PU: Could not
install version when only build changes (ncole)
Posted by nc...@apache.org.
AMBARI-22292. PU: Could not install version when only build changes (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/65ea560d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/65ea560d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/65ea560d
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 65ea560d712df357722d811984069cad2f3540e0
Parents: 68bc38e
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Nov 3 10:10:26 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Nov 3 10:10:26 2017 -0400
----------------------------------------------------------------------
.../ClusterStackVersionResourceProvider.java | 38 +----------------
.../state/repository/VersionDefinitionXml.java | 15 +++++--
.../ambari/server/utils/VersionUtils.java | 44 ++++++++++++++++++++
.../state/repository/VersionDefinitionTest.java | 34 +++++++++++++++
.../ambari/server/utils/TestVersionUtils.java | 3 ++
5 files changed, 95 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 1a75559..969fca1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -88,7 +88,6 @@ import org.apache.ambari.server.utils.StageUtils;
import org.apache.ambari.server.utils.VersionUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.NumberUtils;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
@@ -258,7 +257,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
Collections.sort(entities, new Comparator<RepositoryVersionEntity>() {
@Override
public int compare(RepositoryVersionEntity o1, RepositoryVersionEntity o2) {
- return compareVersions(o1.getVersion(), o2.getVersion());
+ return VersionUtils.compareVersionsWithBuild(o1.getVersion(), o2.getVersion(), 4);
}
});
@@ -502,7 +501,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
continue;
}
- int compare = compareVersions(hostRepoVersion.getVersion(), desiredRepoVersion);
+ int compare = VersionUtils.compareVersionsWithBuild(hostRepoVersion.getVersion(), desiredRepoVersion, 4);
// ignore earlier versions
if (compare <= 0) {
@@ -806,39 +805,6 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
}
/**
- * Additional check over {@link VersionUtils#compareVersions(String, String)} that
- * compares build numbers
- */
- private static int compareVersions(String version1, String version2) {
- version1 = (null == version1) ? "0" : version1;
- version2 = (null == version2) ? "0" : version2;
-
- // check _exact_ equality
- if (StringUtils.equals(version1, version2)) {
- return 0;
- }
-
- int compare = VersionUtils.compareVersions(version1, version2);
- if (0 != compare) {
- return compare;
- }
-
- int v1 = 0;
- int v2 = 0;
- if (version1.indexOf('-') > -1) {
- v1 = NumberUtils.toInt(version1.substring(version1.indexOf('-')), 0);
- }
-
- if (version2.indexOf('-') > -1) {
- v2 = NumberUtils.toInt(version2.substring(version2.indexOf('-')), 0);
- }
-
- compare = v2 - v1;
-
- return Integer.compare(compare, 0);
- }
-
- /**
* Ensures that the stack tools and stack features are set on
* {@link ConfigHelper#CLUSTER_ENV} for the stack of the repository being
* distributed. This step ensures that the new repository can be distributed
http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
index 1dda0b1..634ab04 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
@@ -308,12 +308,21 @@ public class VersionDefinitionXml {
// !!! currently only one version is supported (unique service names)
ManifestService manifest = manifests.get(serviceName);
- summary.setVersions(manifest.version, StringUtils.isEmpty(manifest.releaseVersion) ?
- release.version : manifest.releaseVersion);
+ final String versionToCompare;
+ final String summaryReleaseVersion;
+ if (StringUtils.isEmpty(manifest.releaseVersion)) {
+ versionToCompare = release.getFullVersion();
+ summaryReleaseVersion = release.version;
+ } else {
+ versionToCompare = manifest.releaseVersion;
+ summaryReleaseVersion = manifest.releaseVersion;
+ }
+
+ summary.setVersions(manifest.version, summaryReleaseVersion);
// !!! installed service already meets the release version, then nothing to upgrade
// !!! TODO should this be using the release compatible-with field?
- if (VersionUtils.compareVersions(summary.getReleaseVersion(), serviceVersion, 4) > 0) {
+ if (VersionUtils.compareVersionsWithBuild(versionToCompare, serviceVersion, 4) > 0) {
summary.setUpgrade(true);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
index 08948e1..6a3d81c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
@@ -22,6 +22,7 @@ import java.util.List;
import org.apache.ambari.server.bootstrap.BootStrapImpl;
import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.math.NumberUtils;
/**
* Provides various utility functions to be used for version handling.
@@ -212,4 +213,47 @@ public class VersionUtils {
return versionParts[0] + "." + versionParts[1] + "." + versionParts[2];
}
+
+ /**
+ * Compares versions, using a build number using a dash separator, if one exists.
+ * This is is useful when comparing repository versions with one another that include
+ * build number
+ * @param version1
+ * the first version
+ * @param version2
+ * the second version
+ * @param places
+ * the number of decimal-separated places to compare
+ * @return
+ */
+ public static int compareVersionsWithBuild(String version1, String version2, int places) {
+ version1 = (null == version1) ? "0" : version1;
+ version2 = (null == version2) ? "0" : version2;
+
+ // check _exact_ equality
+ if (StringUtils.equals(version1, version2)) {
+ return 0;
+ }
+
+ int compare = VersionUtils.compareVersions(version1, version2, places);
+ if (0 != compare) {
+ return compare;
+ }
+
+ int v1 = 0;
+ int v2 = 0;
+ if (version1.indexOf('-') > -1) {
+ v1 = NumberUtils.toInt(version1.substring(version1.indexOf('-')), 0);
+ }
+
+ if (version2.indexOf('-') > -1) {
+ v2 = NumberUtils.toInt(version2.substring(version2.indexOf('-')), 0);
+ }
+
+ compare = v2 - v1;
+
+ return Integer.compare(compare, 0);
+
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
index 8433518..370a14f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
@@ -429,7 +429,41 @@ public class VersionDefinitionTest {
xml = VersionDefinitionXml.load(f.toURI().toURL());
summary = xml.getClusterSummary(cluster);
assertEquals(1, summary.getAvailableServiceNames().size());
+ }
+
+ @Test
+ public void testAvailableBuildVersion() throws Exception {
+
+ Cluster cluster = createNiceMock(Cluster.class);
+ RepositoryVersionEntity repositoryVersion = createNiceMock(RepositoryVersionEntity.class);
+ expect(repositoryVersion.getVersion()).andReturn("2.3.4.1-1").atLeastOnce();
+ Service serviceHdfs = createNiceMock(Service.class);
+ expect(serviceHdfs.getName()).andReturn("HDFS").atLeastOnce();
+ expect(serviceHdfs.getDisplayName()).andReturn("HDFS").atLeastOnce();
+ expect(serviceHdfs.getDesiredRepositoryVersion()).andReturn(repositoryVersion).atLeastOnce();
+
+ Service serviceHBase = createNiceMock(Service.class);
+ expect(serviceHBase.getName()).andReturn("HBASE").atLeastOnce();
+ expect(serviceHBase.getDisplayName()).andReturn("HBase").atLeastOnce();
+ expect(serviceHBase.getDesiredRepositoryVersion()).andReturn(repositoryVersion).atLeastOnce();
+
+ // !!! should never be accessed as it's not in any VDF
+ Service serviceAMS = createNiceMock(Service.class);
+
+ expect(cluster.getServices()).andReturn(ImmutableMap.<String, Service>builder()
+ .put("HDFS", serviceHdfs)
+ .put("HBASE", serviceHBase)
+ .put("AMBARI_METRICS", serviceAMS).build()).atLeastOnce();
+
+ replay(cluster, repositoryVersion, serviceHdfs, serviceHBase);
+
+ File f = new File("src/test/resources/version_definition_test_maint_partial.xml");
+ VersionDefinitionXml xml = VersionDefinitionXml.load(f.toURI().toURL());
+ xml.release.version = "2.3.4.1";
+ xml.release.build = "2";
+ ClusterVersionSummary summary = xml.getClusterSummary(cluster);
+ assertEquals(1, summary.getAvailableServiceNames().size());
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
index 6ad4e26..42d321a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
@@ -48,6 +48,9 @@ public class TestVersionUtils {
Assert.assertEquals(0, VersionUtils.compareVersions("2.2", "2.2.VER"));
Assert.assertEquals(0, VersionUtils.compareVersions("2.2.VAR", "2.2.VER"));
Assert.assertEquals(0, VersionUtils.compareVersions("2.2.3", "2.2.3.VER1.V"));
+
+ Assert.assertEquals(0, VersionUtils.compareVersions("2.2.0.1-200", "2.2.0.1-100"));
+ Assert.assertEquals(1, VersionUtils.compareVersionsWithBuild("2.2.0.1-200", "2.2.0.1-100", 4));
}
@Test
[27/51] [abbrv] ambari git commit: AMBARI-22266. Log Search server
does not handle proxies properly (oleewere)
Posted by nc...@apache.org.
AMBARI-22266. Log Search server does not handle proxies properly (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/30a43c9f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/30a43c9f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/30a43c9f
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 30a43c9f3e376343ebeb087e57acb0c6a5211d5a
Parents: b8004df
Author: Oliver Szabo <ol...@gmail.com>
Authored: Wed Nov 8 11:54:46 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Wed Nov 8 11:55:04 2017 +0100
----------------------------------------------------------------------
.../ambari/logsearch/conf/AuthPropsConfig.java | 18 ++++++++++++++++++
.../ambari/logsearch/conf/SecurityConfig.java | 6 ++++--
.../LogsearchAuthenticationEntryPoint.java | 2 +-
3 files changed, 23 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/30a43c9f/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
index 2bcdebc..06673b3 100644
--- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
@@ -167,6 +167,16 @@ public class AuthPropsConfig {
)
private List<String> allowedRoles;
+ @Value("${logsearch.auth.redirect.forward:false}")
+ @LogSearchPropertyDescription(
+ name = "logsearch.auth.redirect.forward",
+ description = "Forward redirects for HTTP calls. (useful in case of proxies)",
+ examples = {"true"},
+ defaultValue = "false",
+ sources = {LOGSEARCH_PROPERTIES_FILE}
+ )
+ private boolean redirectForward;
+
public boolean isAuthFileEnabled() {
return authFileEnabled;
}
@@ -278,4 +288,12 @@ public class AuthPropsConfig {
public void setAllowedRoles(List<String> allowedRoles) {
this.allowedRoles = allowedRoles;
}
+
+ public boolean isRedirectForward() {
+ return redirectForward;
+ }
+
+ public void setRedirectForward(boolean redirectForward) {
+ this.redirectForward = redirectForward;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/30a43c9f/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
index cb8124e..6f8d7ba 100644
--- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
@@ -44,6 +44,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
@@ -105,8 +106,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.httpBasic()
.authenticationEntryPoint(logsearchAuthenticationEntryPoint())
.and()
- .addFilterBefore(logsearchUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
- .addFilterBefore(logsearchKRBAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
+ .addFilterBefore(logsearchKRBAuthenticationFilter(), BasicAuthenticationFilter.class)
+ .addFilterBefore(logsearchUsernamePasswordAuthenticationFilter(), LogsearchKRBAuthenticationFilter.class)
.addFilterAfter(securityContextFormationFilter(), FilterSecurityInterceptor.class)
.addFilterAfter(logsearchEventHistoryFilter(), LogsearchSecurityContextFormationFilter.class)
.addFilterAfter(logsearchAuditLogFilter(), LogsearchSecurityContextFormationFilter.class)
@@ -153,6 +154,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
public LogsearchAuthenticationEntryPoint logsearchAuthenticationEntryPoint() {
LogsearchAuthenticationEntryPoint entryPoint = new LogsearchAuthenticationEntryPoint("/login");
entryPoint.setForceHttps(false);
+ entryPoint.setUseForward(authPropsConfig.isRedirectForward());
return entryPoint;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/30a43c9f/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
index 1831697..2fe5f7b 100644
--- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
@@ -44,7 +44,7 @@ public class LogsearchAuthenticationEntryPoint extends LoginUrlAuthenticationEnt
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Session Timeout");
} else {
logger.debug("Redirecting to login page :" + this.getLoginFormUrl());
- response.sendRedirect(this.getLoginFormUrl() + ((request.getQueryString() != null) ? "?" + request.getQueryString() : ""));
+ super.commence(request, response, authException);
}
}
}
[42/51] [abbrv] ambari git commit: AMBARI-22346. Beeline connection
hangs for longer time when connection to HS2 with metastore DB down
(aonishuk)
Posted by nc...@apache.org.
AMBARI-22346. Beeline connection hangs for longer time when connection to HS2 with metastore DB down (aonishuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/98915a11
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/98915a11
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/98915a11
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 98915a114769c7ddd590854ccf0ab33beabddcf3
Parents: 46ad6c6
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Fri Nov 10 13:28:27 2017 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Fri Nov 10 13:28:27 2017 +0200
----------------------------------------------------------------------
.../HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py | 3 ++-
.../1.2.1/package/scripts/alerts/alert_spark_thrift_port.py | 8 +++++++-
.../2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py | 8 +++++++-
3 files changed, 16 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/98915a11/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
index 3560bf8..6db92b0 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
@@ -28,6 +28,7 @@ from resource_management.libraries.functions import format
from resource_management.libraries.functions import get_kinit_path
from ambari_commons.os_check import OSConst
from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
+from resource_management.core.signal_utils import TerminateStrategy
OK_MESSAGE = "TCP OK - {0:.3f}s response on port {1}"
CRITICAL_MESSAGE = "Connection failed on host {0}:{1} ({2})"
@@ -271,7 +272,7 @@ def execute(configurations={}, parameters={}, host_name=None):
start_time = time.time()
try:
- Execute(cmd, user=hiveuser, timeout=30)
+ Execute(cmd, user=hiveuser, timeout=30, timeout_kill_strategy=TerminateStrategy.KILL_PROCESS_TREE)
total_time = time.time() - start_time
result_code = 'OK'
label = OK_MESSAGE.format(total_time, port)
http://git-wip-us.apache.org/repos/asf/ambari/blob/98915a11/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
index 3f80fd9..6874cb4 100644
--- a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
+++ b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
@@ -27,6 +27,7 @@ from resource_management.libraries.script.script import Script
from resource_management.libraries.functions import get_kinit_path
from resource_management.core.resources import Execute
from resource_management.core import global_lock
+from resource_management.core.signal_utils import TerminateStrategy
stack_root = Script.get_stack_root()
@@ -140,7 +141,12 @@ def execute(configurations={}, parameters={}, host_name=None):
start_time = time.time()
try:
- Execute(cmd, user=hiveruser, path=[beeline_cmd], timeout=CHECK_COMMAND_TIMEOUT_DEFAULT)
+ Execute(cmd,
+ user=hiveruser,
+ path=[beeline_cmd],
+ timeout=CHECK_COMMAND_TIMEOUT_DEFAULT,
+ timeout_kill_strategy=TerminateStrategy.KILL_PROCESS_TREE,
+ )
total_time = time.time() - start_time
result_code = 'OK'
label = OK_MESSAGE.format(total_time, port)
http://git-wip-us.apache.org/repos/asf/ambari/blob/98915a11/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
index 9e1afea..d3660de 100644
--- a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
+++ b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
@@ -27,6 +27,7 @@ from resource_management.libraries.script.script import Script
from resource_management.libraries.functions import get_kinit_path
from resource_management.core.resources import Execute
from resource_management.core import global_lock
+from resource_management.core.signal_utils import TerminateStrategy
stack_root = Script.get_stack_root()
@@ -141,7 +142,12 @@ def execute(configurations={}, parameters={}, host_name=None):
start_time = time.time()
try:
- Execute(cmd, user=hiveruser, path=[beeline_cmd], timeout=CHECK_COMMAND_TIMEOUT_DEFAULT)
+ Execute(cmd,
+ user=hiveruser,
+ path=[beeline_cmd],
+ timeout=CHECK_COMMAND_TIMEOUT_DEFAULT,
+ timeout_kill_strategy=TerminateStrategy.KILL_PROCESS_TREE
+ )
total_time = time.time() - start_time
result_code = 'OK'
label = OK_MESSAGE.format(total_time, port)
[11/51] [abbrv] ambari git commit: AMBARI-22357. Log Search server
should be able to run locally with dockerized dev env by default (oleewere)
Posted by nc...@apache.org.
AMBARI-22357. Log Search server should be able to run locally with dockerized dev env by default (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/68bc38eb
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/68bc38eb
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/68bc38eb
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 68bc38eb241b9f8bd3a31b81f8db0ada5e5229f7
Parents: 1b020cd
Author: Oliver Szabo <ol...@gmail.com>
Authored: Fri Nov 3 14:33:29 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Fri Nov 3 14:36:06 2017 +0100
----------------------------------------------------------------------
ambari-logsearch/README.md | 4 ++
.../ambari-logsearch-server/.gitignore | 1 +
.../ambari-logsearch-server/README.md | 44 +++++-----------
ambari-logsearch/ambari-logsearch-server/run.sh | 2 +-
.../src/main/resources/logsearch.properties | 54 ++++++--------------
5 files changed, 36 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/README.md b/ambari-logsearch/README.md
index 43878f2..33952a2 100644
--- a/ambari-logsearch/README.md
+++ b/ambari-logsearch/README.md
@@ -31,6 +31,10 @@ docker exec -it logsearch bash
```
In case if you started the containers separately and if you would like to access Solr locally with through your external ZooKeeper container, then point `solr` to `localhost` in your `/etc/hosts` file.
+### Run applications from IDE / maven
+
+- [Start Log Search locally](ambari-logsearch-server/README.md)
+
## Package build process
http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/.gitignore
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/.gitignore b/ambari-logsearch/ambari-logsearch-server/.gitignore
index 07e0389..7ea6a1f 100644
--- a/ambari-logsearch/ambari-logsearch-server/.gitignore
+++ b/ambari-logsearch/ambari-logsearch-server/.gitignore
@@ -6,4 +6,5 @@ target
node_modules/
logs/
node/
+*.pid
http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/README.md b/ambari-logsearch/ambari-logsearch-server/README.md
index 126f651..26b1f73 100644
--- a/ambari-logsearch/ambari-logsearch-server/README.md
+++ b/ambari-logsearch/ambari-logsearch-server/README.md
@@ -17,39 +17,23 @@ limitations under the License.
{% endcomment %}
-->
-#Compilation
-mvn clean compile package
+# Log Search Server
-#Deploy
-##Copy to remote
-copy target/logsearch-portal.tar.gz to host machine
-##Setup environment
-```bash
-mkdir /opt/logsearch
-cd /opt/logsearch
-tar xfz ~/logsearch-portal.tar.gz
-```
-#Create Solr Collection
-*Edit for log retention days (default is 7 days)*
-```bash
-vi solr_configsets/hadoop_logs/conf/solrconfig.xml
-```
-```
- <processor class="solr.DefaultValueUpdateProcessorFactory">
- <str name="fieldName">_ttl_</str>
- <str name="value">+7DAYS</str>
- </processor>
-```
-```bash
-./create_collections.sh $SOLR_HOME $NUM_SHARDS $NUM_OF_REPLICATIONS `pwd`/solr_configsets
-```
+## Start locally from maven / IDE
+
+Other services (like zookeeper, solr, logfeeder) can be started with `docker-compose`
```bash
-vi classes/logsearch.properties
-```
-```
-solr.zkhosts=$ZK1:2181,$ZK2:2181,$ZK3:2181/solr
+cd ambari/ambari-logsearch/docker
+docker-compose up -d zookeeper solr logfeeder
```
-*This script will stop logsearch if it is running and restart it*
+
+Then you can start Log Search server from maven
+
```bash
+cd ambari/ambari-logsearch/ambari-logsearch-server
./run.sh
+# or
+mvn clean spring-boot:run
```
+
+You can also start Log Search server from an IDE as well. One thing is important: the config set location that the server tries to upload to ZooKeeper. By default config sets are located at `${LOGSEARCH_SERVER_RELATIVE_LOCATION:}src/main/configsets` in `logsearch.properties`. Based or from where you run `LogSearch.java`, you need to set `LOGSEARCH_SERVER_RELATIVE_LOCATION` env variable properly.
http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/run.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/run.sh b/ambari-logsearch/ambari-logsearch-server/run.sh
index 765fe6c..f245930 100755
--- a/ambari-logsearch/ambari-logsearch-server/run.sh
+++ b/ambari-logsearch/ambari-logsearch-server/run.sh
@@ -17,4 +17,4 @@ echo "
███████╗╚██████╔╝╚██████╔╝ ███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
╚══════╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
"
-mvn spring-boot:run
+mvn clean spring-boot:run
http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties b/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
index db8a0a2..3a0f460 100755
--- a/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
@@ -12,49 +12,27 @@
# 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.
-
-#logsearch.solr.url=http://host:port/solr
-logsearch.solr.url=
-
-#Solr Core
+logsearch.solr.zk_connect_string=localhost:2181
logsearch.solr.collection.service.logs=hadoop_logs
-#logsearch.solr.collection.service.logs=ranger_audits
+logsearch.service.logs.split.interval.mins=15
+logsearch.collection.service.logs.numshards=3
+logsearch.collection.service.logs.replication.factor=2
+logsearch.solr.audit.logs.zk_connect_string=localhost:2181
+logsearch.solr.collection.audit.logs=audit_logs
+logsearch.audit.logs.split.interval.mins=15
+logsearch.collection.audit.logs.numshards=2
+logsearch.collection.audit.logs.replication.factor=2
+logsearch.solr.config_set.folder=${LOGSEARCH_SERVER_RELATIVE_LOCATION:}src/main/configsets
+logsearch.solr.audit.logs.config_set.folder=${LOGSEARCH_SERVER_RELATIVE_LOCATION:}src/main/configsets
logsearch.solr.collection.history=history
-logsearch.service.logs.split.interval.mins=none
-logsearch.collection.service.logs.numshards=1
-logsearch.collection.service.logs.replication.factor=1
-
-#If set, metrics will be sent to Ambari
-#logsearch.solr.metrics.collector.hosts=example.com
-logsearch.solr.metrics.collector.hosts=
-logsearch.solr.audit.logs.url=
-#logsearch.solr.collection.audit.logs=collection_name
-logsearch.solr.collection.audit.logs=ranger_audits
-logsearch.audit.logs.split.interval.mins=none
-logsearch.collection.audit.logs.numshards=1
-logsearch.collection.audit.logs.replication.factor=1
-
-#Authentication settings
-#Note: Simple will be supported only if file ,ldap and external_auth all three are disabled.
+logsearch.solr.history.config.name=history
+logsearch.collection.history.replication.factor=1
logsearch.auth.file.enable=true
+logsearch.login.credentials.file=user_pass.json
+
logsearch.auth.ldap.enable=false
logsearch.auth.simple.enable=false
logsearch.auth.external_auth.enable=false
-logsearch.auth.external_auth.host_url=http://ip:port
-logsearch.auth.external_auth.login_url=/api/v1/users/$USERNAME/privileges?fields=*
-#Note: Use comma(,) for separation of multiple roles
-logsearch.roles.allowed=AMBARI.ADMINISTRATOR
-
-logsearch.http.port=61888
-logsearch.https.port=61889
logsearch.protocol=http
-
-logsearch.solr.kerberos.enable=false
-logsearch.solr.jaas.file=/usr/lib/ambari-logsearch-portal/logsearch_solr_jaas.conf
-
-#portal Kerberos
-logsearch.spnego.kerberos.enabled=false
-logsearch.spnego.kerberos.keytab=
-logsearch.spnego.kerberos.principal=
-logsearch.spnego.kerberos.host=
\ No newline at end of file
+logsearch.config.zk_connect_string=localhost:2181
\ No newline at end of file
[36/51] [abbrv] ambari git commit: AMBARI-22370 - Remove HADOOP_HOME
From Environment For Daemons (jonathanhurley)
Posted by nc...@apache.org.
AMBARI-22370 - Remove HADOOP_HOME From Environment For Daemons (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/780e91e6
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/780e91e6
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/780e91e6
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 780e91e6124f39fcd67e58369ed2a42da2a6f247
Parents: 444718a
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Nov 6 16:05:56 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Nov 9 08:23:15 2017 -0500
----------------------------------------------------------------------
.../libraries/functions/stack_select.py | 3 ++-
.../ATLAS/0.1.0.2.3/package/scripts/params.py | 2 +-
.../ATLAS/0.7.0.3.0/package/scripts/params.py | 2 +-
.../FALCON/0.5.0.2.1/package/scripts/falcon.py | 11 +----------
.../package/scripts/hive_service_interactive.py | 5 ++---
.../package/scripts/webhcat_service.py | 19 ++++---------------
.../package/scripts/hive_service_interactive.py | 5 ++---
.../2.1.0.3.0/package/scripts/params_linux.py | 7 +++----
.../2.1.0.3.0/package/scripts/webhcat_service.py | 19 ++++---------------
.../1.0.0.2.3/package/scripts/service_check.py | 3 +--
.../1.4.4.2.0/package/scripts/params_linux.py | 4 ++--
.../1.4.4.3.0/package/scripts/params_linux.py | 4 ++--
.../0.4.0.2.1/package/scripts/params_linux.py | 2 +-
.../0.9.0.3.0/package/scripts/params_linux.py | 2 +-
.../2.1.0.2.0/package/scripts/params_linux.py | 2 +-
.../3.0.0.3.0/package/scripts/params_linux.py | 2 +-
.../stacks/2.0.6/HIVE/test_webhcat_server.py | 4 ----
.../stacks/2.1/FALCON/test_falcon_server.py | 10 ++--------
.../python/stacks/2.1/TEZ/test_tez_client.py | 2 +-
.../2.3/MAHOUT/test_mahout_service_check.py | 4 +---
.../stacks/2.5/HIVE/test_hive_server_int.py | 15 +++++----------
21 files changed, 38 insertions(+), 89 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
index 9b7d0eb..b741a33 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
@@ -71,7 +71,8 @@ HADOOP_DIR_DEFAULTS = {
"libexec": "/usr/lib/hadoop/libexec",
"sbin": "/usr/lib/hadoop/sbin",
"bin": "/usr/bin",
- "lib": "/usr/lib/hadoop/lib"
+ "lib": "/usr/lib/hadoop/lib",
+ "conf": "/etc/hadoop/conf"
}
PACKAGE_SCOPE_INSTALL = "INSTALL"
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py b/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
index 968ceed..31a866e 100644
--- a/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
@@ -118,7 +118,7 @@ metadata_stop_script = format("{metadata_bin}/atlas_stop.py")
log_dir = config['configurations']['atlas-env']['metadata_log_dir']
# service locations
-hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else '/etc/hadoop/conf'
+hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else format('{stack_root}/current/hadoop-client/conf')
# some commands may need to supply the JAAS location when running as atlas
atlas_jaas_file = format("{conf_dir}/atlas_jaas.conf")
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
index b01884c..7c1249a 100644
--- a/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
@@ -116,7 +116,7 @@ metadata_stop_script = format("{metadata_bin}/atlas_stop.py")
log_dir = config['configurations']['atlas-env']['metadata_log_dir']
# service locations
-hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else '/etc/hadoop/conf'
+hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else format('{stack_root}/current/hadoop-client/conf')
# some commands may need to supply the JAAS location when running as atlas
atlas_jaas_file = format("{conf_dir}/atlas_jaas.conf")
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
index 933515b..7d8fa13 100644
--- a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
+++ b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
@@ -209,12 +209,6 @@ def falcon(type, action = None, upgrade_type=None):
owner = params.falcon_user,
create_parents = True)
- # although Falcon's falcon-config.sh will use 'which hadoop' to figure
- # this out, in an upgraded cluster, it's possible that 'which hadoop'
- # still points to older binaries; it's safer to just pass in the
- # hadoop home directory to use
- environment_dictionary = { "HADOOP_HOME" : params.hadoop_home_dir }
-
pid = get_user_call_output.get_user_call_output(format("cat {server_pid_file}"), user=params.falcon_user, is_checked_call=False)[1]
process_exists = format("ls {server_pid_file} && ps -p {pid}")
@@ -223,7 +217,6 @@ def falcon(type, action = None, upgrade_type=None):
Execute(format('{falcon_home}/bin/falcon-config.sh server falcon'),
user = params.falcon_user,
path = params.hadoop_bin_dir,
- environment=environment_dictionary,
not_if = process_exists,
)
except:
@@ -253,7 +246,6 @@ in the Falcon documentation.
Execute(format('{falcon_home}/bin/falcon-start -port {falcon_port}'),
user = params.falcon_user,
path = params.hadoop_bin_dir,
- environment=environment_dictionary,
not_if = process_exists,
)
except:
@@ -264,8 +256,7 @@ in the Falcon documentation.
try:
Execute(format('{falcon_home}/bin/falcon-stop'),
user = params.falcon_user,
- path = params.hadoop_bin_dir,
- environment=environment_dictionary)
+ path = params.hadoop_bin_dir)
except:
show_logs(params.falcon_log_dir, params.falcon_user)
raise
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
index 703d104..71c22d7 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
@@ -52,12 +52,11 @@ def hive_service_interactive(name, action='start', upgrade_type=None):
if action == 'start':
check_fs_root(params.hive_server_interactive_conf_dir, params.execute_path_hive_interactive)
daemon_cmd = cmd
- hadoop_home = params.hadoop_home
- hive_interactive_bin = "hive2"
+ hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin/hive2")
Execute(daemon_cmd,
user = params.hive_user,
- environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
+ environment = { 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
path = params.execute_path,
not_if = process_id_exists_command)
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
index cb4aafd..bddb5b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
@@ -40,30 +40,22 @@ def webhcat_service(action='start', rolling_restart=False):
def webhcat_service(action='start', upgrade_type=None):
import params
- environ = {
- 'HADOOP_HOME': params.hadoop_home
- }
-
cmd = format('{webhcat_bin_dir}/webhcat_server.sh')
if action == 'start':
- if upgrade_type is not None and params.version and params.stack_root:
- environ['HADOOP_HOME'] = format("{stack_root}/{version}/hadoop")
-
daemon_cmd = format('cd {hcat_pid_dir} ; {cmd} start')
no_op_test = format('ls {webhcat_pid_file} >/dev/null 2>&1 && ps -p `cat {webhcat_pid_file}` >/dev/null 2>&1')
try:
Execute(daemon_cmd,
user=params.webhcat_user,
- not_if=no_op_test,
- environment = environ)
+ not_if=no_op_test)
except:
show_logs(params.hcat_log_dir, params.webhcat_user)
raise
elif action == 'stop':
try:
# try stopping WebHCat using its own script
- graceful_stop(cmd, environ)
+ graceful_stop(cmd)
except Fail:
show_logs(params.hcat_log_dir, params.webhcat_user)
Logger.info(traceback.format_exc())
@@ -95,17 +87,14 @@ def webhcat_service(action='start', upgrade_type=None):
File(params.webhcat_pid_file, action="delete")
-def graceful_stop(cmd, environ):
+def graceful_stop(cmd):
"""
Attemps to stop WebHCat using its own shell script. On some versions this may not correctly
stop the daemon.
:param cmd: the command to run to stop the daemon
- :param environ: the environment variables to execute the command with
:return:
"""
import params
daemon_cmd = format('{cmd} stop')
- Execute(daemon_cmd,
- user = params.webhcat_user,
- environment = environ)
+ Execute(daemon_cmd, user = params.webhcat_user)
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
index 703d104..71c22d7 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
@@ -52,12 +52,11 @@ def hive_service_interactive(name, action='start', upgrade_type=None):
if action == 'start':
check_fs_root(params.hive_server_interactive_conf_dir, params.execute_path_hive_interactive)
daemon_cmd = cmd
- hadoop_home = params.hadoop_home
- hive_interactive_bin = "hive2"
+ hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin/hive2")
Execute(daemon_cmd,
user = params.hive_user,
- environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
+ environment = { 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
path = params.execute_path,
not_if = process_id_exists_command)
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
index 1bd6a1a..088a540 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
@@ -36,19 +36,17 @@ from resource_management.libraries.functions import get_kinit_path
from resource_management.libraries.functions.get_not_managed_resources import get_not_managed_resources
from resource_management.libraries.script.script import Script
from resource_management.libraries.functions import StackFeature
+from resource_management.libraries.functions import stack_select
from resource_management.libraries.functions.stack_features import check_stack_feature
from resource_management.libraries.functions.stack_features import get_stack_feature_version
from resource_management.libraries.functions import upgrade_summary
from resource_management.libraries.functions.get_port_from_url import get_port_from_url
from resource_management.libraries.functions.expect import expect
from resource_management.libraries import functions
-from resource_management.libraries.functions.setup_atlas_hook import has_atlas_in_cluster
-from ambari_commons.ambari_metrics_helper import select_metric_collector_hosts_from_hostnames
from resource_management.libraries.functions.setup_ranger_plugin_xml import get_audit_configs, generate_ranger_service_config
from resource_management.libraries.functions.get_architecture import get_architecture
from resource_management.core.utils import PasswordString
-from resource_management.core.shell import checked_call
from resource_management.core.exceptions import Fail
from ambari_commons.credential_store_helper import get_password_from_credential_store
@@ -107,7 +105,8 @@ stack_supports_hive_interactive_ga = check_stack_feature(StackFeature.HIVE_INTER
component_directory = status_params.component_directory
component_directory_interactive = status_params.component_directory_interactive
-hadoop_home = format('{stack_root}/current/hadoop-client')
+hadoop_home = stack_select.get_hadoop_dir("home")
+
hive_bin = format('{stack_root}/current/{component_directory}/bin')
hive_cmd = os.path.join(hive_bin, "hive")
hive_schematool_ver_bin = format('{stack_root}/{version}/hive/bin')
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
index cb4aafd..bddb5b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
@@ -40,30 +40,22 @@ def webhcat_service(action='start', rolling_restart=False):
def webhcat_service(action='start', upgrade_type=None):
import params
- environ = {
- 'HADOOP_HOME': params.hadoop_home
- }
-
cmd = format('{webhcat_bin_dir}/webhcat_server.sh')
if action == 'start':
- if upgrade_type is not None and params.version and params.stack_root:
- environ['HADOOP_HOME'] = format("{stack_root}/{version}/hadoop")
-
daemon_cmd = format('cd {hcat_pid_dir} ; {cmd} start')
no_op_test = format('ls {webhcat_pid_file} >/dev/null 2>&1 && ps -p `cat {webhcat_pid_file}` >/dev/null 2>&1')
try:
Execute(daemon_cmd,
user=params.webhcat_user,
- not_if=no_op_test,
- environment = environ)
+ not_if=no_op_test)
except:
show_logs(params.hcat_log_dir, params.webhcat_user)
raise
elif action == 'stop':
try:
# try stopping WebHCat using its own script
- graceful_stop(cmd, environ)
+ graceful_stop(cmd)
except Fail:
show_logs(params.hcat_log_dir, params.webhcat_user)
Logger.info(traceback.format_exc())
@@ -95,17 +87,14 @@ def webhcat_service(action='start', upgrade_type=None):
File(params.webhcat_pid_file, action="delete")
-def graceful_stop(cmd, environ):
+def graceful_stop(cmd):
"""
Attemps to stop WebHCat using its own shell script. On some versions this may not correctly
stop the daemon.
:param cmd: the command to run to stop the daemon
- :param environ: the environment variables to execute the command with
:return:
"""
import params
daemon_cmd = format('{cmd} stop')
- Execute(daemon_cmd,
- user = params.webhcat_user,
- environment = environ)
+ Execute(daemon_cmd, user = params.webhcat_user)
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
index c1151fc..b15d158 100644
--- a/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
@@ -71,8 +71,7 @@ class MahoutServiceCheck(Script):
Execute( mahout_command,
tries = 3,
try_sleep = 5,
- environment={'HADOOP_HOME': params.hadoop_home,'HADOOP_CONF_DIR': params.hadoop_conf_dir,
- 'MAHOUT_HOME': params.mahout_home,'JAVA_HOME': params.java64_home},
+ environment={'MAHOUT_HOME': params.mahout_home,'JAVA_HOME': params.java64_home},
path = format('/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin'),
user = params.smokeuser
)
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
index 400c87c..eaf1ee4 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
@@ -23,11 +23,11 @@ from resource_management.libraries.functions.version import format_stack_version
from resource_management.libraries.functions.default import default
from resource_management.libraries.functions.get_kinit_path import get_kinit_path
from resource_management.libraries.script import Script
+from resource_management.libraries.functions import stack_select
from resource_management.libraries.functions.format import format
from resource_management.libraries.functions import StackFeature
from resource_management.libraries.functions.stack_features import check_stack_feature
from resource_management.libraries.functions.expect import expect
-from resource_management.libraries.functions.setup_atlas_hook import has_atlas_in_cluster
from resource_management.core.exceptions import Fail
@@ -71,7 +71,7 @@ zoo_conf_dir = "/etc/zookeeper"
if stack_version_formatted and check_stack_feature(StackFeature.ROLLING_UPGRADE, stack_version_formatted):
sqoop_conf_dir = format("{stack_root}/current/sqoop-client/conf")
sqoop_lib = format("{stack_root}/current/sqoop-client/lib")
- hadoop_home = format("{stack_root}/current/hadoop-client")
+ hadoop_home = stack_select.get_hadoop_dir("home")
hbase_home = format("{stack_root}/current/hbase-client")
hive_home = format("{stack_root}/current/hive-client")
sqoop_bin_dir = format("{stack_root}/current/sqoop-client/bin/")
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
index 400c87c..eaf1ee4 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
@@ -23,11 +23,11 @@ from resource_management.libraries.functions.version import format_stack_version
from resource_management.libraries.functions.default import default
from resource_management.libraries.functions.get_kinit_path import get_kinit_path
from resource_management.libraries.script import Script
+from resource_management.libraries.functions import stack_select
from resource_management.libraries.functions.format import format
from resource_management.libraries.functions import StackFeature
from resource_management.libraries.functions.stack_features import check_stack_feature
from resource_management.libraries.functions.expect import expect
-from resource_management.libraries.functions.setup_atlas_hook import has_atlas_in_cluster
from resource_management.core.exceptions import Fail
@@ -71,7 +71,7 @@ zoo_conf_dir = "/etc/zookeeper"
if stack_version_formatted and check_stack_feature(StackFeature.ROLLING_UPGRADE, stack_version_formatted):
sqoop_conf_dir = format("{stack_root}/current/sqoop-client/conf")
sqoop_lib = format("{stack_root}/current/sqoop-client/lib")
- hadoop_home = format("{stack_root}/current/hadoop-client")
+ hadoop_home = stack_select.get_hadoop_dir("home")
hbase_home = format("{stack_root}/current/hbase-client")
hive_home = format("{stack_root}/current/hive-client")
sqoop_bin_dir = format("{stack_root}/current/sqoop-client/bin/")
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
index 4d63685..cef709b 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
@@ -50,7 +50,7 @@ version = default("/commandParams/version", None)
hadoop_lib_home = stack_select.get_hadoop_dir("lib")
# default hadoop parameters
-hadoop_home = '/usr'
+hadoop_home = stack_select.get_hadoop_dir("home")
hadoop_bin_dir = stack_select.get_hadoop_dir("bin")
hadoop_conf_dir = conf_select.get_hadoop_conf_dir()
tez_etc_dir = "/etc/tez"
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
index 5a028bd..2b3fa38 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
@@ -48,7 +48,7 @@ stack_version_formatted = format_stack_version(stack_version_unformatted)
version = default("/commandParams/version", None)
# default hadoop parameters
-hadoop_home = '/usr'
+hadoop_home = stack_select.get_hadoop_dir("home")
hadoop_bin_dir = stack_select.get_hadoop_dir("bin")
hadoop_conf_dir = conf_select.get_hadoop_conf_dir()
tez_etc_dir = "/etc/tez"
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
index 620408b..3e4504d 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
@@ -65,7 +65,7 @@ stack_name = status_params.stack_name
stack_root = Script.get_stack_root()
tarball_map = default("/configurations/cluster-env/tarball_map", None)
-config_path = os.path.join(stack_root, "current/hadoop-client/conf")
+config_path = stack_select.get_hadoop_dir("conf")
config_dir = os.path.realpath(config_path)
# get the correct version to use for checking stack features
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
index e4dbe2c..617dc3b 100644
--- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
@@ -65,7 +65,7 @@ stack_name = status_params.stack_name
stack_root = Script.get_stack_root()
tarball_map = default("/configurations/cluster-env/tarball_map", None)
-config_path = os.path.join(stack_root, "current/hadoop-client/conf")
+config_path = stack_select.get_hadoop_dir("conf")
config_dir = os.path.realpath(config_path)
# get the correct version to use for checking stack features
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
index f9480ee..b4652ac 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
@@ -65,7 +65,6 @@ class TestWebHCatServer(RMFTestCase):
self.assert_configure_default()
self.assertResourceCalled('Execute', 'cd /var/run/webhcat ; /usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh start',
- environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client'},
not_if = "ls /var/run/webhcat/webhcat.pid >/dev/null 2>&1 && ps -p `cat /var/run/webhcat/webhcat.pid` >/dev/null 2>&1",
user = 'hcat',
)
@@ -82,7 +81,6 @@ class TestWebHCatServer(RMFTestCase):
self.assertResourceCalled('Execute', '/usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh stop',
user = 'hcat',
- environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client' }
)
self.assertResourceCalled('Execute', 'ambari-sudo.sh kill -9 `cat /var/run/webhcat/webhcat.pid`',
@@ -148,7 +146,6 @@ class TestWebHCatServer(RMFTestCase):
self.assert_configure_secured()
self.assertResourceCalled('Execute', 'cd /var/run/webhcat ; /usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh start',
- environment = {'HADOOP_HOME': '/usr/hdp/2.1.0.0-1234/hadoop'},
not_if = "ls /var/run/webhcat/webhcat.pid >/dev/null 2>&1 && ps -p `cat /var/run/webhcat/webhcat.pid` >/dev/null 2>&1",
user = 'hcat',
)
@@ -165,7 +162,6 @@ class TestWebHCatServer(RMFTestCase):
self.assertResourceCalled('Execute', '/usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh stop',
user = 'hcat',
- environment = {'HADOOP_HOME': '/usr/hdp/2.1.0.0-1234/hadoop' }
)
self.assertResourceCalled('Execute', 'ambari-sudo.sh kill -9 `cat /var/run/webhcat/webhcat.pid`',
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py b/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
index 7f2ed46..8c48347 100644
--- a/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
+++ b/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
@@ -49,7 +49,6 @@ class TestFalconServer(RMFTestCase):
self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-config.sh server falcon',
path = ['/usr/bin'],
user = 'falcon',
- environment = {'HADOOP_HOME': '/usr/lib/hadoop'},
not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',
)
@@ -61,7 +60,6 @@ class TestFalconServer(RMFTestCase):
self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-start -port 15000',
path = ['/usr/bin'],
user = 'falcon',
- environment = {'HADOOP_HOME': '/usr/lib/hadoop'},
not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',
)
@@ -78,8 +76,7 @@ class TestFalconServer(RMFTestCase):
self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-stop',
path = ['/usr/bin'],
- user = 'falcon',
- environment = {'HADOOP_HOME': '/usr/lib/hadoop'})
+ user = 'falcon')
self.assertResourceCalled('File', '/var/run/falcon/falcon.pid',
action = ['delete'])
@@ -236,8 +233,7 @@ class TestFalconServer(RMFTestCase):
self.assertResourceCalled('Execute',
'/usr/hdp/current/falcon-server/bin/falcon-stop',
- path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'], user='falcon',
- environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2135/hadoop'})
+ path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'], user='falcon')
self.assertResourceCalled('File', '/var/run/falcon/falcon.pid',
action = ['delete'])
@@ -406,14 +402,12 @@ class TestFalconServer(RMFTestCase):
)
self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-config.sh server falcon',
- environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2135/hadoop'},
path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'],
user = 'falcon',
not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',
)
self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-start -port 15000',
- environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2135/hadoop'},
path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'],
user = 'falcon',
not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py b/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
index fad99f6..59b2166 100644
--- a/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
+++ b/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
@@ -130,6 +130,6 @@ class TestTezClient(RMFTestCase):
config_dict = json_content,
stack_version = self.STACK_VERSION,
target = RMFTestCase.TARGET_COMMON_SERVICES,
- call_mocks = [(0, None, ''), (0, None)],
+ call_mocks = [(0, None, ''),(0, None, ''), (0, None)],
mocks_dict = mocks_dict)
# for now, it's enough to know the method didn't fail
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py b/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
index b80476c..8695653 100644
--- a/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
+++ b/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
@@ -109,9 +109,7 @@ class TestMahoutClient(RMFTestCase):
self.assertResourceCalled('Execute', 'mahout seqdirectory --input /user/ambari-qa/mahoutsmokeinput/'
'sample-mahout-test.txt --output /user/ambari-qa/mahoutsmokeoutput/ '
'--charset utf-8',
- environment = {'HADOOP_CONF_DIR': '/usr/hdp/2.2.1.0-2067/hadoop/conf',
- 'HADOOP_HOME': '/usr/hdp/2.2.1.0-2067/hadoop',
- 'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45',
+ environment = {'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45',
'MAHOUT_HOME': '/usr/hdp/current/mahout-client'},
path = ['/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin'],
tries = 3,
http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py b/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
index 4951c7e..cf79ec7 100644
--- a/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
@@ -115,8 +115,7 @@ class TestHiveServerInteractive(RMFTestCase):
)
self.assertResourceCalled('Execute',
'/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
- environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
- 'HIVE_BIN': 'hive2',
+ environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user='hive',
@@ -178,8 +177,7 @@ class TestHiveServerInteractive(RMFTestCase):
)
self.assertResourceCalled('Execute',
'/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
- environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
- 'HIVE_BIN': 'hive2',
+ environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user='hive',
@@ -227,8 +225,7 @@ class TestHiveServerInteractive(RMFTestCase):
)
self.assertResourceCalled('Execute',
'/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
- environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
- 'HIVE_BIN': 'hive2',
+ environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user='hive',
@@ -305,8 +302,7 @@ class TestHiveServerInteractive(RMFTestCase):
)
self.assertResourceCalled('Execute',
'/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
- environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
- 'HIVE_BIN': 'hive2',
+ environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user='hive',
@@ -364,8 +360,7 @@ class TestHiveServerInteractive(RMFTestCase):
)
self.assertResourceCalled('Execute',
'/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
- environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
- 'HIVE_BIN': 'hive2',
+ environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
user='hive',
[24/51] [abbrv] ambari git commit: AMBARI-22377 Ambari 3.0: Implement
new design for Admin View: Views page. (atkach)
Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
new file mode 100644
index 0000000..7aa25ab
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
@@ -0,0 +1,134 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.
+-->
+
+<div id="views-table">
+
+ <div class="clearfix">
+ <div class="pull-right">
+ <button ng-disabled="views.length === 0" ng-click="createInstance(views[0]);" class="btn btn-default">
+ {{'views.create' | translate}}
+ </button>
+ </div>
+ </div>
+
+ <table class="table table-striped table-hover">
+ <thead>
+ <tr class="fix-bottom">
+ <th class="fix-bottom col-md-2">
+ <span>{{'common.name' | translate}}</span>
+ </th>
+ <th class="fix-bottom col-md-3">
+ <span>{{'urls.url' | translate}}</span>
+ </th>
+ <th class="fix-bottom col-md-2">
+ <span>{{'views.table.viewType' | translate}}</span>
+ </th>
+ <th class="fix-bottom col-md-2">
+ <span>{{'urls.viewInstance' | translate}}</span>
+ </th>
+ <th class="fix-bottom col-md-2 view-instance-actions">
+ <span>{{'common.actions' | translate}}</span>
+ </th>
+ </tr>
+ <tr>
+ <th class="fix-top">
+ <div class="search-container">
+ <input type="text" class="form-control" placeholder="{{'common.any' | translate}}"
+ ng-model="instanceNameFilter" ng-change="filterInstances()">
+ <button type="button" class="close clearfilter" ng-show="instanceNameFilter"
+ ng-click="instanceNameFilter=''; filterInstances()">
+ <span aria-hidden="true">×</span>
+ <span class="sr-only">{{'common.controls.close' | translate}}</span>
+ </button>
+ </div>
+ </th>
+ <th class="fix-top">
+ <div class="search-container">
+ <input type="text" class="form-control" placeholder="{{'common.any' | translate}}"
+ ng-model="instanceUrlFilter" ng-change="filterInstances()">
+ <button type="button" class="close clearfilter" ng-show="instanceUrlFilter"
+ ng-click="instanceUrlFilter=''; filterInstances()">
+ <span aria-hidden="true">×</span>
+ <span class="sr-only">{{'common.controls.close' | translate}}</span>
+ </button>
+ </div>
+ </th>
+ <th class="fix-top">
+ <select class="form-control typefilter v-small-input"
+ ng-model="instanceTypeFilter"
+ ng-options="item.label for item in typeFilterOptions"
+ ng-change="filterInstances()">
+ </select>
+ </th>
+ <th class="fix-top">
+ </th>
+ <th class="fix-top">
+ </th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr ng-repeat="instance in instances | filter : { isShowed: true }">
+ <td>
+ <span>{{instance.short_url_name}}</span>
+ </td>
+ <td>
+ <a target="_blank"
+ href="{{fromSiteRoot('/#/main/view/' + instance.view_name + '/' + instance.short_url)}}">/main/view/{{instance.view_name}}/{{instance.short_url}}
+ <i class="fa fa-external-link" aria-hidden="true"></i></a>
+ </td>
+ <td>
+ <span>{{instance.view_name}} {{"{"+instance.version+"}"}} </span>
+ </td>
+ <td>
+ <span>{{instance.instance_name}}</span>
+ </td>
+ <td class="view-instance-actions">
+ <a href="#/views/{{instance.view_name}}/versions/{{instance.version}}/instances/{{instance.instance_name}}/edit">
+ <i class="fa fa-pencil"></i>
+ </a>
+ <a href="#/views/{{instance.view_name}}/versions/{{instance.version}}/instances/{{instance.instance_name}}/clone">
+ <i class="fa fa-copy"></i>
+ </a>
+ <a href ng-click="deleteInstance(instance)">
+ <i class="fa fa-trash-o"></i>
+ </a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div ng-if="isLoading" class="spinner-container">
+ <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
+ </div>
+ <div class="alert empty-table-alert col-sm-12" ng-show="!tableInfo.filtered && !isLoading">
+ {{'views.emptyTable'| translate}}
+ </div>
+ <div class="col-sm-12 table-bar" ng-show="instances.length >= minInstanceForPagination">
+ <div class="pull-left filtered-info">
+ <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.filtered, term: urs.urls}'}}</span>
+ <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
+ </div>
+ <div class="pull-right left-margin">
+ <pagination class="paginator" total-items="tableInfo.filtered" max-size="maxVisiblePages" items-per-page="instancesPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+ </div>
+ <div class="pull-right">
+ <select class="form-control" ng-model="instancesPerPage" ng-change="resetPagination()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+ </div>
+ </div>
+
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
index 0c9e1b9..c625475 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
@@ -25,9 +25,9 @@
<form class="form-horizontal create-user-form" role="form" novalidate name="formHolder.form" autocomplete="off">
<div class="form-group" ng-class="{'has-error' : formHolder.form.url_name.$error.required && formHolder.form.submitted}">
- <label for="urlname" class="col-sm-2 control-label">{{'urls.name' | translate}}</label>
+ <label for="urlname" class="col-sm-2 control-label">{{'common.name' | translate}}</label>
<div class="col-sm-10">
- <input ng-minlength="2" ng-maxlength="25" type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'urls.name' | translate}}" ng-model="url.urlName" required autocomplete="off">
+ <input ng-minlength="2" ng-maxlength="25" type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'common.name' | translate}}" ng-model="url.urlName" required autocomplete="off">
<div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.required && formHolder.form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
<div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.minlength && formHolder.form.submitted">{{'common.alerts.minimumTwoChars' | translate}}</div>
<div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.maxlength && formHolder.form.submitted">{{'common.alerts.maxTwentyFiveChars' | translate}}</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
index 9198818..dd5f65a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
@@ -27,9 +27,9 @@
<form class="form-horizontal create-user-form" role="form" novalidate name="url_form" autocomplete="off">
<div class="form-group" ng-class="{'has-error' : url_form.url_name.$error.required && url_form.submitted}">
- <label for="urlname" class="col-sm-2 control-label">{{'urls.name' | translate}}</label>
+ <label for="urlname" class="col-sm-2 control-label">{{'common.name' | translate}}</label>
<div class="col-sm-10">
- <input disabled type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'urls.name' | translate}}" ng-model="url.url_name" required autocomplete="off">
+ <input disabled type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'common.name' | translate}}" ng-model="url.url_name" required autocomplete="off">
<div class="alert alert-danger top-margin" ng-show="url_form.url_name.$error.required && url_form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
new file mode 100644
index 0000000..f78333a
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
@@ -0,0 +1,135 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+describe('#CloneViewInstanceCtrl', function () {
+ var scope, ctrl, $httpBackend, View;
+
+ beforeEach(module('ambariAdminConsole', function($provide){
+ $provide.value('$routeParams', {viewId: 'TestView'});
+ }));
+
+ afterEach(function() {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+ beforeEach(inject(function (_$httpBackend_, $rootScope, $controller, _View_, $q) {
+ View = _View_;
+ spyOn(View, 'createInstance').andReturn($q.defer().promise);
+ spyOn(View, 'getInstance').andReturn($q.defer().promise);
+
+ $httpBackend = _$httpBackend_;
+ $httpBackend.whenGET(/\/api\/v1\/views\/TestView\?.+/).respond(200, {
+ "versions": [{"ViewVersionInfo": {}}]
+ });
+ $httpBackend.whenGET(/\/api\/v1\/views\/TestView\/versions\/1\.0\.0/).respond(200, {
+ "ViewVersionInfo": {"parameters": [{"name": "n", "defaultValue": "d"}]}
+ });
+ $httpBackend.whenGET('template/modal/backdrop.html').respond(200, '<div></div>');
+ $httpBackend.whenGET('template/modal/window.html').respond(200, '<div></div>');
+ scope = $rootScope.$new();
+ ctrl = $controller('CloneViewInstanceCtrl', {$scope: scope});
+ }));
+
+ it('it should invoke View.createInstance on save', function () {
+ scope.form = {
+ instanceCreateForm: {
+ submitted: false,
+ $valid: true
+ }
+ };
+ $httpBackend.flush();
+ scope.instance = {};
+ scope.save();
+ expect(View.createInstance).toHaveBeenCalled();
+ });
+
+ it('should set default property value before creating view instance', function () {
+ scope.form = {
+ instanceCreateForm: {
+ $dirty: true
+ }
+ };
+ scope.instance = {};
+ scope.version = '1.0.0';
+ scope.isClone=false;
+ $httpBackend.expectGET('template/modal/backdrop.html');
+ $httpBackend.expectGET('template/modal/window.html');
+ $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
+ "items" : [
+ {
+ "Clusters" : {
+ "cluster_name" : "c1",
+ "version" : "HDP-2.2"
+ }
+ }
+ ]
+ });
+ $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
+ "items" : [
+ {
+ "ClusterInfo" : {
+ "name" : "c1",
+ "services" : ["HDFS"]
+ }
+ }
+ ]
+ });
+ scope.$digest();
+ $httpBackend.flush();
+ chai.expect(scope.view.ViewVersionInfo.parameters[0].value).to.equal('d');
+ expect(View.getInstance).not.toHaveBeenCalled();
+ });
+
+ it('before cloning view instance confirm that View.getInstance is called', function () {
+ scope.form = {
+ instanceCreateForm: {
+ $dirty: true
+ }
+ };
+ scope.instance = {};
+ scope.version = '1.0.0';
+ scope.isClone=true;
+ $httpBackend.expectGET('template/modal/backdrop.html');
+ $httpBackend.expectGET('template/modal/window.html');
+ $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
+ "items" : [
+ {
+ "Clusters" : {
+ "cluster_name" : "c1",
+ "version" : "HDP-2.2"
+ }
+ }
+ ]
+ });
+ $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
+ "items" : [
+ {
+ "ClusterInfo" : {
+ "name" : "c1",
+ "services" : ["HDFS"]
+ }
+ }
+ ]
+ });
+ scope.$digest();
+ $httpBackend.flush();
+ expect(View.getInstance).toHaveBeenCalled();
+ });
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js
deleted file mode 100644
index f8ccc24..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-describe('#CreateViewInstanceCtrl', function () {
- var scope, ctrl, $httpBackend, View;
-
- beforeEach(module('ambariAdminConsole', function($provide){
- $provide.value('$routeParams', {viewId: 'TestView'});
- }));
-
- afterEach(function() {
- $httpBackend.verifyNoOutstandingExpectation();
- $httpBackend.verifyNoOutstandingRequest();
- });
-
- beforeEach(inject(function (_$httpBackend_, $rootScope, $controller, _View_, $q) {
- View = _View_;
- spyOn(View, 'createInstance').andReturn($q.defer().promise);
- spyOn(View, 'getInstance').andReturn($q.defer().promise);
-
- $httpBackend = _$httpBackend_;
- $httpBackend.whenGET(/\/api\/v1\/views\/TestView\?.+/).respond(200, {
- "versions": [{"ViewVersionInfo": {}}]
- });
- $httpBackend.whenGET(/\/api\/v1\/views\/TestView\/versions\/1\.0\.0/).respond(200, {
- "ViewVersionInfo": {"parameters": [{"name": "n", "defaultValue": "d"}]}
- });
- $httpBackend.whenGET('template/modal/backdrop.html').respond(200, '<div></div>');
- $httpBackend.whenGET('template/modal/window.html').respond(200, '<div></div>');
- scope = $rootScope.$new();
- ctrl = $controller('CreateViewInstanceCtrl', {$scope: scope});
- }));
-
- it('it should invoke View.createInstance on save', function () {
- scope.form = {
- instanceCreateForm: {
- submitted: false,
- $valid: true
- }
- };
- $httpBackend.flush();
- scope.instance = {};
- scope.save();
- expect(View.createInstance).toHaveBeenCalled();
- });
-
- it('should set default property value before creating view instance', function () {
- scope.form = {
- instanceCreateForm: {
- $dirty: true
- }
- };
- scope.instance = {};
- scope.version = '1.0.0';
- scope.isClone=false;
- $httpBackend.expectGET('template/modal/backdrop.html');
- $httpBackend.expectGET('template/modal/window.html');
- $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "Clusters" : {
- "cluster_name" : "c1",
- "version" : "HDP-2.2"
- }
- }
- ]
- });
- $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "ClusterInfo" : {
- "name" : "c1",
- "services" : ["HDFS"]
- }
- }
- ]
- });
- scope.$digest();
- $httpBackend.flush();
- chai.expect(scope.view.ViewVersionInfo.parameters[0].value).to.equal('d');
- expect(View.getInstance).not.toHaveBeenCalled();
- });
-
- it('before cloning view instance confirm that View.getInstance is called', function () {
- scope.form = {
- instanceCreateForm: {
- $dirty: true
- }
- };
- scope.instance = {};
- scope.version = '1.0.0';
- scope.isClone=true;
- $httpBackend.expectGET('template/modal/backdrop.html');
- $httpBackend.expectGET('template/modal/window.html');
- $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "Clusters" : {
- "cluster_name" : "c1",
- "version" : "HDP-2.2"
- }
- }
- ]
- });
- $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "ClusterInfo" : {
- "name" : "c1",
- "services" : ["HDFS"]
- }
- }
- ]
- });
- scope.$digest();
- $httpBackend.flush();
- expect(View.getInstance).toHaveBeenCalled();
- });
-
-});
[33/51] [abbrv] ambari git commit: AMBARI-22373.Disable auto config
of interpreter.json at the time of installation(Prabhjyot Singh via Venkata
Sairam)
Posted by nc...@apache.org.
AMBARI-22373.Disable auto config of interpreter.json at the time of installation(Prabhjyot Singh via Venkata Sairam)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5f714cee
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5f714cee
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5f714cee
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 5f714cee399a1671f73abd8d405049a45d4c743c
Parents: 7074e6e
Author: Venkata Sairam <ve...@gmail.com>
Authored: Thu Nov 9 11:50:06 2017 +0530
Committer: Venkata Sairam <ve...@gmail.com>
Committed: Thu Nov 9 11:50:06 2017 +0530
----------------------------------------------------------------------
.../ZEPPELIN/0.7.0/package/scripts/master.py | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/5f714cee/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
index 6ccdfba..5efc277 100644
--- a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
+++ b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
@@ -257,7 +257,6 @@ class Master(Script):
if not glob.glob(params.conf_dir + "/interpreter.json") and \
not os.path.exists(params.conf_dir + "/interpreter.json"):
self.create_interpreter_json()
- self.update_zeppelin_interpreter()
if params.zeppelin_interpreter_config_upgrade == True:
self.reset_interpreter_settings()
@@ -599,6 +598,16 @@ class Master(Script):
group=params.zeppelin_group,
mode=0664)
+ if params.conf_stored_in_hdfs:
+ params.HdfsResource(self.get_zeppelin_conf_FS(params),
+ type="file",
+ action="create_on_execute",
+ source=format("{params.conf_dir}/interpreter.json"),
+ owner=params.zeppelin_user,
+ recursive_chown=True,
+ recursive_chmod=True,
+ replace_existing_files=True)
+
def get_zeppelin_spark_dependencies(self):
import params
return glob.glob(params.zeppelin_dir + '/interpreter/spark/dep/zeppelin-spark-dependencies*.jar')
[15/51] [abbrv] ambari git commit: AMBARI-22320. Some pre-upgrade
checks do not work when upgrading from IOP to HDP-2.6.3 (ncole)
Posted by nc...@apache.org.
AMBARI-22320. Some pre-upgrade checks do not work when upgrading from IOP to HDP-2.6.3 (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1fefbbac
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1fefbbac
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1fefbbac
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 1fefbbacedaefe342577246f1bbb7bf3fe9c2bc1
Parents: 0c6cf81
Author: Nate Cole <nc...@hortonworks.com>
Authored: Sat Nov 4 07:25:31 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Sat Nov 4 07:25:31 2017 -0400
----------------------------------------------------------------------
.../server/state/repository/VersionDefinitionXml.java | 10 +++++++---
.../server/state/repository/VersionDefinitionTest.java | 8 ++++++++
2 files changed, 15 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/1fefbbac/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
index 634ab04..62f78de 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
@@ -320,10 +320,14 @@ public class VersionDefinitionXml {
summary.setVersions(manifest.version, summaryReleaseVersion);
- // !!! installed service already meets the release version, then nothing to upgrade
- // !!! TODO should this be using the release compatible-with field?
- if (VersionUtils.compareVersionsWithBuild(versionToCompare, serviceVersion, 4) > 0) {
+ if (RepositoryType.STANDARD == release.repositoryType) {
summary.setUpgrade(true);
+ } else {
+ // !!! installed service already meets the release version, then nothing to upgrade
+ // !!! TODO should this be using the release compatible-with field?
+ if (VersionUtils.compareVersionsWithBuild(versionToCompare, serviceVersion, 4) > 0) {
+ summary.setUpgrade(true);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1fefbbac/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
index 370a14f..6f33c7e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
@@ -28,6 +28,7 @@ import static org.junit.Assert.assertTrue;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -425,6 +426,13 @@ public class VersionDefinitionTest {
summary = xml.getClusterSummary(cluster);
assertEquals(0, summary.getAvailableServiceNames().size());
+ f = new File("src/test/resources/version_definition_test_maint.xml");
+ xml = VersionDefinitionXml.load(f.toURI().toURL());
+ xml.release.repositoryType = RepositoryType.STANDARD;
+ xml.availableServices = Collections.emptyList();
+ summary = xml.getClusterSummary(cluster);
+ assertEquals(2, summary.getAvailableServiceNames().size());
+
f = new File("src/test/resources/version_definition_test_maint_partial.xml");
xml = VersionDefinitionXml.load(f.toURI().toURL());
summary = xml.getClusterSummary(cluster);
[41/51] [abbrv] ambari git commit: AMBARI-22303. Spark history server
is stopped (with umask 027 and custom spark log/pid dir) (aonishuk)
Posted by nc...@apache.org.
AMBARI-22303. Spark history server is stopped (with umask 027 and custom spark log/pid dir) (aonishuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/46ad6c68
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/46ad6c68
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/46ad6c68
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 46ad6c6878b00f7791845ecf7c2b3fef7244faad
Parents: feccebc
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Fri Nov 10 12:53:06 2017 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Fri Nov 10 12:53:06 2017 +0200
----------------------------------------------------------------------
.../SPARK/1.2.1/package/scripts/setup_spark.py | 3 ++-
.../SPARK2/2.0.0/package/scripts/setup_spark.py | 3 ++-
.../python/stacks/2.2/SPARK/test_job_history_server.py | 12 ++++++++----
.../test/python/stacks/2.2/SPARK/test_spark_client.py | 12 ++++++++----
.../python/stacks/2.3/SPARK/test_spark_thrift_server.py | 6 ++++--
5 files changed, 24 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
index 53c8f9e..6a29efb 100644
--- a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
+++ b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
@@ -52,7 +52,8 @@ def setup_spark(env, type, upgrade_type=None, action=None, config_dir=None):
owner=params.spark_user,
group=params.user_group,
mode=0775,
- create_parents = True
+ create_parents = True,
+ cd_access = 'a',
)
if type == 'server' and action == 'config':
params.HdfsResource(params.spark_hdfs_user_dir,
http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
index a7b8459..792b2a1 100755
--- a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
+++ b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
@@ -42,7 +42,8 @@ def setup_spark(env, type, upgrade_type = None, action = None):
owner=params.spark_user,
group=params.user_group,
mode=0775,
- create_parents = True
+ create_parents = True,
+ cd_access = 'a',
)
if type == 'server' and action == 'config':
params.HdfsResource(params.spark_hdfs_user_dir,
http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py b/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
index 922ace2..8801746 100644
--- a/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
+++ b/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
@@ -165,13 +165,15 @@ class TestJobHistoryServer(RMFTestCase):
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('Directory', '/var/log/spark',
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('HdfsResource', '/user/spark',
immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
@@ -246,13 +248,15 @@ class TestJobHistoryServer(RMFTestCase):
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('Directory', '/var/log/spark',
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('HdfsResource', '/user/spark',
immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py b/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
index b4535cd..e15d5a4 100644
--- a/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
+++ b/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
@@ -58,13 +58,15 @@ class TestSparkClient(RMFTestCase):
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('Directory', '/var/log/spark',
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('PropertiesFile', '/usr/hdp/current/spark-client/conf/spark-defaults.conf',
owner = 'spark',
@@ -108,13 +110,15 @@ class TestSparkClient(RMFTestCase):
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('Directory', '/var/log/spark',
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('PropertiesFile', '/usr/hdp/current/spark-client/conf/spark-defaults.conf',
owner = 'spark',
http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py b/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
index fbe5403..78d45cf 100644
--- a/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
+++ b/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
@@ -85,13 +85,15 @@ class TestSparkThriftServer(RMFTestCase):
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('Directory', '/var/log/spark',
owner = 'spark',
group = 'hadoop',
create_parents = True,
- mode = 0775
+ mode = 0775,
+ cd_access = 'a',
)
self.assertResourceCalled('HdfsResource', '/user/spark',
immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
[23/51] [abbrv] ambari git commit: AMBARI-22364. Log Feeder should be
able to run locally with dockerized dev env by default (oleewere)
Posted by nc...@apache.org.
AMBARI-22364. Log Feeder should be able to run locally with dockerized dev env by default (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/654404dc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/654404dc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/654404dc
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 654404dc8c545f47bafd8a446b99ecb251d83982
Parents: 063ba36
Author: Oliver Szabo <ol...@gmail.com>
Authored: Tue Nov 7 14:22:38 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Tue Nov 7 17:08:04 2017 +0100
----------------------------------------------------------------------
.../ambari-logsearch-logfeeder/README.md | 17 +++++-----
.../ambari-logsearch-logfeeder/pom.xml | 4 ++-
.../src/main/resources/log-samples/.gitignore | 4 +++
.../log-samples/logs/service_sample.txt | 3 ++
.../log-samples/shipper-conf/global.config.json | 10 ++++++
.../shipper-conf/input.config-sample.json | 31 ++++++++++++++++++
.../shipper-conf/output.config-sample.json | 34 ++++++++++++++++++++
.../src/main/resources/log4j.xml | 4 +--
.../src/main/resources/logfeeder.properties | 31 ++++++++++--------
9 files changed, 113 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/README.md b/ambari-logsearch/ambari-logsearch-logfeeder/README.md
index 5a64daf..d2e55f0 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/README.md
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/README.md
@@ -22,19 +22,18 @@ limitations under the License.
Log Feeder is a component of the Log Search service that reads logs, parses them and stores them in Apache Solr for the purpose
of later analysis.
-# Compilation
+## Start locally from maven / IDE
+
+First you need to start every required service (except logfeeder), go to `ambari-logsearch/docker` folder and run:
```bash
-mvn clean compile package
+docker-compose up -d zookeeper solr logsearch
```
-# Deploy
-## Copy to remote
-copy target/logsearch-logfeeder.tgz to host machine
-## Setup environment
+Secondly, if you are planning to run Log Feeder from an IDE, for running the LogFeeder main methoud, you will need to set the working directory to `ambari/ambari-logsearch/ambari-logsearch-logfeeder` and use `--monitor` as a command line argument.
+With Maven, you won't need these steps, just run this command from the ambari-logsearch-logfeeder folder:
+
```bash
-mkdir /opt/logfeeder
-cd /opt/logfeeder
-tar xfz ~/logsearch-logfeeder.tar.gz
+mvn clean package -DskipTests exec:java
```
# Input Configuration
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
index b1b6ece..6b7d94f 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
@@ -220,7 +220,9 @@
</executions>
<configuration>
<mainClass>org.apache.ambari.logfeeder.LogFeeder</mainClass>
- <!-- <arguments> <argument></argument> </arguments> -->
+ <arguments>
+ <argument>--monitor</argument>
+ </arguments>
</configuration>
</plugin>
<!-- copy-dependencies -->
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore
new file mode 100644
index 0000000..dfb10d6
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore
@@ -0,0 +1,4 @@
+logs/*.log
+shipper-conf/input.config-*.json
+!shipper-conf/input.config-sample.json
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt
new file mode 100644
index 0000000..21048ac
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt
@@ -0,0 +1,3 @@
+2016-07-13 10:45:49,640 [WARN] Sample log line 1 - warn level
+2016-07-13 10:45:49,640 [ERROR] Sample log line 2 - error level
+2016-07-13 10:45:50,351 [INFO] Sample log line 3 - info level
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json
new file mode 100644
index 0000000..6b8602c
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json
@@ -0,0 +1,10 @@
+{
+ "global":{
+ "add_fields":{
+ "cluster":"cl1"
+ },
+ "source":"file",
+ "tail":"true",
+ "gen_event_md5":"true"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json
new file mode 100644
index 0000000..4ab2eb2
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json
@@ -0,0 +1,31 @@
+{
+ "input": [
+ {
+ "type": "service_sample",
+ "rowtype": "service",
+ "path": "target/classes/log-samples/logs/service_sample.txt"
+ }
+ ],
+ "filter": [
+ {
+ "filter": "grok",
+ "conditions": {
+ "fields": {
+ "type": [
+ "service_sample"
+ ]
+ }
+ },
+ "log4j_format": "",
+ "multiline_pattern": "^(%{TIMESTAMP_ISO8601:logtime})",
+ "message_pattern": "(?m)^%{TIMESTAMP_ISO8601:logtime}%{SPACE}\\[%{LOGLEVEL:level}\\]%{SPACE}%{GREEDYDATA:log_message}",
+ "post_map_values": {
+ "logtime": {
+ "map_date": {
+ "date_pattern": "yyyy-MM-dd HH:mm:ss,SSS"
+ }
+ }
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json
new file mode 100644
index 0000000..94b44da
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json
@@ -0,0 +1,34 @@
+{
+ "output": [
+ {
+ "is_enabled": "true",
+ "comment": "Output to solr for service logs",
+ "destination": "solr",
+ "zk_connect_string": "localhost:2181",
+ "type": "service",
+ "skip_logtime": "true",
+ "conditions": {
+ "fields": {
+ "rowtype": [
+ "service"
+ ]
+ }
+ }
+ },
+ {
+ "comment": "Output to solr for audit records",
+ "is_enabled": "true",
+ "destination": "solr",
+ "zk_connect_string": "localhost:2181",
+ "type": "audit",
+ "skip_logtime": "true",
+ "conditions": {
+ "fields": {
+ "rowtype": [
+ "audit"
+ ]
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
index 8d5174e..eb20665 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
@@ -28,7 +28,7 @@
</appender>
<appender name="daily_rolling_file" class="org.apache.log4j.DailyRollingFileAppender">
- <param name="file" value="logs/logsearch-logfeeder.log" />
+ <param name="file" value="target/logs/logsearch-logfeeder.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" />
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
@@ -38,7 +38,7 @@
<appender name="rolling_file_json"
class="org.apache.ambari.logsearch.appender.LogsearchRollingFileAppender">
- <param name="file" value="logs/logsearch-logfeeder.json" />
+ <param name="file" value="target/logs/logsearch-logfeeder.json" />
<param name="append" value="true" />
<param name="maxFileSize" value="10MB" />
<param name="maxBackupIndex" value="10" />
http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
index 74ea0ef..115778b 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
@@ -13,19 +13,24 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-logfeeder.checkpoint.folder=
+cluster.name=cl1
+logfeeder.checkpoint.folder=target/checkpoints
logfeeder.metrics.collector.hosts=
-
-#filter config
-logfeeder.log.filter.enable=false
+logfeeder.config.dir=target/classes/log-samples/shipper-conf/
+logfeeder.config.files=target/classes/log-samples/shipper-conf/global.config.json,\
+ target/classes/log-samples/shipper-conf/input.config-sample.json,\
+ target/classes/log-samples/shipper-conf/output.config-sample.json
+logfeeder.log.filter.enable=true
logfeeder.solr.config.interval=5
-logfeeder.solr.zk_connect_string=
-logfeeder.solr.url=
-
-logfeeder.solr.kerberos.enable=false
-logfeeder.solr.jaas.file=/usr/lib/ambari-logsearch-logfeeder/logsearch_solr_jaas.conf
-
-#logfeeder tmp dir
-logfeeder.tmp.dir=/tmp/$username/logfeeder/
-
logfeeder.solr.core.config.name=history
+logfeeder.solr.zk_connect_string=localhost:2181
+logfeeder.cache.enabled=true
+logfeeder.cache.size=100
+logfeeder.cache.key.field=log_message
+logfeeder.cache.dedup.interval=1000
+logfeeder.cache.last.dedup.enabled=true
+logsearch.config.zk_connect_string=localhost:2181
+logfeeder.include.default.level=FATAL,ERROR,WARN,INFO,DEBUG,TRACE,UNKNOWN
+
+#logfeeder tmp dir
+logfeeder.tmp.dir=target/tmp
[43/51] [abbrv] ambari git commit: AMBARI-22412. Remove IPA
integration from experimental status (rlevas)
Posted by nc...@apache.org.
AMBARI-22412. Remove IPA integration from experimental status (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/22b2d55f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/22b2d55f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/22b2d55f
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 22b2d55f646ebd965834e43536056c5f229e236e
Parents: 98915a1
Author: Robert Levas <rl...@hortonworks.com>
Authored: Fri Nov 10 10:46:01 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Fri Nov 10 10:46:01 2017 -0500
----------------------------------------------------------------------
ambari-web/app/config.js | 1 -
.../main/admin/kerberos/step1_controller.js | 52 +++++++++-----------
ambari-web/app/messages.js | 2 +-
.../admin/kerberos/step1_controller_test.js | 17 -------
4 files changed, 23 insertions(+), 49 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/app/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js
index 0963f70..8dbbde3 100644
--- a/ambari-web/app/config.js
+++ b/ambari-web/app/config.js
@@ -82,7 +82,6 @@ App.supports = {
serviceAutoStart: true,
logSearch: true,
redhatSatellite: false,
- enableIpa: false,
addingNewRepository: false,
kerberosStackAdvisor: true,
logCountVizualization: false,
http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
index 2e41e3d..9c864a8 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
@@ -25,29 +25,6 @@ App.KerberosWizardStep1Controller = Em.Controller.extend({
isSubmitDisabled: Em.computed.someBy('selectedOption.preConditions', 'checked', false),
- ipaOption: Em.Object.create({
- displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
- value: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
- preConditions: [
- Em.Object.create({
- displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.1'),
- checked: false
- }),
- Em.Object.create({
- displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.2'),
- checked: false
- }),
- Em.Object.create({
- displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.3'),
- checked: false
- }),
- Em.Object.create({
- displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.4'),
- checked: false
- })
- ]
- }),
-
options: Em.A([
Em.Object.create({
displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
@@ -94,6 +71,28 @@ App.KerberosWizardStep1Controller = Em.Controller.extend({
]
}),
Em.Object.create({
+ displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
+ value: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
+ preConditions: [
+ Em.Object.create({
+ displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.1'),
+ checked: false
+ }),
+ Em.Object.create({
+ displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.2'),
+ checked: false
+ }),
+ Em.Object.create({
+ displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.3'),
+ checked: false
+ }),
+ Em.Object.create({
+ displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.4'),
+ checked: false
+ })
+ ]
+ }),
+ Em.Object.create({
displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.manual'),
value: Em.I18n.t('admin.kerberos.wizard.step1.option.manual'),
preConditions: [
@@ -135,13 +134,6 @@ App.KerberosWizardStep1Controller = Em.Controller.extend({
loadStep: function () {
- if (App.get('supports.enableIpa')) {
- var ipaOption = this.get('ipaOption');
- var options = this.get('options');
- if (options.indexOf(ipaOption) === -1){
- options.pushObject(ipaOption);
- }
- }
},
submit: function () {
http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index bee581a..390f803 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1273,7 +1273,7 @@ Em.I18n.translations = {
'admin.kerberos.wizard.step1.option.ad.condition.5': 'The Java Cryptography Extensions (JCE) have been setup on the Ambari Server host and all hosts in the cluster.',
'admin.kerberos.wizard.step1.option.ipa': 'Existing IPA',
'admin.kerberos.wizard.step1.option.ipa.condition.1': 'Cluster hosts are joined to the IPA domain and hosts are registered in DNS',
- 'admin.kerberos.wizard.step1.option.ipa.condition.2': 'A password policy in place that sets no expiry for created principals or krbPasswordExpiry attribute is writable',
+ 'admin.kerberos.wizard.step1.option.ipa.condition.2': 'A password policy in place that sets no expiry for created principals',
'admin.kerberos.wizard.step1.option.ipa.condition.3': 'The ipa managed krb5.conf sets default_ccache_name = /tmp/krb5cc_%{uid}',
'admin.kerberos.wizard.step1.option.ipa.condition.4': 'The Java Cryptography Extensions (JCE) have been setup on the Ambari Server host and all hosts in the cluster.',
'admin.kerberos.wizard.step1.prerequisites.label': 'Following prerequisites needs to be checked to progress ahead in the wizard.',
http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
index ca80341..e5a185e 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
@@ -46,23 +46,6 @@ describe('App.KerberosWizardStep1Controller', function() {
controller.set('options', []);
});
- it("enableIpa is true", function() {
- App.set('supports.enableIpa', true);
- controller.loadStep();
- expect(controller.get('selectedItem')).to.be.equal(Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'));
- expect(controller.get('options')).to.not.be.empty;
- controller.loadStep();
- var options = controller.get('options');
- expect(options.length).to.be.equal(1);
- });
-
- it("enableIpa is false", function() {
- App.set('supports.enableIpa', false);
- controller.loadStep();
- expect(controller.get('selectedItem')).to.be.equal(Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'));
- expect(controller.get('options')).to.be.empty;
- });
-
it("on load selected item should not change", function() {
controller.set('selectedItem',Em.I18n.t('admin.kerberos.wizard.step3.option.kdc'));
controller.loadStep();
[05/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement
new design for Admin View. (atkach)
Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js
deleted file mode 100644
index f03dcb5..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js
+++ /dev/null
@@ -1,215 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-describe('#MainCtrl', function () {
-
- var scope, ctrl, $httpBackend, $window, clusterService, deferred;
-
- beforeEach(function () {
- module('ambariAdminConsole', function ($provide) {
- $provide.value('$window', {
- location: {
- pathname: 'http://c6401.ambari.apache.org:8080/views/ADMIN_VIEW/2.0.0/INSTANCE/#/'
- },
- localStorage: {
- getItem: function () {
- return null;
- },
- setItem: angular.noop
- }
- });
- localStorage.ambari = JSON.stringify({
- app: {
- authenticated: true,
- loginName: 'admin',
- user: 'user'
- }
- });
- });
- inject(function (_$httpBackend_, $rootScope, $controller, _$window_, _Cluster_, _$q_) {
- clusterService = _Cluster_;
- deferred = _$q_.defer();
- spyOn(clusterService, 'getStatus').andReturn(deferred.promise);
- deferred.resolve({
- Clusters: {
- provisioning_state: 'INIT'
- }
- });
- $window = _$window_;
- $httpBackend = _$httpBackend_;
- $httpBackend.whenGET(/api\/v1\/services\/AMBARI\/components\/AMBARI_SERVER.+/).respond(200, {
- RootServiceComponents: {
- component_version: 2.2,
- properties: {
- 'user.inactivity.timeout.default': 20
- }
- }
- });
- $httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
- "href": "http://c6401.ambari.apache.org:8080/api/v1/views?fields=versions/instances/ViewInstanceInfo&versions/ViewVersionInfo/system=false&versions/instances/ViewInstanceInfo/visible=true",
- "items": [
- {
- "ViewInfo": {
- "view_name": "SLIDER"
- },
- "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER",
- "versions": [
- {
- "ViewVersionInfo": {
- "system": false,
- "version": "1.0.0",
- "view_name": "SLIDER"
- },
- "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0",
- "instances": [
- {
- "ViewInstanceInfo": {
- "context_path": "/views/SLIDER/1.0.0/VisibleInstance",
- "description": "VisibleInstance",
- "icon64_path": null,
- "icon_path": null,
- "instance_data": {},
- "instance_name": "VisibleInstance",
- "label": "VisibleInstance",
- "properties": {
- "ambari.server.password": "123",
- "ambari.server.url": "123",
- "ambari.server.username": "123",
- "slider.user": null,
- "view.kerberos.principal": null,
- "view.kerberos.principal.keytab": null
- },
- "static": false,
- "version": "1.0.0",
- "view_name": "SLIDER",
- "visible": true
- },
- "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0/instances/VisibleInstance"
- }
- ]
- }
- ]
- }
- ]
- });
- $httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, {
- data: {
- data: {
- addingNewRepository: true
- }
- }
- });
- scope = $rootScope.$new();
- scope.$apply();
- ctrl = $controller('MainCtrl', {
- $scope: scope
- });
- });
- });
-
- afterEach(function() {
- $httpBackend.verifyNoOutstandingExpectation();
- $httpBackend.verifyNoOutstandingRequest();
- });
-
- describe('signout', function () {
-
- beforeEach(function () {
- $httpBackend.whenGET(/\/api\/v1\/logout\?_=\d+/).respond(200,{
- message: "successfully logged out"
- });
- $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
- items: [
- {
- AuthorizationInfo: {
- authorization_id: "AMBARI.RENAME_CLUSTER"
- }
- }
- ]
- });
- });
-
- it('should reset window.location and ambari localstorage', function () {
- scope.signOut();
-
- runs(function() {
- chai.expect($window.location.pathname).to.equal('/');
- });
-
- var data = JSON.parse(localStorage.ambari);
- chai.expect(data.app.authenticated).to.equal(undefined);
- chai.expect(data.app.loginName).to.equal(undefined);
- chai.expect(data.app.user).to.equal(undefined);
- $httpBackend.flush();
- });
-
- it('should get visible view instances and show them in top nav menu', function() {
- $httpBackend.flush();
-
- chai.expect(scope.viewInstances.length).to.equal(1);
- chai.expect(scope.viewInstances[0].instance_name).to.equal('VisibleInstance');
- });
- });
-
- describe('roles loading', function () {
-
- var mock = {
- callback: angular.noop
- },
- cases = [
- {
- canPersistData: true,
- items: [
- {
- AuthorizationInfo: {
- authorization_id: 'CLUSTER.MANAGE_USER_PERSISTED_DATA'
- }
- }
- ],
- title: 'user can persist data'
- },
- {
- canPersistData: false,
- items: [],
- title: 'user can\'t persist data'
- }
- ];
-
- angular.forEach(cases, function (item) {
-
- describe(item.title, function () {
-
- beforeEach(function () {
- $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
- items: item.items
- });
- spyOn(mock, 'callback');
- scope.authDataLoad.promise.then(mock.callback);
- $httpBackend.flush();
- });
-
- it('authDataLoad should be resolved with the correct argument', function () {
- expect(mock.callback).toHaveBeenCalledWith(item.canPersistData);
- });
-
- });
-
- });
-
- });
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
index 6b0b17f..d17747b 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
@@ -39,7 +39,7 @@ describe('Utility Service', function () {
});
scope = $rootScope.$new();
scope.$apply();
- ctrl = $controller('MainCtrl', {
+ ctrl = $controller('AppCtrl', {
$scope: scope
});
httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, {});
@@ -54,6 +54,7 @@ describe('Utility Service', function () {
httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
items: []
});
+ httpBackend.whenGET("views/main.html").respond(200, {});
});
});
[17/51] [abbrv] ambari git commit: AMBARI-22368 Log Search UI: move
top menu down. (Istvan Tobias via ababiichuk)
Posted by nc...@apache.org.
AMBARI-22368 Log Search UI: move top menu down. (Istvan Tobias via ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/976153f9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/976153f9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/976153f9
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 976153f96bc333ad6f50196edba0ce2edb8e9078
Parents: 1afee60
Author: Istvan Tobias <to...@gmail.com>
Authored: Mon Nov 6 19:14:42 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Mon Nov 6 19:19:15 2017 +0200
----------------------------------------------------------------------
.../ambari-logsearch-web/src/app/app.module.ts | 2 +
.../action-menu/action-menu.component.html | 20 ++++
.../action-menu/action-menu.component.less | 27 +++++
.../action-menu/action-menu.component.spec.ts | 47 +++++++++
.../action-menu/action-menu.component.ts | 105 +++++++++++++++++++
.../src/app/components/app.component.html | 4 +-
.../src/app/components/app.component.less | 5 +-
.../logs-container.component.html | 58 +++++-----
.../logs-container.component.less | 3 +
.../main-container.component.html | 2 +-
.../src/app/components/mixins.less | 5 +
.../components/top-menu/top-menu.component.html | 10 +-
.../components/top-menu/top-menu.component.less | 1 +
.../components/top-menu/top-menu.component.ts | 83 +--------------
.../src/app/components/variables.less | 3 +
15 files changed, 261 insertions(+), 114 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index 37cd869..488437e 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -73,6 +73,7 @@ import {PaginationComponent} from '@app/components/pagination/pagination.compone
import {PaginationControlsComponent} from '@app/components/pagination-controls/pagination-controls.component';
import {TimeHistogramComponent} from '@app/components/time-histogram/time-histogram.component';
import {LogsContainerComponent} from '@app/components/logs-container/logs-container.component';
+import {ActionMenuComponent} from "@app/components/action-menu/action-menu.component";
import {ModalComponent} from '@app/components/modal/modal.component';
import {TimeZonePickerComponent} from '@app/components/timezone-picker/timezone-picker.component';
import {NodeBarComponent} from '@app/components/node-bar/node-bar.component';
@@ -125,6 +126,7 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
PaginationControlsComponent,
TimeHistogramComponent,
LogsContainerComponent,
+ ActionMenuComponent,
ModalComponent,
TimeZonePickerComponent,
NodeBarComponent,
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html
new file mode 100644
index 0000000..ab6326a
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html
@@ -0,0 +1,20 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<menu-button *ngFor="let item of items" label="{{item.label | translate}}" [action]="item.action"
+ [iconClass]="item.iconClass" [labelClass]="item.labelClass" [subItems]="item.subItems"
+ [hideCaret]="item.hideCaret" [badge]="item.badge" [isRightAlign]="item.isRightAlign">
+</menu-button>
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less
new file mode 100644
index 0000000..880a97b
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+@import '../variables';
+
+:host {
+ display: block;
+ margin-left: auto;
+ menu-button {
+ margin: 0 1em;
+ color: @table-border-color;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts
new file mode 100644
index 0000000..081304e
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {TranslationModules} from '@app/test-config.spec';
+
+import {ActionMenuComponent} from './action-menu.component';
+
+describe('ActionMenuComponent', () => {
+ let component: ActionMenuComponent;
+ let fixture: ComponentFixture<ActionMenuComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: TranslationModules,
+ declarations: [ActionMenuComponent],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ActionMenuComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts
new file mode 100644
index 0000000..58e0025
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts
@@ -0,0 +1,105 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import {Component} from '@angular/core';
+
+@Component({
+ selector: 'action-menu',
+ templateUrl: './action-menu.component.html',
+ styleUrls: ['./action-menu.component.less']
+})
+export class ActionMenuComponent {
+
+ //TODO implement loading of real data into subItems
+ readonly items = [
+ {
+ iconClass: 'fa fa-arrow-left',
+ label: 'topMenu.undo',
+ labelClass: 'unstyled-link',
+ action: 'undo',
+ subItems: [
+ {
+ label: 'Apply \'Last week\' filter'
+ },
+ {
+ label: 'Clear all filters'
+ },
+ {
+ label: 'Apply \'HDFS\' filter'
+ },
+ {
+ label: 'Apply \'Errors\' filter'
+ }
+ ]
+ },
+ {
+ iconClass: 'fa fa-arrow-right',
+ label: 'topMenu.redo',
+ labelClass: 'unstyled-link',
+ action: 'redo',
+ subItems: [
+ {
+ label: 'Apply \'Warnings\' filter'
+ },
+ {
+ label: 'Switch to graph mode'
+ },
+ {
+ label: 'Apply \'Custom Date\' filter'
+ }
+ ]
+ },
+ {
+ iconClass: 'fa fa-refresh',
+ label: 'topMenu.refresh',
+ labelClass: 'unstyled-link',
+ action: 'refresh'
+ },
+ {
+ iconClass: 'fa fa-history',
+ label: 'topMenu.history',
+ labelClass: 'unstyled-link',
+ action: 'openHistory',
+ isRightAlign: true,
+ subItems: [
+ {
+ label: 'Apply \'Custom Date\' filter'
+ },
+ {
+ label: 'Switch to graph mode'
+ },
+ {
+ label: 'Apply \'Warnings\' filter'
+ },
+ {
+ label: 'Apply \'Last week\' filter'
+ },
+ {
+ label: 'Clear all filters'
+ },
+ {
+ label: 'Apply \'HDFS\' filter'
+ },
+ {
+ label: 'Apply \'Errors\' filter'
+ }
+ ]
+ }
+ ];
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
index a0444c9..833f43f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
@@ -18,8 +18,8 @@
<header>
<nav class="navbar navbar-fixed-top">
<div class="container-fluid">
- <h1 [ngClass]="{'full-flex-width': !isAuthorized, 'navbar-left': true}">{{'common.title' | translate}}</h1>
- <top-menu *ngIf="isAuthorized" class="navbar-right"></top-menu>
+ <h1 [ngClass]="{'full-flex-width': !isAuthorized, 'pull-left': true}">{{'common.title' | translate}}</h1>
+ <top-menu *ngIf="isAuthorized"></top-menu>
</div>
</nav>
</header>
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
index 8731582..f0fecfc 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
@@ -31,11 +31,10 @@
color: #fff;
.container-fluid {
- .default-flex;
+ .stretch-flex;
}
h1 {
- flex-basis: 70%;
margin-bottom: @h1-vertical-margin;
text-transform: uppercase;
@@ -45,7 +44,7 @@
}
/deep/ top-menu {
- flex-basis: 30%;
+ margin-left: auto;
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
index 70150a5..2c3a3b9 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
@@ -15,30 +15,40 @@
limitations under the License.
-->
-<div class="tabs-container row">
- <tabs class="col-md-12" [items]="tabs | async" (tabSwitched)="onSwitchTab($event)"
- (tabClosed)="onCloseTab($event[0], $event[1])"></tabs>
+<div class="tabs-container container-fluid">
+ <div class="row">
+ <div class="col-md-12">
+ <tabs class="pull-left" [items]="tabs | async" (tabSwitched)="onSwitchTab($event)"
+ (tabClosed)="onCloseTab($event[0], $event[1])"></tabs>
+ <action-menu class="pull-right"></action-menu>
+ </div>
+ </div>
</div>
-<filters-panel class="row" [filtersForm]="filtersForm"></filters-panel>
-<div *ngIf="autoRefreshRemainingSeconds" class="col-md-12">
- <div class="auto-refresh-message pull-right">
- {{'filter.capture.triggeringRefresh' | translate: autoRefreshMessageParams}}
+<div class="container-fluid">
+ <filters-panel class="row" [filtersForm]="filtersForm"></filters-panel>
+ <div class="row">
+ <div *ngIf="autoRefreshRemainingSeconds" class="col-md-12">
+ <div class="auto-refresh-message pull-right">
+ {{'filter.capture.triggeringRefresh' | translate: autoRefreshMessageParams}}
+ </div>
+ </div>
+
+ <!-- TODO use plugin for singular/plural -->
+ <div class="logs-header col-md-12">{{
+ (!totalEventsFoundMessageParams.totalCount ? 'logs.noEventFound' :
+ (totalEventsFoundMessageParams.totalCount === 1 ? 'logs.oneEventFound' : 'logs.totalEventFound'))
+ | translate: totalEventsFoundMessageParams
+ }}</div>
</div>
+ <collapsible-panel openTitle="logs.hideGraph" collapsedTitle="logs.showGraph">
+ <time-histogram [data]="histogramData" [customOptions]="histogramOptions" svgId="service-logs-histogram"
+ (selectArea)="setCustomTimeRange($event[0], $event[1])"></time-histogram>
+ </collapsible-panel>
+ <dropdown-button *ngIf="!isServiceLogsFileView" class="pull-right" label="logs.columns"
+ [options]="availableColumns | async" [isRightAlign]="true" [isMultipleChoice]="true"
+ action="updateSelectedColumns" [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button>
+ <logs-list [logs]="logs | async" [totalCount]="totalCount" [displayedColumns]="displayedColumns"
+ [isServiceLogsFileView]="isServiceLogsFileView" [filtersForm]="filtersForm"></logs-list>
+ <log-context *ngIf="isServiceLogContextView" [hostName]="activeLog.host_name" [componentName]="activeLog.component_name"
+ [id]="activeLog.id"></log-context>
</div>
-<!-- TODO use plugin for singular/plural -->
-<div class="logs-header">{{
- (!totalEventsFoundMessageParams.totalCount ? 'logs.noEventFound' :
- (totalEventsFoundMessageParams.totalCount === 1 ? 'logs.oneEventFound' : 'logs.totalEventFound'))
- | translate: totalEventsFoundMessageParams
-}}</div>
-<collapsible-panel openTitle="logs.hideGraph" collapsedTitle="logs.showGraph">
- <time-histogram [data]="histogramData" [customOptions]="histogramOptions" svgId="service-logs-histogram"
- (selectArea)="setCustomTimeRange($event[0], $event[1])"></time-histogram>
-</collapsible-panel>
-<dropdown-button *ngIf="!isServiceLogsFileView" class="pull-right" label="logs.columns"
- [options]="availableColumns | async" [isRightAlign]="true" [isMultipleChoice]="true"
- action="updateSelectedColumns" [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button>
-<logs-list [logs]="logs | async" [totalCount]="totalCount" [displayedColumns]="displayedColumns"
- [isServiceLogsFileView]="isServiceLogsFileView" [filtersForm]="filtersForm"></logs-list>
-<log-context *ngIf="isServiceLogContextView" [hostName]="activeLog.host_name" [componentName]="activeLog.component_name"
- [id]="activeLog.id"></log-context>
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
index 23d5f92..9902b79 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
@@ -25,6 +25,9 @@
.tabs-container, .auto-refresh-message {
background-color: @filters-panel-background-color;
}
+ .tabs-container {
+ border-bottom: 1px solid @table-border-color;
+ }
filters-panel {
margin-bottom: @block-margin-top;
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
index 2061582..95dd238 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
@@ -20,4 +20,4 @@
<span class="fa fa-spinner fa-spin"></span>
</div>
<login-form *ngIf="!isInitialLoading && !isAuthorized"></login-form>
-<logs-container *ngIf="isAuthorized" class="col-md-12"></logs-container>
+<logs-container *ngIf="isAuthorized"></logs-container>
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
index 2e46213..5fa265b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
@@ -28,6 +28,11 @@
justify-content: space-between;
}
+.stretch-flex {
+ align-items: stretch;
+ display: flex;
+}
+
.common-hexagon(@side, @color) {
display: block;
position: absolute;
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
index a7858a5..369ddd4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
@@ -15,7 +15,9 @@
limitations under the License.
-->
-<menu-button *ngFor="let item of items" label="{{item.label | translate}}" [action]="item.action"
- [iconClass]="item.iconClass" [labelClass]="item.labelClass"
- [subItems]="item.subItems" [hideCaret]="item.hideCaret" [badge]="item.badge">
-</menu-button>
+<div class="pull-right">
+ <menu-button *ngFor="let item of items" label="{{item.label | translate}}" [action]="item.action"
+ [iconClass]="item.iconClass" [labelClass]="item.labelClass" [subItems]="item.subItems"
+ [hideCaret]="item.hideCaret" [badge]="item.badge" [isRightAlign]="item.isRightAlign">
+ </menu-button>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
index 4fe899a..32d1beb 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
@@ -19,4 +19,5 @@
:host {
.default-flex;
+ margin-right: 0;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
index 73b6131..05c1a62 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
@@ -16,98 +16,21 @@
* limitations under the License.
*/
-import {Component, OnInit} from '@angular/core';
+import {Component} from '@angular/core';
@Component({
selector: 'top-menu',
templateUrl: './top-menu.component.html',
styleUrls: ['./top-menu.component.less']
})
-export class TopMenuComponent implements OnInit {
-
- constructor() {
- }
-
- ngOnInit() {
- }
+export class TopMenuComponent {
//TODO implement loading of real data into subItems
readonly items = [
{
- iconClass: 'fa fa-arrow-left',
- label: 'topMenu.undo',
- labelClass: 'unstyled-link',
- action: 'undo',
- subItems: [
- {
- label: 'Apply \'Last week\' filter'
- },
- {
- label: 'Clear all filters'
- },
- {
- label: 'Apply \'HDFS\' filter'
- },
- {
- label: 'Apply \'Errors\' filter'
- }
- ]
- },
- {
- iconClass: 'fa fa-arrow-right',
- label: 'topMenu.redo',
- labelClass: 'unstyled-link',
- action: 'redo',
- subItems: [
- {
- label: 'Apply \'Warnings\' filter'
- },
- {
- label: 'Switch to graph mode'
- },
- {
- label: 'Apply \'Custom Date\' filter'
- }
- ]
- },
- {
- iconClass: 'fa fa-refresh',
- label: 'topMenu.refresh',
- labelClass: 'unstyled-link',
- action: 'refresh'
- },
- {
- iconClass: 'fa fa-history',
- label: 'topMenu.history',
- labelClass: 'unstyled-link',
- action: 'openHistory',
- subItems: [
- {
- label: 'Apply \'Custom Date\' filter'
- },
- {
- label: 'Switch to graph mode'
- },
- {
- label: 'Apply \'Warnings\' filter'
- },
- {
- label: 'Apply \'Last week\' filter'
- },
- {
- label: 'Clear all filters'
- },
- {
- label: 'Apply \'HDFS\' filter'
- },
- {
- label: 'Apply \'Errors\' filter'
- }
- ]
- },
- {
iconClass: 'fa fa-user unstyled-link',
hideCaret: true,
+ isRightAlign: true,
subItems: [
{
label: 'Options'
http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
index 150ac56..7b7fcae 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
@@ -61,3 +61,6 @@
// Icon
@icon-padding: 5px;
+
+// Table
+@table-border-color: #EEEEEE;
[37/51] [abbrv] ambari git commit: AMBARI-22398. Upstart is not able
to stop the ambari-agent (aonishuk)
Posted by nc...@apache.org.
AMBARI-22398. Upstart is not able to stop the ambari-agent (aonishuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e968b121
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e968b121
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e968b121
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: e968b12186848edd7b4e8b7103e8283b61f59c50
Parents: 780e91e
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Thu Nov 9 16:37:58 2017 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Thu Nov 9 16:37:58 2017 +0200
----------------------------------------------------------------------
ambari-agent/src/main/python/ambari_agent/AmbariAgent.py | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e968b121/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py b/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
index 28b9528..aeb200c 100644
--- a/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
+++ b/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
@@ -49,9 +49,6 @@ def main():
mergedArgs = [PYTHON, AGENT_SCRIPT] + args
- # Become a parent for all subprocesses
- os.setpgrp()
-
try:
while status == AGENT_AUTO_RESTART_EXIT_CODE:
mainProcess = subprocess.Popen(mergedArgs)
[49/51] [abbrv] ambari git commit: AMBARI-22387. Create a Pre-Upgrade
Check Warning About LZO (dlysnichenko)
Posted by nc...@apache.org.
AMBARI-22387. Create a Pre-Upgrade Check Warning About LZO (dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/76349ac2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/76349ac2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/76349ac2
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 76349ac20d8955b3f25383b6f4f209a690b38bef
Parents: 5122671
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Mon Nov 13 13:29:52 2017 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Mon Nov 13 13:30:26 2017 +0200
----------------------------------------------------------------------
.../ambari/server/checks/CheckDescription.java | 9 ++
.../apache/ambari/server/checks/LZOCheck.java | 77 ++++++++++
.../HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml | 1 +
.../stacks/HDP/2.3/upgrades/upgrade-2.6.xml | 1 +
.../HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml | 1 +
.../stacks/HDP/2.4/upgrades/upgrade-2.6.xml | 1 +
.../HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml | 1 +
.../stacks/HDP/2.5/upgrades/upgrade-2.6.xml | 1 +
.../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml | 1 +
.../stacks/HDP/2.6/upgrades/upgrade-2.6.xml | 1 +
.../ambari/server/checks/LZOCheckTest.java | 145 +++++++++++++++++++
11 files changed, 239 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
index 3caac14..20bb1b0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
@@ -327,6 +327,15 @@ public class CheckDescription {
"As Ranger is SSL enabled, Ranger SSL configurations will need to be changed from default value of /etc/ranger/*/conf folder to /etc/ranger/security. " +
"Since the certificates/keystores/truststores in this path may affect the upgrade/downgrade process, it is recommended to manually move the certificates/keystores/truststores out of the conf folders and change the appropriate config values before proceeding.").build());
+ public static CheckDescription LZO_CONFIG_CHECK = new CheckDescription("LZO_CONFIG_CHECK",
+ PrereqCheckType.CLUSTER,
+ "LZO Codec Check",
+ new ImmutableMap.Builder<String, String>()
+ .put(AbstractCheckDescriptor.DEFAULT,
+ "You have LZO codec enabled in the core-site config of your cluster. LZO is no longer installed automatically. " +
+ "If any hosts require LZO, it should be installed before starting the upgrade. " +
+ "Consult Ambari documentation for instructions on how to do this.").build());
+
public static CheckDescription JAVA_VERSION = new CheckDescription("JAVA_VERSION",
PrereqCheckType.CLUSTER,
"Verify Java version requirement",
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
new file mode 100644
index 0000000..3000b79
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ambari.server.checks;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link LZOCheck}
+ * is used to check that the LZO codec enabled in the core-site config fnd warning if any hosts require LZO, it should be installed before starting the upgrade.
+ */
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.INFORMATIONAL_WARNING)
+public class LZOCheck extends AbstractCheckDescriptor {
+
+ final static String IO_COMPRESSION_CODECS = "io.compression.codecs";
+ final static String LZO_ENABLE_KEY = "io.compression.codec.lzo.class";
+ final static String LZO_ENABLE_VALUE = "com.hadoop.compression.lzo.LzoCodec";
+
+ /**
+ * Constructor.
+ */
+ public LZOCheck() {
+ super(CheckDescription.LZO_CONFIG_CHECK);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
+ List<String> errorMessages = new ArrayList<>();
+ PrereqCheckStatus checkStatus = PrereqCheckStatus.WARNING;
+
+ String codecs = getProperty(request, "core-site", IO_COMPRESSION_CODECS);
+ if (codecs!= null && codecs.contains(LZO_ENABLE_VALUE)) {
+ errorMessages.add(getFailReason(IO_COMPRESSION_CODECS, prerequisiteCheck, request));
+ }
+ String classValue = getProperty(request, "core-site", LZO_ENABLE_KEY);
+
+ if (LZO_ENABLE_VALUE.equals(classValue)) {
+ errorMessages.add(getFailReason(LZO_ENABLE_KEY, prerequisiteCheck, request));
+ }
+
+ if (!errorMessages.isEmpty()) {
+ prerequisiteCheck.setFailReason(StringUtils.join(errorMessages, "You have LZO codec enabled in the core-site config of your cluster. LZO is no longer installed automatically. " +
+ "If any hosts require LZO, it should be installed before starting the upgrade. " +
+ "Consult Ambari documentation for instructions on how to do this."));
+ prerequisiteCheck.getFailedOn().add("LZO");
+ prerequisiteCheck.setStatus(checkStatus);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
index 907626d..bb22c1e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
@@ -24,6 +24,7 @@
<check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
<check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
<check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<configuration>
<!-- Configuration properties for all pre-reqs including required pre-reqs -->
<check-properties name="org.apache.ambari.server.checks.HiveDynamicServiceDiscoveryCheck">
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
index 567e6e1..faf8cbc 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
@@ -36,6 +36,7 @@
<check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
<check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
<check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<!-- Specific to HDP 2.5, Storm is not rolling -->
<check>org.apache.ambari.server.checks.StormShutdownWarning</check>
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
index faf5b76..97824f2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
@@ -24,6 +24,7 @@
<check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
<check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
<check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<configuration>
<!-- Configuration properties for all pre-reqs including required pre-reqs -->
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
index 572a259..9e56d97 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
@@ -37,6 +37,7 @@
<check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
<check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
<check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<!-- Specific to HDP 2.5, Storm is not rolling -->
<check>org.apache.ambari.server.checks.StormShutdownWarning</check>
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
index 8012c90..ace9542 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
@@ -22,6 +22,7 @@
<type>NON_ROLLING</type>
<prerequisite-checks>
<check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<configuration>
<!-- Configuration properties for all pre-reqs including required pre-reqs -->
<check-properties name="org.apache.ambari.server.checks.HiveDynamicServiceDiscoveryCheck">
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
index 7c43948..df11ae1 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
@@ -35,6 +35,7 @@
<check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
<check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
<check>org.apache.ambari.server.checks.DruidHighAvailabilityCheck</check>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<configuration>
<!-- Configuration properties for all pre-reqs including required pre-reqs -->
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
index ae2a855..0355362 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
@@ -21,6 +21,7 @@
<target-stack>HDP-2.6</target-stack>
<type>NON_ROLLING</type>
<prerequisite-checks>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<configuration>
<!-- Configuration properties for all pre-reqs including required pre-reqs -->
<check-properties name="org.apache.ambari.server.checks.HiveDynamicServiceDiscoveryCheck">
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
index 37847a2..5aa2d20 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
@@ -34,6 +34,7 @@
<check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
<check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
<check>org.apache.ambari.server.checks.DruidHighAvailabilityCheck</check>
+ <check>org.apache.ambari.server.checks.LZOCheck</check>
<configuration>
<!-- Configuration properties for all pre-reqs including required pre-reqs -->
http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java
new file mode 100644
index 0000000..e50e936
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ambari.server.checks;
+
+ import java.util.HashMap;
+ import java.util.Map;
+
+ import org.apache.ambari.server.configuration.Configuration;
+ import org.apache.ambari.server.controller.PrereqCheckRequest;
+ import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+ import org.apache.ambari.server.state.Cluster;
+ import org.apache.ambari.server.state.Clusters;
+ import org.apache.ambari.server.state.Config;
+ import org.apache.ambari.server.state.DesiredConfig;
+ import org.apache.ambari.server.state.RepositoryType;
+ import org.apache.ambari.server.state.Service;
+ import org.apache.ambari.server.state.repository.ClusterVersionSummary;
+ import org.apache.ambari.server.state.repository.VersionDefinitionXml;
+ import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+ import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+ import org.junit.Assert;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.runner.RunWith;
+ import org.mockito.Mock;
+ import org.mockito.Mockito;
+ import org.mockito.runners.MockitoJUnitRunner;
+
+ import com.google.inject.Provider;
+
+
+/* Test for LZOCheck */
+@RunWith(MockitoJUnitRunner.class)
+public class LZOCheckTest {
+
+ private final Clusters clusters = Mockito.mock(Clusters.class);
+ private final LZOCheck lZOCheck = new LZOCheck();
+
+ @Mock
+ private ClusterVersionSummary m_clusterVersionSummary;
+
+ @Mock
+ private VersionDefinitionXml m_vdfXml;
+
+ @Mock
+ private RepositoryVersionEntity m_repositoryVersion;
+
+ final Map<String, Service> m_services = new HashMap<>();
+
+ @Before
+ public void setup() throws Exception {
+ lZOCheck.clustersProvider = new Provider<Clusters>() {
+ @Override
+ public Clusters get() {
+ return clusters;
+ }
+ };
+ Configuration config = Mockito.mock(Configuration.class);
+ lZOCheck.config = config;
+
+ m_services.clear();
+
+ Mockito.when(m_repositoryVersion.getType()).thenReturn(RepositoryType.STANDARD);
+ Mockito.when(m_repositoryVersion.getRepositoryXml()).thenReturn(m_vdfXml);
+ Mockito.when(m_vdfXml.getClusterSummary(Mockito.any(Cluster.class))).thenReturn(m_clusterVersionSummary);
+ Mockito.when(m_clusterVersionSummary.getAvailableServiceNames()).thenReturn(m_services.keySet());
+ }
+
+ @Test
+ public void testIsApplicable() throws Exception {
+ final Cluster cluster = Mockito.mock(Cluster.class);
+
+ Mockito.when(cluster.getServices()).thenReturn(m_services);
+ Mockito.when(cluster.getClusterId()).thenReturn(1L);
+ Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
+
+ PrereqCheckRequest request = new PrereqCheckRequest("cluster");
+ request.setTargetRepositoryVersion(m_repositoryVersion);
+
+ Assert.assertTrue(lZOCheck.isApplicable(request));
+ }
+
+ @Test
+ public void testPerform() throws Exception {
+ final Cluster cluster = Mockito.mock(Cluster.class);
+ final Map<String, Service> services = new HashMap<>();
+ final Service service = Mockito.mock(Service.class);
+
+ Mockito.when(cluster.getServices()).thenReturn(services);
+ Mockito.when(cluster.getClusterId()).thenReturn(1L);
+ Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
+
+ final DesiredConfig desiredConfig = Mockito.mock(DesiredConfig.class);
+ Mockito.when(desiredConfig.getTag()).thenReturn("tag");
+ Map<String, DesiredConfig> configMap = new HashMap<>();
+ configMap.put("core-site", desiredConfig);
+
+ Mockito.when(cluster.getDesiredConfigs()).thenReturn(configMap);
+ final Config config = Mockito.mock(Config.class);
+ Mockito.when(cluster.getConfig(Mockito.anyString(), Mockito.anyString())).thenReturn(config);
+ final Map<String, String> properties = new HashMap<>();
+ Mockito.when(config.getProperties()).thenReturn(properties);
+
+ PrerequisiteCheck check = new PrerequisiteCheck(null, null);
+ lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+
+
+ properties.put(LZOCheck.IO_COMPRESSION_CODECS,"test," + LZOCheck.LZO_ENABLE_VALUE);
+ check = new PrerequisiteCheck(null, null);
+ lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus());
+
+ properties.put(LZOCheck.IO_COMPRESSION_CODECS,"test");
+ check = new PrerequisiteCheck(null, null);
+ lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+
+ properties.put(LZOCheck.LZO_ENABLE_KEY, LZOCheck.LZO_ENABLE_VALUE);
+ check = new PrerequisiteCheck(null, null);
+ lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus());
+
+ properties.put(LZOCheck.LZO_ENABLE_KEY, LZOCheck.LZO_ENABLE_VALUE);
+ properties.put(LZOCheck.IO_COMPRESSION_CODECS,"test," + LZOCheck.LZO_ENABLE_VALUE);
+ check = new PrerequisiteCheck(null, null);
+ lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus());
+ }
+}