Juan Hernandez has uploaded a new change for review.

Change subject: core: Add Keystone authenticator
......................................................................

core: Add Keystone authenticator

This patch adds an initial version of the OpenStack Keystone
authenticator. It performs authentication connnecting to the Keystone
service and requesting a token using the configured URL and tenant and
the given user name.

To enable this authenticator create a configuration file with the
following content to the /etc/ovirt-engine/auth.d directory:

  #
  # The name of the authentication profile, this should match
  # the name of the tenant, but this isn't enforced:
  #
  name=mytenant

  #
  # The type of the authenticator:
  #
  authenticator.type=keystone

  #
  # Keystone specific parameters:
  #
  keystone.url=http://server:5000/v3
  keystone.tenant=mytenant

  #
  # The type of the directory:
  #
  directory.type=nop

Note that this patch doesn't add a Keystone directory, that will be
added in later patches.

Also note that this authenticator doesn't yet support TLS for the
communications with the Keystone server. This is a must for real
environments and will be added in later patches or in a later
incarnation of this same patch.

Change-Id: I9588f015ac8766e38163665e4eec68b9d5638a6d
Signed-off-by: Juan Hernandez <juan.hernan...@redhat.com>
---
M backend/manager/modules/authentication/pom.xml
A 
backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticator.java
A 
backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticatorFactory.java
M 
backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
4 files changed, 177 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/49/21149/1

diff --git a/backend/manager/modules/authentication/pom.xml 
b/backend/manager/modules/authentication/pom.xml
index 179834f..47a967e 100644
--- a/backend/manager/modules/authentication/pom.xml
+++ b/backend/manager/modules/authentication/pom.xml
@@ -34,6 +34,18 @@
       <artifactId>commons-lang</artifactId>
     </dependency>
 
+    <dependency>
+      <groupId>com.woorea</groupId>
+      <artifactId>keystone-client</artifactId>
+      <version>${openstack-client.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.woorea</groupId>
+      <artifactId>keystone-model</artifactId>
+      <version>${openstack-client.version}</version>
+    </dependency>
+
   </dependencies>
 
   <build>
diff --git 
a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticator.java
 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticator.java
new file mode 100644
index 0000000..dab544f
--- /dev/null
+++ 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticator.java
@@ -0,0 +1,92 @@
+package org.ovirt.engine.core.authentication.openstack;
+
+import com.woorea.openstack.base.client.OpenStackResponseException;
+import com.woorea.openstack.keystone.Keystone;
+import com.woorea.openstack.keystone.api.TokensResource;
+import org.ovirt.engine.core.authentication.PasswordAuthenticator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This authenticator authenticates the internal connecting to a OpenStack 
Keystone identity management server. To
+ * configure it create a an authenticator profile like this:
+ *
+ * <pre>
+ * name=keystone
+ * module=org.ovirt.engine.core.authentication
+ * authenticator.type=keystone
+ * keystone.url=http://server:5000/v3
+ * keystone.tenant=mytenant
+ * directory.type=nop
+ * </pre>
+ */
+public class KeystoneAuthenticator implements PasswordAuthenticator {
+    // The log:
+    private static final Logger log = 
LoggerFactory.getLogger(KeystoneAuthenticator.class);
+
+    // The name of the authenticator:
+    private String name;
+
+    // The name of the tenant:
+    private String tenant;
+
+    // The Keystone client:
+    private Keystone client;
+
+    /**
+     * Create a new Keystone authenticator.
+     *
+     * @param name the name of the authenticator
+     * @param url the URL of the Keystone service
+     * @param tenant the name of the Keystone tenant
+     */
+    public KeystoneAuthenticator(String name, String url, String tenant) {
+        // Save the name of the authenticator and the tenant:
+        this.name = name;
+        this.tenant = tenant;
+
+        // Create the Keystone client:
+        client = new Keystone(url);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean authenticate(String user, char[] password) {
+        // Create the authentiction request:
+        TokensResource.Authenticate request = client.tokens().authenticate()
+            .withUsernamePassword(user, new String(password))
+            .withTenantName(tenant);
+
+        // Execute the request, if it succeeds without an exception then the 
user is correctly authenticaticated (note
+        // that we don't really need the returned token, just need to check if 
the request succeeds or not):
+        try {
+            request.execute();
+            return true;
+        }
+        catch (OpenStackResponseException exception) {
+            // The 401 response code corresponds to authentication failure, 
whilest other codes may indicate
+            // configuration problems, so in those cases it is worth sending 
the complete stack trace to the log:
+            if (exception.getStatus() != 401) {
+                log.warn(
+                    "Keystone authentication for user \"{}\" failed with error 
code \"{}\", this may indicate a " +
+                    "configuration problem.",
+                    user,
+                    exception.getStatus(),
+                    exception
+                );
+            }
+            return false;
+        }
+    }
+}
diff --git 
a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticatorFactory.java
 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticatorFactory.java
new file mode 100644
index 0000000..57749ec
--- /dev/null
+++ 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/openstack/KeystoneAuthenticatorFactory.java
@@ -0,0 +1,72 @@
+package org.ovirt.engine.core.authentication.openstack;
+
+import java.io.File;
+
+import org.ovirt.engine.core.authentication.Authenticator;
+import org.ovirt.engine.core.authentication.AuthenticatorFactory;
+import org.ovirt.engine.core.authentication.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class KeystoneAuthenticatorFactory implements AuthenticatorFactory {
+    // The log:
+    private static final Logger log = 
LoggerFactory.getLogger(KeystoneAuthenticatorFactory.class);
+
+    // The type supported by this factory:
+    private static final String TYPE = "keystone";
+
+    // Names of configuration views:
+    private static final String KEYSTONE_VIEW = "keystone";
+
+    // Names of the configuration parameters:
+    private static final String NAME_PARAMETER = "name";
+    private static final String URL_PARAMETER = "url";
+    private static final String TENANT_PARAMETER = "tenant";
+
+    @Override
+    public String getType() {
+        return TYPE;
+    }
+
+    @Override
+    public Authenticator create(File file, Configuration config) {
+        // Get the name of the authenticator:
+        String name = config.getInheritedString(NAME_PARAMETER);
+        if (name == null) {
+            log.error(
+                "The configuration file \"{}\" doesn't contain the name of the 
authenticator.",
+                file.getAbsolutePath()
+            );
+            return null;
+        }
+
+        // Get the Keystone vuew:
+        Configuration keystoneView = config.getInheritedView(KEYSTONE_VIEW);
+
+        // Get the Keystone URL:
+        String url = keystoneView.getString(URL_PARAMETER);
+        if (url == null) {
+            log.error(
+                "The configuration file \"{}\" doesn't contain the parameter 
\"{}\", this is mandatory and should " +
+                "contain the URL of the Keystone service.",
+                file.getAbsolutePath(),
+                keystoneView.getAbsoluteKey(URL_PARAMETER)
+            );
+            return null;
+        }
+
+        // Get the name of the tenant:
+        String tenant = keystoneView.getString(TENANT_PARAMETER);
+        if (tenant == null) {
+            log.error(
+                "The configuration file \"{}\" doesn't contain the parameter 
\"{}\", this is mandatory and should " +
+                "contain the name of the OpenStack tenant.",
+                keystoneView.getAbsoluteKey(TENANT_PARAMETER)
+            );
+            return null;
+        }
+
+        // We are good, create the authenticator:
+        return new KeystoneAuthenticator(name, url, tenant);
+    }
+}
diff --git 
a/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
 
b/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
index 2bea66f..e5e211f 100644
--- 
a/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
+++ 
b/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
@@ -5,4 +5,5 @@
 org.ovirt.engine.core.authentication.header.HeaderAuthenticatorFactory
 org.ovirt.engine.core.authentication.internal.InternalAuthenticatorFactory
 
org.ovirt.engine.core.authentication.kerberos.KerberosPasswordAuthenticatorFactory
+org.ovirt.engine.core.authentication.openstack.KeystoneAuthenticatorFactory
 org.ovirt.engine.core.authentication.nop.NopAuthenticatorFactory


-- 
To view, visit http://gerrit.ovirt.org/21149
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9588f015ac8766e38163665e4eec68b9d5638a6d
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <juan.hernan...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to