You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2014/08/18 11:43:26 UTC

[01/22] git commit: updated refs/heads/saml2 to 54986d5

Repository: cloudstack
Updated Branches:
  refs/heads/saml2 d8aee7196 -> 54986d58a (forced update)


GUI changes to leverage a new control for storage tags


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fd6d083a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fd6d083a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fd6d083a

Branch: refs/heads/saml2
Commit: fd6d083ad649af0fee64d0c70be0227b5504fb00
Parents: 34b698d
Author: seif <se...@gmail.com>
Authored: Thu Aug 14 15:43:06 2014 -0600
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Sun Aug 17 17:18:51 2014 -0600

----------------------------------------------------------------------
 ui/lib/jquery.tokeninput.js         |  3 +-
 ui/scripts/sharedFunctions.js       | 50 +++++++++++++++++++
 ui/scripts/system.js                | 34 ++++++++++++-
 ui/scripts/ui/dialog.js             | 32 ------------
 ui/scripts/ui/widgets/detailView.js | 83 +++++++++++++++++++++++++++++++-
 5 files changed, 166 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fd6d083a/ui/lib/jquery.tokeninput.js
----------------------------------------------------------------------
diff --git a/ui/lib/jquery.tokeninput.js b/ui/lib/jquery.tokeninput.js
index 1a684d2..638ce68 100644
--- a/ui/lib/jquery.tokeninput.js
+++ b/ui/lib/jquery.tokeninput.js
@@ -206,6 +206,7 @@ $.TokenList = function (input, url_or_data, settings) {
             outline: "none"
         })
         .attr("id", settings.idPrefix + input.id)
+        .attr("name", settings.idPrefix + input.id)
         .focus(function () {
             if (settings.tokenLimit === null || settings.tokenLimit !== token_count) {
                 show_dropdown_hint();
@@ -218,7 +219,7 @@ $.TokenList = function (input, url_or_data, settings) {
 
             if ((lastChar === ',' || lastChar === ' ') && ($.trim($(this).val()).length >= 1))
             {
-                var custom_token = { id : $.trim($(this).val().substring(0, longueur - 1)), name : $(this).val().substring(0, longueur - 1) };
+                var custom_token = { id : $.trim($(this).val().substring(0, longueur - 1)), name : $.trim($(this).val().substring(0, longueur - 1)) };
 
                 add_token(custom_token);
                 $(this).val("");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fd6d083a/ui/scripts/sharedFunctions.js
----------------------------------------------------------------------
diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js
index e8c4fcb..bb2d596 100644
--- a/ui/scripts/sharedFunctions.js
+++ b/ui/scripts/sharedFunctions.js
@@ -49,6 +49,56 @@ var md5HashedLogin = false;
 var pageSize = 20;
 //var pageSize = 1; //for testing only
 
+function to_json_array(str) {
+    var simple_array = str.split(",");
+    var json_array = [];
+
+    $.each(simple_array, function(index, value) {
+        if ($.trim(value).length > 0) {
+            var obj = {
+                          id: value,
+                          name: value
+                      };
+
+            json_array.push(obj);
+        }
+    });
+
+    return json_array;
+}
+
+function _tag_equals(tag1, tag2) {
+    return (tag1.name == tag2.name) && (tag1.id == tag2.id);
+}
+
+function _tag_array_contains(tag, tags)
+{
+    for (var i = 0; i < tags.length; i++)
+    {
+        if (_tag_equals(tags[i], tag)) return true;
+    }
+
+    return false;
+}
+
+function unique_tags(tags)
+{
+    var unique = [];
+
+    if (tags != null)
+    {
+        for (var i = 0; i < tags.length; i++)
+        {
+            if (!_tag_array_contains(tags[i], unique))
+            {
+                unique.push(tags[i]);
+            }
+        }
+    }
+
+    return unique;
+}
+
 //async action
 var pollAsyncJobResult = function(args) {
     $.ajax({

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fd6d083a/ui/scripts/system.js
----------------------------------------------------------------------
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index 5c49a1a..db1629f 100644
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -16901,7 +16901,7 @@
 
                                                     if (item != null)
                                                     {
-                                                        tags = $.map(item, function (tag) {
+                                                        tags = $.map(item, function(tag) {
                                                             return {
                                                                        id: tag.name,
                                                                        name: tag.name
@@ -17248,7 +17248,37 @@
                                     },
                                     tags: {
                                         label: 'label.storage.tags',
-                                        isEditable: true
+                                        isTokenInput : true,
+                                        isEditable: true,
+                                        dataProvider: function(args) {
+                                            $.ajax({
+                                                url: createURL("listStorageTags"),
+                                                dataType: "json",
+                                                success: function(json) {
+                                                    var item = json.liststoragetagsresponse.storagetag;
+                                                    var tags = [];
+
+                                                    if (item != null)
+                                                    {
+                                                        tags = $.map(item, function(tag) {
+                                                            return {
+                                                                       id: tag.name,
+                                                                       name: tag.name
+                                                                   };
+                                                        });
+                                                    }
+
+                                                    args.response.success({
+                                                        data: tags
+                                                    });
+                                                },
+                                                error: function (XMLHttpResponse) {
+                                                    var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
+
+                                                    args.response.error(errorMsg);
+                                                }
+                                            });
+                                        }
                                     },
                                     zonename: {
                                         label: 'label.zone'

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fd6d083a/ui/scripts/ui/dialog.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js
index f2ba5c1..87866d5 100644
--- a/ui/scripts/ui/dialog.js
+++ b/ui/scripts/ui/dialog.js
@@ -470,38 +470,6 @@
                         context: args.context,
                         response: {
                             success: function(args) {
-                                function equals(tag1, tag2) {
-                                    return (tag1.name == tag2.name) && (tag1.id == tag2.id);
-                                }
-
-                                function contains(tag, tags)
-                                {
-		                            for (var i = 0; i < tags.length; i++)
-                                    {
-                                        if (equals(tags[i], tag)) return true;
-                                    }
-
-	  	                            return false;
-                                }
-
-                                function unique_tags(tags)
-                                {
-                                    var unique = [];
-
-                                    if (tags != null)
-                                    {
-                                        for (var i = 0; i < tags.length; i++)
-                                        {
-                                            if (!contains(tags[i], unique))
-                                            {
-                                                unique.push(tags[i]);
-                                            }
-                                        }
-                                    }
-
-                                    return unique;
-                                }
-
                                 $input.tokenInput(unique_tags(args.data), { theme: "facebook", preventDuplicates: true });
                             }
                         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fd6d083a/ui/scripts/ui/widgets/detailView.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js
index ed51fad..33d0d14 100644
--- a/ui/scripts/ui/widgets/detailView.js
+++ b/ui/scripts/ui/widgets/detailView.js
@@ -437,6 +437,7 @@
          */
         edit: function($detailView, args) {
             $detailView.addClass('edit-mode');
+            var token_value = "";
 
             if ($detailView.find('.button.done').size()) return false;
 
@@ -472,6 +473,8 @@
 
             var convertInputs = function($inputs) {
                 // Save and turn back into labels
+                var $token;
+                var tags_value = "";
                 $inputs.each(function() {
                     if ($(this).closest('.tagger').size()) return true;
 
@@ -479,9 +482,19 @@
                     var $value = $input.closest('td.value span');
 
                     if ($input.is('input[type=text]'))
+                    {
+                        if ($input.attr('name') === "token-input-")
+                        {
+                            $token = $value;
+                        }
+                        else if ($input.attr('name') === "tags")
+                        {
+                            tags_value = $input.attr('value');
+                        }
                         $value.html(_s(
                             $input.attr('value')
                         ));
+                    }
                     else if ($input.is('input[type=password]')) {
                         $value.html('');
                     } else if ($input.is('input[type=checkbox]')) {
@@ -496,6 +509,8 @@
                         $value.data('detail-view-selected-option', _s($input.find('option:selected').val()));
                     }
                 });
+
+                $token.html(_s(tags_value));
             };
 
             var removeEditForm = function() {
@@ -523,6 +538,11 @@
                     var $value = $input.closest('td.value span');
                     var originalValue = $input.data('original-value');
 
+                    if ($input.attr('id') === 'token-input-')
+                    {
+                        originalValue = token_value;
+                    }
+
                     $value.html(_s(originalValue));
                 });
 
@@ -550,6 +570,7 @@
                         }
                     });
 
+                    data['token-input-'] = data['tags'];
                     $editButton.fadeOut('fast', function() {
                         $editButton.remove();
                     });
@@ -652,6 +673,7 @@
                 // Turn into form field
                 var selectData = $value.data('detail-view-editable-select');
                 var isBoolean = $value.data('detail-view-editable-boolean');
+                var isTokenInput = $value.data('detail-view-is-TokenInput');
                 var data = !isBoolean ? cloudStack.sanitizeReverse($value.html()) : $value.data('detail-view-boolean-value');
                 var rules = $value.data('validation-rules') ? $value.data('validation-rules') : {};
                 var isPassword = $value.data('detail-view-is-password');
@@ -689,6 +711,54 @@
                             checked: data
                         })
                     );
+                } else if (isTokenInput) { // jquery.tokeninput.js
+                    function to_json_array(str) {
+                        var simple_array = str.split(",");
+                        var json_array = [];
+
+                        $.each(simple_array, function(index, value) {
+                            if ($.trim(value).length > 0)
+                            {
+                                var obj = {
+                                    id : value,
+                                    name : value
+                                };
+
+                                json_array.push(obj);
+                            }
+                        });
+
+                        return json_array;
+                    }
+
+                    var existing_tags = to_json_array(data);
+
+                    isAsync = true;
+
+                    selectArgs = {
+                        context: $detailView.data('view-args').context,
+                        response: {
+                            success: function(args) {
+                                $input.tokenInput(unique_tags(args.data),
+                                {
+                                    theme: "facebook",
+                                    preventDuplicates: true,
+                                    prePopulate: existing_tags,
+                                    processPrePopulate: true
+                                });
+                            }
+                        }
+                    };
+
+                    $input = $('<input>').attr({
+                        name: name,
+                        type: 'text',
+                        value: data
+                    }).data('original-value', data);
+
+                    $value.append($input);
+                    token_value = data;
+                    $value.data('value_token').dataProvider(selectArgs);
                 } else {
                     // Text input
                     $value.append(
@@ -1035,9 +1105,20 @@
 
                 // Set up editable metadata
                 if (typeof(value.isEditable) == 'function')
+                {
                     $value.data('detail-view-is-editable', value.isEditable(context));
-                else //typeof(value.isEditable) == 'boolean' or 'undefined'
+                }
+                else // typeof(value.isEditable) == 'boolean' or 'undefined'
+                {
                     $value.data('detail-view-is-editable', value.isEditable);
+
+                    if (value.isTokenInput)
+                    {
+                         $value.data('detail-view-is-TokenInput', true);
+                         $value.data('value_token', value);
+                    }
+                }
+
                 if (value.select) {
                     value.selected = $value.html();
 


[17/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
ui: refactor and use a unified unboxing helping method in cloudStack.js

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/54986d58
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/54986d58
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/54986d58

Branch: refs/heads/saml2
Commit: 54986d58a468734c9350c44e2f06c72f42ce366e
Parents: 60e8413
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 04:56:54 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:35 2014 +0200

----------------------------------------------------------------------
 ui/scripts/cloudStack.js | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54986d58/ui/scripts/cloudStack.js
----------------------------------------------------------------------
diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js
index edc7c21..38cf501 100644
--- a/ui/scripts/cloudStack.js
+++ b/ui/scripts/cloudStack.js
@@ -129,24 +129,25 @@
            i.e. calling listCapabilities API with g_sessionKey from $.cookie('sessionKey') will succeed,
            then userValid will be set to true, then an user object (instead of "false") will be returned, then login screen will be bypassed.
            */
+                    var unBoxCookieValue = function (cookieName) {
+                        var cookieValue = $.cookie(cookieName);
+                        if (cookieValue && cookieValue.length > 2 && cookieValue[0] === '"' && cookieValue[cookieValue.length-1] === '"') {
+                            cookieValue = cookieValue.slice(1, cookieValue.length-1);
+                            $.cookie(cookieName, cookieValue, { expires: 1 });
+                        }
+                        return cookieValue;
+                    };
                     g_mySession = $.cookie('JSESSIONID');
-                    g_sessionKey = $.cookie('sessionKey');
-                    // Unbox quotes from sessionKey cookie value
-                    if (g_sessionKey && g_sessionKey[0] === '"' && g_sessionKey[g_sessionKey.length-1] === '"') {
-                        g_sessionKey = g_sessionKey.slice(1, g_sessionKey.length-1);
-                        $.cookie('sessionKey', g_sessionKey, {
-                            expires: 1
-                        });
-                    }
-                    g_role = $.cookie('role');
-                    g_username = $.cookie('username');
-                    g_userid = $.cookie('userid');
-                    g_account = $.cookie('account');
-                    g_domainid = $.cookie('domainid');
-                    g_userfullname = $.cookie('userfullname');
-                    g_timezone = $.cookie('timezone');
+                    g_sessionKey = unBoxCookieValue('sessionKey');
+                    g_role = unBoxCookieValue('role');
+                    g_userid = unBoxCookieValue('userid');
+                    g_domainid = unBoxCookieValue('domainid');
+                    g_account = unBoxCookieValue('account');
+                    g_username = unBoxCookieValue('username');
+                    g_userfullname = unBoxCookieValue('userfullname');
+                    g_timezone = unBoxCookieValue('timezone');
                     if ($.cookie('timezoneoffset') != null)
-                        g_timezoneoffset = isNaN($.cookie('timezoneoffset')) ? null : parseFloat($.cookie('timezoneoffset'));
+                        g_timezoneoffset = isNaN(unBoxCookieValue('timezoneoffset')) ? null : parseFloat(unBoxCookieValue('timezoneoffset'));
                     else
                         g_timezoneoffset = null;
                 } else { //single-sign-on	(bypass login screen)


[09/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7234: stop sending smb credentials to Hyper-v agent


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/0ecc9f79
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/0ecc9f79
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/0ecc9f79

Branch: refs/heads/saml2
Commit: 0ecc9f79af0f915ac347f856c3c2f8ce40f636af
Parents: 97f5281
Author: Anshul Gangwar <an...@citrix.com>
Authored: Wed Jul 30 12:21:43 2014 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Mon Aug 18 11:38:29 2014 +0530

----------------------------------------------------------------------
 .../storage/datastore/db/StoragePoolVO.java     |  38 ++--
 .../HypervResource/CloudStackTypes.cs           |  77 +-------
 .../ServerResource/HypervResource/Utils.cs      | 188 ++-----------------
 .../resource/HypervDirectConnectResource.java   |  46 +++++
 4 files changed, 88 insertions(+), 261 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0ecc9f79/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
index 1508ce0..33e1d78 100644
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
@@ -129,23 +129,23 @@ public class StoragePoolVO implements StoragePool {
     }
 
     public StoragePoolVO() {
-        this.status = StoragePoolStatus.Initial;
+        status = StoragePoolStatus.Initial;
     }
 
     public StoragePoolVO(long poolId, String name, String uuid, StoragePoolType type, long dataCenterId, Long podId, long availableBytes, long capacityBytes,
             String hostAddress, int port, String hostPath) {
         this.name = name;
-        this.id = poolId;
+        id = poolId;
         this.uuid = uuid;
-        this.poolType = type;
+        poolType = type;
         this.dataCenterId = dataCenterId;
-        this.usedBytes = availableBytes;
+        usedBytes = availableBytes;
         this.capacityBytes = capacityBytes;
         this.hostAddress = hostAddress;
         this.port = port;
         this.podId = podId;
-        this.setStatus(StoragePoolStatus.Initial);
-        this.setPath(hostPath);
+        setStatus(StoragePoolStatus.Initial);
+        setPath(hostPath);
     }
 
     public StoragePoolVO(StoragePoolVO that) {
@@ -153,12 +153,12 @@ public class StoragePoolVO implements StoragePool {
     }
 
     public StoragePoolVO(StoragePoolType type, String hostAddress, int port, String path) {
-        this.poolType = type;
+        poolType = type;
         this.hostAddress = hostAddress;
         this.port = port;
-        this.setStatus(StoragePoolStatus.Initial);
-        this.uuid = UUID.randomUUID().toString();
-        this.setPath(path);
+        setStatus(StoragePoolStatus.Initial);
+        uuid = UUID.randomUUID().toString();
+        setPath(path);
     }
 
     @Override
@@ -177,7 +177,7 @@ public class StoragePoolVO implements StoragePool {
     }
 
     public void setPoolType(StoragePoolType protocol) {
-        this.poolType = protocol;
+        poolType = protocol;
     }
 
     @Override
@@ -258,14 +258,17 @@ public class StoragePoolVO implements StoragePool {
     }
 
     public void setHostAddress(String host) {
-        this.hostAddress = host;
+        hostAddress = host;
     }
 
     @Override
     public String getPath() {
         String updatedPath = path;
-        if (this.poolType == StoragePoolType.SMB) {
+        if (poolType == StoragePoolType.SMB) {
             updatedPath = UriUtils.getUpdateUri(updatedPath, false);
+            if (updatedPath.contains("password") && updatedPath.contains("?")) {
+                updatedPath = updatedPath.substring(0, updatedPath.indexOf('?'));
+            }
         }
 
         return updatedPath;
@@ -285,7 +288,7 @@ public class StoragePoolVO implements StoragePool {
     }
 
     public void setDataCenterId(long dcId) {
-        this.dataCenterId = dcId;
+        dataCenterId = dcId;
     }
 
     public void setPodId(Long podId) {
@@ -327,9 +330,10 @@ public class StoragePoolVO implements StoragePool {
     }
 
     public ScopeType getScope() {
-        return this.scope;
+        return scope;
     }
 
+    @Override
     public HypervisorType getHypervisor() {
         return hypervisor;
     }
@@ -344,7 +348,7 @@ public class StoragePoolVO implements StoragePool {
             return false;
         }
         StoragePoolVO that = (StoragePoolVO)obj;
-        return this.id == that.id;
+        return id == that.id;
     }
 
     @Override
@@ -359,7 +363,7 @@ public class StoragePoolVO implements StoragePool {
 
     @Override
     public boolean isShared() {
-        return this.scope == ScopeType.HOST ? false : true;
+        return scope == ScopeType.HOST ? false : true;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0ecc9f79/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
index 4516191..a69240f 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation (ASF) under one
+// 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
@@ -69,52 +69,6 @@ namespace HypervResource
             }
         }
 
-        public string User
-        {
-            get
-            {
-                string user = null;
-                if (uri != null)
-                {
-                    var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
-                    user = System.Web.HttpUtility.UrlDecode(queryDictionary["user"]);
-                }
-                return user;
-            }
-        }
-
-        public string Password
-        {
-            get
-            {
-                string password = null;
-                if (uri != null)
-                {
-                    var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
-                    password = System.Web.HttpUtility.UrlDecode(queryDictionary["password"]);
-                }
-                return password;
-            }
-        }
-
-        public string Domain
-        {
-            get
-            {
-                string domain = null;
-                if (uri != null)
-                {
-                    var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
-                    if (queryDictionary["domain"] != null)
-                    {
-                        domain = System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]);
-                    }
-                    else domain = uri.Host;
-                }
-                return domain;
-            }
-        }
-
         public Boolean isLocal
         {
             get
@@ -457,36 +411,7 @@ namespace HypervResource
                 return uncPath;
             }
         }
-        public string User
-        {
-            get
-            {
-                var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
-                return System.Web.HttpUtility.UrlDecode(queryDictionary["user"]);
-            }
-        }
-
-        public string Password
-        {
-            get
-            {
-                var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
-                return System.Web.HttpUtility.UrlDecode(queryDictionary["password"]);
-            }
-        }
 
-        public string Domain
-        {
-            get
-            {
-                var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
-                if (queryDictionary["domain"] != null)
-                {
-                    return System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]);
-                }
-                else return uri.Host;
-            }
-        }
         public static NFSTO ParseJson(dynamic json)
         {
             NFSTO result = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0ecc9f79/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
index b40cb8f..5c57239 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
@@ -84,48 +84,31 @@ namespace HypervResource
         /// <param name="destFile"></param>
         public static void DownloadCifsFileToLocalFile(string filePathRelativeToShare, NFSTO cifsShareDetails, string destFile)
         {
-            try
+            String dest = "";
+            if (filePathRelativeToShare.EndsWith(".iso") || filePathRelativeToShare.EndsWith(".vhd") || filePathRelativeToShare.EndsWith(".vhdx"))
             {
-                IntPtr token = IntPtr.Zero;
-
-                LogonUser(cifsShareDetails.User, cifsShareDetails.Domain, cifsShareDetails.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token);
-                using (WindowsImpersonationContext remoteIdentity = new WindowsIdentity(token).Impersonate())
+                dest = Path.Combine(cifsShareDetails.UncPath, filePathRelativeToShare);
+                dest = Utils.NormalizePath(dest);
+            }
+            // if the filePathRelativeToShare string don't have filename and only a dir point then find the vhd files in that folder and use
+            // In the clean setup, first copy command wont be having the filename it contains onlyu dir path.
+            // we need to scan the folder point and then copy the file to destination.
+            else if (!filePathRelativeToShare.EndsWith(".vhd") || !filePathRelativeToShare.EndsWith(".vhdx"))
+            {
+                // scan the folder and get the vhd filename.
+                String uncPath = Path.Combine(cifsShareDetails.UncPath, Path.Combine(filePathRelativeToShare.Split('/')));
+                //uncPath = uncPath.Replace("/", "\\");
+                DirectoryInfo dir = new DirectoryInfo(uncPath);
+                FileInfo[] vhdFiles = dir.GetFiles("*.vhd*");
+                if (vhdFiles.Length > 0)
                 {
-                    String dest = "";
-                    if (filePathRelativeToShare.EndsWith(".iso") || filePathRelativeToShare.EndsWith(".vhd") || filePathRelativeToShare.EndsWith(".vhdx"))
-                    {
-                        dest = Path.Combine(cifsShareDetails.UncPath, filePathRelativeToShare);
-                        dest = Utils.NormalizePath(dest);
-                    }
-                    // if the filePathRelativeToShare string don't have filename and only a dir point then find the vhd files in that folder and use
-                    // In the clean setup, first copy command wont be having the filename it contains onlyu dir path.
-                    // we need to scan the folder point and then copy the file to destination.
-                    else if (!filePathRelativeToShare.EndsWith(".vhd") || !filePathRelativeToShare.EndsWith(".vhdx"))
-                    {
-                        // scan the folder and get the vhd filename.
-                        String uncPath = Path.Combine(cifsShareDetails.UncPath, Path.Combine(filePathRelativeToShare.Split('/')));
-                        //uncPath = uncPath.Replace("/", "\\");
-                        DirectoryInfo dir = new DirectoryInfo(uncPath);
-                        FileInfo[] vhdFiles = dir.GetFiles("*.vhd*");
-                        if (vhdFiles.Length > 0)
-                        {
-                            FileInfo file = vhdFiles[0];
-                            dest = file.FullName;
-                        }
-                    }
-
-                    s_logger.Info(CloudStackTypes.CopyCommand + ": copy " + Path.Combine(cifsShareDetails.UncPath, filePathRelativeToShare) + " to " + destFile);
-                    File.Copy(dest, destFile, true);
-                    remoteIdentity.Undo();
+                    FileInfo file = vhdFiles[0];
+                    dest = file.FullName;
                 }
             }
-            catch (UnauthorizedAccessException ex)
-            {
-                string errMsg = "Invalid user or password for the share " + cifsShareDetails.UncPath;
-                s_logger.Error(errMsg);
 
-                throw new ArgumentException(errMsg, ex);
-            }
+            s_logger.Info(CloudStackTypes.CopyCommand + ": copy " + Path.Combine(cifsShareDetails.UncPath, filePathRelativeToShare) + " to " + destFile);
+            File.Copy(dest, destFile, true);
         }
 
         public static void GetShareDetails(string remoteUNC, out long capacity, out long available)
@@ -193,142 +176,11 @@ namespace HypervResource
 
         // from http://stackoverflow.com/a/2541569/939250
         #region imports
-        [DllImport("advapi32.dll", SetLastError = true)]
-        private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
-
-        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
-        private static extern bool CloseHandle(IntPtr handle);
-
-        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
-        public extern static bool DuplicateToken(IntPtr existingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr duplicateTokenHandle);
-
         [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
         private static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
            out ulong lpFreeBytesAvailable,
            out ulong lpTotalNumberOfBytes,
            out ulong lpTotalNumberOfFreeBytes);
         #endregion
-
-        #region consts
-        // logon types 
-        const int LOGON32_LOGON_INTERACTIVE = 2;
-        const int LOGON32_LOGON_NETWORK = 3;
-        const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
-
-        // logon providers 
-        const int LOGON32_PROVIDER_DEFAULT = 0;
-        const int LOGON32_PROVIDER_WINNT50 = 3;
-        const int LOGON32_PROVIDER_WINNT40 = 2;
-        const int LOGON32_PROVIDER_WINNT35 = 1;
-
-        const int RESOURCE_CONNECTED = 0x00000001;
-        const int RESOURCE_GLOBALNET = 0x00000002;
-        const int RESOURCE_REMEMBERED = 0x00000003;
-
-        const int RESOURCETYPE_ANY = 0x00000000;
-        const int RESOURCETYPE_DISK = 0x00000001;
-        const int RESOURCETYPE_PRINT = 0x00000002;
-
-        const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000;
-        const int RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001;
-        const int RESOURCEDISPLAYTYPE_SERVER = 0x00000002;
-        const int RESOURCEDISPLAYTYPE_SHARE = 0x00000003;
-        const int RESOURCEDISPLAYTYPE_FILE = 0x00000004;
-        const int RESOURCEDISPLAYTYPE_GROUP = 0x00000005;
-
-        const int RESOURCEUSAGE_CONNECTABLE = 0x00000001;
-        const int RESOURCEUSAGE_CONTAINER = 0x00000002;
-
-
-        const int CONNECT_INTERACTIVE = 0x00000008;
-        const int CONNECT_PROMPT = 0x00000010;
-        const int CONNECT_REDIRECT = 0x00000080;
-        const int CONNECT_UPDATE_PROFILE = 0x00000001;
-        const int CONNECT_COMMANDLINE = 0x00000800;
-        const int CONNECT_CMD_SAVECRED = 0x00001000;
-
-        const int CONNECT_LOCALDRIVE = 0x00000100;
-        #endregion
-
-        #region Errors
-        const int NO_ERROR = 0;
-
-        const int ERROR_ACCESS_DENIED = 5;
-        const int ERROR_ALREADY_ASSIGNED = 85;
-        const int ERROR_BAD_DEVICE = 1200;
-        const int ERROR_BAD_NET_NAME = 67;
-        const int ERROR_BAD_PROVIDER = 1204;
-        const int ERROR_CANCELLED = 1223;
-        const int ERROR_EXTENDED_ERROR = 1208;
-        const int ERROR_INVALID_ADDRESS = 487;
-        const int ERROR_INVALID_PARAMETER = 87;
-        const int ERROR_INVALID_PASSWORD = 1216;
-        const int ERROR_MORE_DATA = 234;
-        const int ERROR_NO_MORE_ITEMS = 259;
-        const int ERROR_NO_NET_OR_BAD_PATH = 1203;
-        const int ERROR_NO_NETWORK = 1222;
-
-        const int ERROR_BAD_PROFILE = 1206;
-        const int ERROR_CANNOT_OPEN_PROFILE = 1205;
-        const int ERROR_DEVICE_IN_USE = 2404;
-        const int ERROR_NOT_CONNECTED = 2250;
-        const int ERROR_OPEN_FILES = 2401;
-
-        private struct ErrorClass
-        {
-            public int num;
-            public string message;
-            public ErrorClass(int num, string message)
-            {
-                this.num = num;
-                this.message = message;
-            }
-        }
-
-        private static ErrorClass[] ERROR_LIST = new ErrorClass[] {
-            new ErrorClass(ERROR_ACCESS_DENIED, "Error: Access Denied"),
-            new ErrorClass(ERROR_ALREADY_ASSIGNED, "Error: Already Assigned"),
-            new ErrorClass(ERROR_BAD_DEVICE, "Error: Bad Device"),
-            new ErrorClass(ERROR_BAD_NET_NAME, "Error: Bad Net Name"),
-            new ErrorClass(ERROR_BAD_PROVIDER, "Error: Bad Provider"),
-            new ErrorClass(ERROR_CANCELLED, "Error: Cancelled"),
-            new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"),
-            new ErrorClass(ERROR_INVALID_ADDRESS, "Error: Invalid Address"),
-            new ErrorClass(ERROR_INVALID_PARAMETER, "Error: Invalid Parameter"),
-            new ErrorClass(ERROR_INVALID_PASSWORD, "Error: Invalid Password"),
-            new ErrorClass(ERROR_MORE_DATA, "Error: More Data"),
-            new ErrorClass(ERROR_NO_MORE_ITEMS, "Error: No More Items"),
-            new ErrorClass(ERROR_NO_NET_OR_BAD_PATH, "Error: No Net Or Bad Path"),
-            new ErrorClass(ERROR_NO_NETWORK, "Error: No Network"),
-            new ErrorClass(ERROR_BAD_PROFILE, "Error: Bad Profile"),
-            new ErrorClass(ERROR_CANNOT_OPEN_PROFILE, "Error: Cannot Open Profile"),
-            new ErrorClass(ERROR_DEVICE_IN_USE, "Error: Device In Use"),
-            new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"),
-            new ErrorClass(ERROR_NOT_CONNECTED, "Error: Not Connected"),
-            new ErrorClass(ERROR_OPEN_FILES, "Error: Open Files"),
-        };
-
-        private static string getErrorForNumber(int errNum)
-        {
-            foreach (ErrorClass er in ERROR_LIST)
-            {
-                if (er.num == errNum) return er.message;
-            }
-            return "Error: Unknown, " + errNum;
-        }
-        #endregion
-
-        [StructLayout(LayoutKind.Sequential)]
-        private class NETRESOURCE
-        {
-            public int dwScope = 0;
-            public int dwType = 0;
-            public int dwDisplayType = 0;
-            public int dwUsage = 0;
-            public string lpLocalName = "";
-            public string lpRemoteName = "";
-            public string lpComment = "";
-            public string lpProvider = "";
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0ecc9f79/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
index 2671b20..76f8e75 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -65,6 +65,8 @@ import org.apache.log4j.Logger;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 
+import org.apache.cloudstack.storage.command.CopyCommand;
+
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.CheckRouterAnswer;
 import com.cloud.agent.api.CheckRouterCommand;
@@ -123,9 +125,11 @@ import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DhcpTO;
 import com.cloud.agent.api.to.FirewallRuleTO;
 import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.PortForwardingRuleTO;
 import com.cloud.agent.api.to.StaticNatRuleTO;
@@ -486,6 +490,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
             answer = execute((PlugNicCommand)cmd);
         } else if (clazz == UnPlugNicCommand.class) {
             answer = execute((UnPlugNicCommand)cmd);
+        } else if (clazz == CopyCommand.class) {
+            answer = execute((CopyCommand)cmd);
         }
         else {
             if (clazz == StartCommand.class) {
@@ -519,6 +525,46 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
         return answer;
     }
 
+    private Answer execute(CopyCommand cmd) {
+        URI agentUri = null;
+        try {
+            String cmdName = cmd.getClass().getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (URISyntaxException e) {
+            String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+            return null;
+        }
+        cleanPassword(cmd.getSrcTO().getDataStore());
+        cleanPassword(cmd.getDestTO().getDataStore());
+
+        // Send the cmd to hyperv agent.
+        String ansStr = postHttpRequest(s_gson.toJson(cmd), agentUri);
+        if (ansStr == null) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result.toString()));
+        s_logger.debug("executeRequest received response " + logResult);
+        if (result.length > 0) {
+            return result[0];
+        }
+
+        return null;
+    }
+
+    private void cleanPassword(DataStoreTO dataStoreTO) {
+        if (dataStoreTO instanceof NfsTO) {
+            NfsTO nfsTO = (NfsTO)dataStoreTO;
+            String url = nfsTO.getUrl();
+            if (url.contains("cifs") && url.contains("password")) {
+                nfsTO.setUrl(url.substring(0, url.indexOf('?')));
+            }
+        }
+    }
 
     private PlugNicAnswer execute(PlugNicCommand cmd) {
         if (s_logger.isInfoEnabled()) {


[15/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
server: add opensaml as dependency

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4563cc6e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4563cc6e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4563cc6e

Branch: refs/heads/saml2
Commit: 4563cc6e1c25b95c391c6467059879321c9fdda3
Parents: 329b209
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Sun Aug 17 19:11:40 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:34 2014 +0200

----------------------------------------------------------------------
 server/pom.xml | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4563cc6e/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index 1b21ebd..04c25af 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -133,6 +133,11 @@
       <artifactId>cloud-engine-components-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opensaml</groupId>
+      <artifactId>opensaml</artifactId>
+      <version>2.6.1</version>
+    </dependency>
   </dependencies>
   <build>
     <testResources>


[22/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
Minor fixes

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/60e84135
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/60e84135
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/60e84135

Branch: refs/heads/saml2
Commit: 60e841350533a2e2c7e5e3e71672d56b74f94031
Parents: ce285f6
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 04:31:46 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:35 2014 +0200

----------------------------------------------------------------------
 server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java | 2 +-
 ui/scripts/cloudStack.js                                         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60e84135/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
index 1f88c1c..ce97cfd 100644
--- a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
@@ -325,7 +325,7 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
                             resp.addCookie(new Cookie("sessionKey", URLEncoder.encode(loginResponse.getSessionKey(), HttpUtils.UTF_8)));
                             resp.addCookie(new Cookie("account", URLEncoder.encode(loginResponse.getAccount(), HttpUtils.UTF_8)));
                             resp.addCookie(new Cookie("timezone", URLEncoder.encode(loginResponse.getTimeZone(), HttpUtils.UTF_8)));
-                            resp.addCookie(new Cookie("userfullname", URLEncoder.encode(loginResponse.getFirstName() + " " + loginResponse.getLastName(), HttpUtils.UTF_8)));
+                            resp.addCookie(new Cookie("userfullname", loginResponse.getFirstName() + "%20" + loginResponse.getLastName()));
                             resp.sendRedirect("http://localhost:8080/client");
                             return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60e84135/ui/scripts/cloudStack.js
----------------------------------------------------------------------
diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js
index 420c137..edc7c21 100644
--- a/ui/scripts/cloudStack.js
+++ b/ui/scripts/cloudStack.js
@@ -132,7 +132,7 @@
                     g_mySession = $.cookie('JSESSIONID');
                     g_sessionKey = $.cookie('sessionKey');
                     // Unbox quotes from sessionKey cookie value
-                    if (g_sessionKey[0] === '"' && g_sessionKey[g_sessionKey.length-1] === '"') {
+                    if (g_sessionKey && g_sessionKey[0] === '"' && g_sessionKey[g_sessionKey.length-1] === '"') {
                         g_sessionKey = g_sessionKey.slice(1, g_sessionKey.length-1);
                         $.cookie('sessionKey', g_sessionKey, {
                             expires: 1


[11/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7361: Fix SAML2UserAuthenticator to not let every login credential

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/6a8f8317
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/6a8f8317
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/6a8f8317

Branch: refs/heads/saml2
Commit: 6a8f8317fd88279b12a8fccc4bbdb313c53d720e
Parents: a1d0925
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 11:40:09 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:41:32 2014 +0200

----------------------------------------------------------------------
 .../cloudstack/SAML2UserAuthenticator.java      | 27 +++++++++++++++++---
 1 file changed, 23 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a8f8317/plugins/user-authenticators/saml2/src/org/apache/cloudstack/SAML2UserAuthenticator.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/SAML2UserAuthenticator.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/SAML2UserAuthenticator.java
index 4e1e795..4d4f1d3 100644
--- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/SAML2UserAuthenticator.java
+++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/SAML2UserAuthenticator.java
@@ -16,25 +16,44 @@ package org.apache.cloudstack;
 
 import com.cloud.server.auth.DefaultUserAuthenticator;
 import com.cloud.server.auth.UserAuthenticator;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import com.cloud.user.dao.UserAccountDao;
+import com.cloud.user.dao.UserDao;
 import com.cloud.utils.Pair;
 import org.apache.log4j.Logger;
 
 import javax.ejb.Local;
+import javax.inject.Inject;
 import java.util.Map;
 
 @Local(value = {UserAuthenticator.class})
 public class SAML2UserAuthenticator extends DefaultUserAuthenticator {
     public static final Logger s_logger = Logger.getLogger(SAML2UserAuthenticator.class);
 
+    @Inject
+    private UserAccountDao _userAccountDao;
+    @Inject
+    private UserDao _userDao;
+
     @Override
     public Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, Map<String, Object[]> requestParameters) {
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Trying SAML2 auth for user: " + username);
         }
-
-        // TODO: implement core logic, HTTP GET redirections etc.
-
-        return new Pair<Boolean, ActionOnFailedAuthentication>(true, null);
+        final UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId);
+        if (userAccount == null) {
+            s_logger.debug("Unable to find user with " + username + " in domain " + domainId);
+            return new Pair<Boolean, ActionOnFailedAuthentication>(false, null);
+        } else {
+            User user = _userDao.getUser(userAccount.getId());
+            // TODO: check SAMLRequest, signature etc. from requestParameters
+            if (user != null && user.getUuid().startsWith("saml")) {
+                return new Pair<Boolean, ActionOnFailedAuthentication>(true, null);
+            }
+        }
+        // Deny all by default
+        return new Pair<Boolean, ActionOnFailedAuthentication>(false, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
     }
 
     @Override


[12/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
SAML: WIP redirections work now

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/40abe1df
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/40abe1df
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/40abe1df

Branch: refs/heads/saml2
Commit: 40abe1df114052b8637e13319c34c1bb38a928ca
Parents: 4563cc6
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Sun Aug 17 19:12:00 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:34 2014 +0200

----------------------------------------------------------------------
 .../api/auth/SAML2LoginAPIAuthenticatorCmd.java | 241 ++++++++++++++++++-
 1 file changed, 239 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40abe1df/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
index beba4f1..c6b0bb6 100644
--- a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
@@ -26,11 +26,54 @@ import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.LoginCmdResponse;
 import org.apache.log4j.Logger;
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.DefaultBootstrap;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameIDPolicy;
+import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder;
+import org.opensaml.saml2.core.impl.AuthnRequestBuilder;
+import org.opensaml.saml2.core.impl.IssuerBuilder;
+import org.opensaml.saml2.core.impl.NameIDPolicyBuilder;
+import org.opensaml.saml2.core.impl.RequestedAuthnContextBuilder;
+import org.opensaml.xml.ConfigurationException;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.util.XMLHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.FactoryConfigurationError;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.StringWriter;
+import java.math.BigInteger;
+import java.net.URLEncoder;
+import java.security.SecureRandom;
 import java.util.Map;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
 
 @APICommand(name = "samlsso", description = "SP initiated SAML Single Sign On", requestHasSensitiveInfo = true, responseObject = LoginCmdResponse.class, entityType = {})
 public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator {
@@ -71,12 +114,206 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
         throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "This is an authentication api, cannot be used directly");
     }
 
+    public String buildAuthnRequestUrl(String resourceUrl) {
+        String randomId = new BigInteger(130, new SecureRandom()).toString(32);
+        // TODO: Add method to get this url from metadata
+        String identityProviderUrl = "https://idp.ssocircle.com:443/sso/SSORedirect/metaAlias/ssocircle";
+        String encodedAuthRequest = "";
+
+        try {
+            DefaultBootstrap.bootstrap();
+            AuthnRequest authnRequest = this.buildAuthnRequestObject(randomId, identityProviderUrl, resourceUrl); // SAML AuthRequest
+            encodedAuthRequest = encodeAuthnRequest(authnRequest);
+        } catch (ConfigurationException | FactoryConfigurationError | MarshallingException | IOException e) {
+            s_logger.error("SAML AuthnRequest message building error: " + e.getMessage());
+        }
+        return identityProviderUrl + "?SAMLRequest=" + encodedAuthRequest; // + "&RelayState=" + relayState;
+    }
+
+    private AuthnRequest buildAuthnRequestObject(String authnId, String idpUrl, String consumerUrl) {
+        // Issuer object
+        IssuerBuilder issuerBuilder = new IssuerBuilder();
+        Issuer issuer = issuerBuilder.buildObject();
+        //SAMLConstants.SAML20_NS,
+        //        "Issuer", "samlp");
+        issuer.setValue("apache-cloudstack");
+
+        // NameIDPolicy
+        NameIDPolicyBuilder nameIdPolicyBuilder = new NameIDPolicyBuilder();
+        NameIDPolicy nameIdPolicy = nameIdPolicyBuilder.buildObject();
+        nameIdPolicy.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
+        nameIdPolicy.setSPNameQualifier("Apache CloudStack");
+        nameIdPolicy.setAllowCreate(true);
+
+        // AuthnContextClass
+        AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
+        AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject(
+                SAMLConstants.SAML20_NS,
+                "AuthnContextClassRef", "saml");
+        authnContextClassRef.setAuthnContextClassRef("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport");
+
+        // AuthnContex
+        RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder();
+        RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
+        requestedAuthnContext
+                .setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
+        requestedAuthnContext.getAuthnContextClassRefs().add(
+                authnContextClassRef);
+
+
+        // Creation of AuthRequestObject
+        AuthnRequestBuilder authRequestBuilder = new AuthnRequestBuilder();
+        AuthnRequest authnRequest = authRequestBuilder.buildObject();
+        //SAMLConstants.SAML20P_NS,
+        //        "AuthnRequest", "samlp");
+        authnRequest.setID(authnId);
+        authnRequest.setDestination(idpUrl);
+        authnRequest.setVersion(SAMLVersion.VERSION_20);
+        authnRequest.setForceAuthn(true);
+        authnRequest.setIsPassive(false);
+        authnRequest.setIssuer(issuer);
+        authnRequest.setIssueInstant(new DateTime());
+        authnRequest.setProviderName("Apache CloudStack");
+        authnRequest.setProtocolBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
+        authnRequest.setAssertionConsumerServiceURL(consumerUrl);
+        //authnRequest.setNameIDPolicy(nameIdPolicy);
+        //authnRequest.setRequestedAuthnContext(requestedAuthnContext);
+
+        return authnRequest;
+    }
+
+    private String encodeAuthnRequest(AuthnRequest authnRequest)
+            throws MarshallingException, IOException {
+
+        Marshaller marshaller = null;
+        org.w3c.dom.Element authDOM = null;
+        StringWriter requestWriter = null;
+        String requestMessage = null;
+        Deflater deflater = null;
+        ByteArrayOutputStream byteArrayOutputStream = null;
+        DeflaterOutputStream deflaterOutputStream = null;
+        String encodedRequestMessage = null;
+
+        marshaller = org.opensaml.Configuration.getMarshallerFactory()
+                .getMarshaller(authnRequest); // object to DOM converter
+
+        authDOM = marshaller.marshall(authnRequest); // converting to a DOM
+
+        requestWriter = new StringWriter();
+        XMLHelper.writeNode(authDOM, requestWriter);
+        requestMessage = requestWriter.toString(); // DOM to string
+
+        deflater = new Deflater(Deflater.DEFLATED, true);
+        byteArrayOutputStream = new ByteArrayOutputStream();
+        deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream,
+                deflater);
+        deflaterOutputStream.write(requestMessage.getBytes()); // compressing
+        deflaterOutputStream.close();
+
+        encodedRequestMessage = Base64.encodeBytes(byteArrayOutputStream
+                .toByteArray(), Base64.DONT_BREAK_LINES);
+        encodedRequestMessage = URLEncoder.encode(encodedRequestMessage,
+                "UTF-8").trim(); // encoding string
+
+        return encodedRequestMessage;
+    }
+
+
+    public String processResponseMessage(String responseMessage) {
+
+        XMLObject responseObject = null;
+
+        try {
+
+            responseObject = this.unmarshall(responseMessage);
+
+        } catch (ConfigurationException | ParserConfigurationException | SAXException | IOException | UnmarshallingException e) {
+            e.printStackTrace();
+        }
+
+        return this.getResult(responseObject);
+    }
+
+    private XMLObject unmarshall(String responseMessage)
+            throws ConfigurationException, ParserConfigurationException,
+            SAXException, IOException, UnmarshallingException {
+
+        DocumentBuilderFactory documentBuilderFactory = null;
+        DocumentBuilder docBuilder = null;
+        Document document = null;
+        Element element = null;
+        UnmarshallerFactory unmarshallerFactory = null;
+        Unmarshaller unmarshaller = null;
+
+        DefaultBootstrap.bootstrap();
+
+        documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+        documentBuilderFactory.setNamespaceAware(true);
+
+        docBuilder = documentBuilderFactory.newDocumentBuilder();
+
+        document = docBuilder.parse(new ByteArrayInputStream(responseMessage
+                .trim().getBytes())); // response to DOM
+
+        element = document.getDocumentElement(); // the DOM element
+
+        unmarshallerFactory = Configuration.getUnmarshallerFactory();
+
+        unmarshaller = unmarshallerFactory.getUnmarshaller(element);
+
+        return unmarshaller.unmarshall(element); // Response object
+
+    }
+
+    private String getResult(XMLObject responseObject) {
+
+        Element ele = null;
+        NodeList statusNodeList = null;
+        Node statusNode = null;
+        NamedNodeMap statusAttr = null;
+        Node valueAtt = null;
+        String statusValue = null;
+
+        String[] word = null;
+        String result = null;
+
+        NodeList nameIDNodeList = null;
+        Node nameIDNode = null;
+        String nameID = null;
+
+        // reading the Response Object
+        ele = responseObject.getDOM();
+        statusNodeList = ele.getElementsByTagName("samlp:StatusCode");
+        statusNode = statusNodeList.item(0);
+        statusAttr = statusNode.getAttributes();
+        valueAtt = statusAttr.item(0);
+        statusValue = valueAtt.getNodeValue();
+
+        word = statusValue.split(":");
+        result = word[word.length - 1];
+
+        nameIDNodeList = ele.getElementsByTagNameNS(
+                "urn:oasis:names:tc:SAML:2.0:assertion", "NameID");
+        nameIDNode = nameIDNodeList.item(0);
+        nameID = nameIDNode.getFirstChild().getNodeValue();
+
+        result = nameID + ":" + result;
+
+        return result;
+    }
+
+
+
     @Override
     public String authenticate(String command, Map<String, Object[]> params, HttpSession session, String remoteAddress, String responseType, StringBuilder auditTrailSb, final HttpServletResponse resp) throws ServerApiException {
-
         String response = null;
         try {
-            resp.sendRedirect(getIdpUrl());
+            String redirectUrl = buildAuthnRequestUrl("http://localhost:8080/client/api?command=login");
+            resp.sendRedirect(redirectUrl);
+
+            //resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+            //resp.setHeader("Location", redirectUrl);
 
             // TODO: create and send assertion with the URL as GET params
 


[08/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7235: [Hyper-V] In case of any exception in ModifyStoragePoolCommand, now we are returning appropriate error


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d1796c5f
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d1796c5f
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d1796c5f

Branch: refs/heads/saml2
Commit: d1796c5f585e79d9f833b414023352e5df84fb03
Parents: 0ecc9f7
Author: Anshul Gangwar <an...@citrix.com>
Authored: Mon Aug 4 15:28:50 2014 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Mon Aug 18 11:38:29 2014 +0530

----------------------------------------------------------------------
 .../HypervResource/HypervResourceController.cs  | 73 +++++++++++---------
 1 file changed, 42 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d1796c5f/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
index 195a964..62f5355 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation (ASF) under one
+// 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
@@ -951,44 +951,54 @@ namespace HypervResource
                 string details = null;
                 string localPath;
                 StoragePoolType poolType;
-                object ansContent;
-
-                bool result = ValidateStoragePoolCommand(cmd, out localPath, out poolType, ref details);
-                if (!result)
-                {
-                    ansContent = new
-                    {
-                        result = result,
-                        details = details,
-                        contextMap = contextMap
-                    };
-                    return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
-                }
-
-                var tInfo = new Dictionary<string, string>();
                 long capacityBytes = 0;
                 long availableBytes = 0;
                 string hostPath = null;
-                if (poolType == StoragePoolType.Filesystem)
-                {
-                    GetCapacityForLocalPath(localPath, out capacityBytes, out availableBytes);
-                    hostPath = localPath;
-                }
-                else if (poolType == StoragePoolType.NetworkFilesystem ||
-                    poolType == StoragePoolType.SMB)
+                bool result = false;
+                var tInfo = new Dictionary<string, string>();
+                object ansContent;
+
+                try
                 {
-                    NFSTO share = new NFSTO();
-                    String uriStr = "cifs://" + (string)cmd.pool.host + (string)cmd.pool.path;
-                    share.uri = new Uri(uriStr);
-                    hostPath = Utils.NormalizePath(share.UncPath);
+                    result = ValidateStoragePoolCommand(cmd, out localPath, out poolType, ref details);
+                    if (!result)
+                    {
+                        ansContent = new
+                        {
+                            result = result,
+                            details = details,
+                            contextMap = contextMap
+                        };
+                        return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
+                    }
 
-                    // Check access to share.
-                    Utils.GetShareDetails(share.UncPath, out capacityBytes, out availableBytes);
-                    config.setPrimaryStorage((string)cmd.pool.uuid, hostPath);
+                    if (poolType == StoragePoolType.Filesystem)
+                    {
+                        GetCapacityForLocalPath(localPath, out capacityBytes, out availableBytes);
+                        hostPath = localPath;
+                    }
+                    else if (poolType == StoragePoolType.NetworkFilesystem ||
+                        poolType == StoragePoolType.SMB)
+                    {
+                        NFSTO share = new NFSTO();
+                        String uriStr = "cifs://" + (string)cmd.pool.host + (string)cmd.pool.path;
+                        share.uri = new Uri(uriStr);
+                        hostPath = Utils.NormalizePath(share.UncPath);
+
+                        // Check access to share.
+                        Utils.GetShareDetails(hostPath, out capacityBytes, out availableBytes);
+                        config.setPrimaryStorage((string)cmd.pool.uuid, hostPath);
+                    }
+                    else
+                    {
+                        result = false;
+                    }
                 }
-                else
+                catch
                 {
                     result = false;
+                    details = String.Format("Failed to add storage pool {0}, please verify your pool details", (string)cmd.pool.uuid);
+                    logger.Error(details);
                 }
 
                 String uuid = null;
@@ -1003,6 +1013,7 @@ namespace HypervResource
                     availableBytes = availableBytes
                 };
 
+
                 ansContent = new
                 {
                     result = result,


[07/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7277: [Hyper-V] For vmsync first VMs are listed and their power state is
determined. To exclude hosted system we filter the result on Caption='Virtual Machine'
but this string is locale dependent so it may not not work properly for locales other
than english. To overcome this now we started using ProcessId >= 0 filter


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1c688f40
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1c688f40
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1c688f40

Branch: refs/heads/saml2
Commit: 1c688f40e134e2f65fe11bb37946e550feb896ca
Parents: d1796c5
Author: Anshul Gangwar <an...@citrix.com>
Authored: Thu Aug 7 11:36:45 2014 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Mon Aug 18 11:38:29 2014 +0530

----------------------------------------------------------------------
 .../ServerResource/HypervResource/HypervResourceController.cs   | 5 ++++-
 .../hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs   | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1c688f40/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
index 62f5355..6c6ec56 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
@@ -2434,7 +2434,10 @@ namespace HypervResource
                     logger.Error(details, sysEx);
                 }
 
-                return JArray.FromObject(hostVmStateReport);
+                var answer = JArray.FromObject(hostVmStateReport);
+                logger.Info(String.Format("{0}: {1}",CloudStackTypes.HostVmStateReportCommand, answer.ToString()));
+
+                return answer;
             }
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1c688f40/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
index b2a7b45..f9b6e34 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
@@ -2315,7 +2315,7 @@ namespace HypervResource
 
         public ComputerSystem.ComputerSystemCollection GetComputerSystemCollection()
         {
-            var wmiQuery = String.Format("Caption=\"Virtual Machine\"");
+            var wmiQuery = String.Format("ProcessId >= 0");
             return ComputerSystem.GetInstances(wmiQuery);
         }
 


[02/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7360 [vmware] Add host to existing cluster fails if the cluster is using Nexus 1000v as backend for atleast one traffic type.

While adding host to existing cluster which is using Nexus 1000v as a network backend, skip validation of Nexus VSM as it was already done while adding that cluster.

Signed-off-by: Sateesh Chodapuneedi <sa...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a1d0925f
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a1d0925f
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a1d0925f

Branch: refs/heads/saml2
Commit: a1d0925f902041b187f14413e91bc368f0708753
Parents: f099732
Author: Sateesh Chodapuneedi <sa...@apache.org>
Authored: Mon Aug 18 07:18:13 2014 +0530
Committer: Sateesh Chodapuneedi <sa...@apache.org>
Committed: Mon Aug 18 07:18:13 2014 +0530

----------------------------------------------------------------------
 .../vmware/VmwareServerDiscoverer.java          | 22 ++++++++++++--------
 .../vmware/manager/VmwareManager.java           |  2 ++
 .../vmware/manager/VmwareManagerImpl.java       | 15 +++++++++++++
 3 files changed, 30 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a1d0925f/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
index 0916813..d0d676f 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
@@ -299,15 +299,19 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer
             if (guestTrafficLabel != null) {
                 s_logger.info("Detected guest network label : " + guestTrafficLabel);
             }
-            vsmIp = _urlParams.get("vsmipaddress");
-            String vsmUser = _urlParams.get("vsmusername");
-            String vsmPassword = _urlParams.get("vsmpassword");
-            String clusterName = cluster.getName();
-            try {
-                vsmInfo = _nexusElement.validateAndAddVsm(vsmIp, vsmUser, vsmPassword, clusterId, clusterName);
-            } catch (ResourceInUseException ex) {
-                DiscoveryException discEx = new DiscoveryException(ex.getLocalizedMessage() + ". The resource is " + ex.getResourceName());
-                throw discEx;
+            // Before proceeding with validation of Nexus 1000v VSM check if an instance of Nexus 1000v VSM is already associated with this cluster.
+            boolean clusterHasVsm = _vmwareMgr.hasNexusVSM(clusterId);
+            if (!clusterHasVsm) {
+                vsmIp = _urlParams.get("vsmipaddress");
+                String vsmUser = _urlParams.get("vsmusername");
+                String vsmPassword = _urlParams.get("vsmpassword");
+                String clusterName = cluster.getName();
+                try {
+                    vsmInfo = _nexusElement.validateAndAddVsm(vsmIp, vsmUser, vsmPassword, clusterId, clusterName);
+                } catch (ResourceInUseException ex) {
+                    DiscoveryException discEx = new DiscoveryException(ex.getLocalizedMessage() + ". The resource is " + ex.getResourceName());
+                    throw discEx;
+                }
             }
             vsmCredentials = _vmwareMgr.getNexusVSMCredentialsByClusterId(clusterId);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a1d0925f/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
index 27975ee..35e275e 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
@@ -77,4 +77,6 @@ public interface VmwareManager {
     public int getVcenterSessionTimeout();
 
     boolean isLegacyZone(long dcId);
+
+    boolean hasNexusVSM(Long clusterId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a1d0925f/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 3fd1a9c..3121bfb 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -1218,4 +1218,19 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
         // Returning list of VmwareDatacenterVO objects, in-line with future requirements, if any, like participation of multiple VMware DCs in a zone.
         return vmwareDcList;
     }
+
+    @Override
+    public boolean hasNexusVSM(Long clusterId) {
+        ClusterVSMMapVO vsmMapVo = null;
+
+        vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
+        if (vsmMapVo == null) {
+            s_logger.info("There is no instance of Nexus 1000v VSM associated with this cluster [Id:" + clusterId + "] yet.");
+            return false;
+        }
+        else {
+            s_logger.info("An instance of Nexus 1000v VSM [Id:" + vsmMapVo.getVsmId() + "] associated with this cluster [Id:" + clusterId + "]");
+            return true;
+        }
+    }
 }


[10/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7177: Fixed AlertSyslogAppender does not honor a non-default port in sysloghost parameter


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/97f5281c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/97f5281c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/97f5281c

Branch: refs/heads/saml2
Commit: 97f5281cf46e686d23df0fe0b1db0a6b6d591944
Parents: aadb5f4
Author: Anshul Gangwar <an...@citrix.com>
Authored: Thu Jul 24 10:58:05 2014 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Mon Aug 18 11:38:29 2014 +0530

----------------------------------------------------------------------
 .../cloudstack/syslog/AlertsSyslogAppender.java | 32 ++++++++++++++------
 1 file changed, 22 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/97f5281c/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
----------------------------------------------------------------------
diff --git a/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java b/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
index 50ccbc1..5f6e8ec 100644
--- a/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
+++ b/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
@@ -157,13 +157,25 @@ public class AlertsSyslogAppender extends AppenderSkeleton {
 
     private boolean validateIpAddresses() {
         for (String ipAddress : _syslogHostsList) {
-            if (ipAddress.trim().equalsIgnoreCase("localhost")) {
-                continue;
-            }
-            if (!NetUtils.isValidIp(ipAddress)) {
+            String[] hostTokens = (ipAddress.trim()).split(":");
+            String ip = hostTokens[0];
+
+            if (hostTokens.length >= 1 && hostTokens.length <= 2) {
+                if (hostTokens.length == 2 && !NetUtils.isValidPort(hostTokens[1])) {
+                    return false;
+                }
+                if (ip.equalsIgnoreCase("localhost")) {
+                    continue;
+                }
+                if (!NetUtils.isValidIp(ip)) {
+                    return false;
+                }
+            } else
+            {
                 return false;
             }
         }
+
         return true;
     }
 
@@ -265,7 +277,7 @@ public class AlertsSyslogAppender extends AppenderSkeleton {
             return;
         }
 
-        this._facility = facility;
+        _facility = facility;
         if (_syslogAppenders != null && !_syslogAppenders.isEmpty()) {
             for (SyslogAppender syslogAppender : _syslogAppenders) {
                 syslogAppender.setFacility(facility);
@@ -299,8 +311,8 @@ public class AlertsSyslogAppender extends AppenderSkeleton {
     }
 
     public void setSyslogHosts(String syslogHosts) {
-        this._syslogHosts = syslogHosts;
-        this.setSyslogAppenders();
+        _syslogHosts = syslogHosts;
+        setSyslogAppenders();
     }
 
     public String getDelimiter() {
@@ -308,7 +320,7 @@ public class AlertsSyslogAppender extends AppenderSkeleton {
     }
 
     public void setDelimiter(String delimiter) {
-        this._delimiter = delimiter;
+        _delimiter = delimiter;
     }
 
     public String getPairDelimiter() {
@@ -316,7 +328,7 @@ public class AlertsSyslogAppender extends AppenderSkeleton {
     }
 
     public void setPairDelimiter(String pairDelimiter) {
-        this._pairDelimiter = pairDelimiter;
+        _pairDelimiter = pairDelimiter;
     }
 
     public String getKeyValueDelimiter() {
@@ -324,6 +336,6 @@ public class AlertsSyslogAppender extends AppenderSkeleton {
     }
 
     public void setKeyValueDelimiter(String keyValueDelimiter) {
-        this._keyValueDelimiter = keyValueDelimiter;
+        _keyValueDelimiter = keyValueDelimiter;
     }
 }


[04/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7182: NPE while trying to deploy VMs in parallel in isolated network
- Check to see if network is implemented changed from 'state == Implementing||Implemented' to 'state == Implemented'.
The earlier check was a hack to prevent the issue described below.
- At the time of implementing network (using implementNetwork() method), if the VR needs to be deployed then it follows
the same path of regular VM deployment. This leads to a nested call to implementNetwork() while preparing VR nics. This
flow creates issues in dealing with network state transitions. The original call puts network in "Implementing" state
and then the nested call again tries to put it into same state resulting in issues. In order to avoid it, implementNetwork()
call for VR is replaced with below code.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8bc7ae69
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8bc7ae69
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8bc7ae69

Branch: refs/heads/saml2
Commit: 8bc7ae695d621b67e1e5d1916a1852cad1f4dda0
Parents: 59ea2e2
Author: Koushik Das <ko...@apache.org>
Authored: Thu Jul 31 11:51:58 2014 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Mon Aug 18 10:43:04 2014 +0530

----------------------------------------------------------------------
 .../orchestration/NetworkOrchestrator.java      | 29 ++++++++++++++++----
 1 file changed, 24 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8bc7ae69/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index cdca839..ca0b86d 100755
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -928,7 +928,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
 
     boolean isNetworkImplemented(NetworkVO network) {
         Network.State state = network.getState();
-        if (state == Network.State.Implemented || state == Network.State.Implementing) {
+        if (state == Network.State.Implemented) {
             return true;
         } else if (state == Network.State.Setup) {
             DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
@@ -939,6 +939,24 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
         return false;
     }
 
+    Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context, boolean isRouter) throws ConcurrentOperationException,
+    ResourceUnavailableException, InsufficientCapacityException {
+        Pair<NetworkGuru, NetworkVO> implemented = null;
+        if (!isRouter) {
+            implemented = implementNetwork(networkId, dest, context);
+        } else {
+            // At the time of implementing network (using implementNetwork() method), if the VR needs to be deployed then
+            // it follows the same path of regular VM deployment. This leads to a nested call to implementNetwork() while
+            // preparing VR nics. This flow creates issues in dealing with network state transitions. The original call
+            // puts network in "Implementing" state and then the nested call again tries to put it into same state resulting
+            // in issues. In order to avoid it, implementNetwork() call for VR is replaced with below code.
+            NetworkVO network = _networksDao.findById(networkId);
+            NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+            implemented = new Pair<NetworkGuru, NetworkVO>(guru, network);
+        }
+        return implemented;
+    }
+
     @Override
     @DB
     public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
@@ -1280,7 +1298,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
         });
 
         for (NicVO nic : nics) {
-            Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context);
+            Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context, vmProfile.getVirtualMachine().getType() == Type.DomainRouter);
             if (implemented == null || implemented.first() == null) {
                 s_logger.warn("Failed to implement network id=" + nic.getNetworkId() + " as a part of preparing nic id=" + nic.getId());
                 throw new CloudRuntimeException("Failed to implement network id=" + nic.getNetworkId() + " as a part preparing nic id=" + nic.getId());
@@ -3082,9 +3100,10 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
 
         //2) prepare nic
         if (prepare) {
-            Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context);
-            if (implemented == null) {
-                throw new CloudRuntimeException("Failed to prepare the nic as a part of creating nic " + nic + " for vm "+ vm + " due to network " + network + " implement failure");
+            Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context, vmProfile.getVirtualMachine().getType() == Type.DomainRouter);
+            if (implemented == null || implemented.first() == null) {
+                s_logger.warn("Failed to implement network id=" + nic.getNetworkId() + " as a part of preparing nic id=" + nic.getId());
+                throw new CloudRuntimeException("Failed to implement network id=" + nic.getNetworkId() + " as a part preparing nic id=" + nic.getId());
             }
             nic = prepareNic(vmProfile, dest, context, nic.getId(), implemented.second());
             s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network);


[03/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
Added the listHostTags API command


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/59ea2e29
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/59ea2e29
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/59ea2e29

Branch: refs/heads/saml2
Commit: 59ea2e2960b3447344365d2dfce745e0a7ba7816
Parents: fd6d083
Author: seif <se...@gmail.com>
Authored: Fri Aug 15 17:16:58 2014 +0200
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Sun Aug 17 20:38:46 2014 -0600

----------------------------------------------------------------------
 .../api/command/admin/host/ListHostTagsCmd.java |  64 ++++++++++
 .../api/response/HostTagResponse.java           |  60 +++++++++
 .../apache/cloudstack/query/QueryService.java   |   3 +
 client/tomcatconf/commands.properties.in        |   1 +
 .../spring-engine-schema-core-daos-context.xml  |   1 +
 server/src/com/cloud/api/ApiDBUtils.java        |  11 ++
 .../com/cloud/api/query/QueryManagerImpl.java   |  48 +++++++
 .../com/cloud/api/query/ViewResponseHelper.java |  13 +-
 .../src/com/cloud/api/query/dao/HostTagDao.java |  30 +++++
 .../com/cloud/api/query/dao/HostTagDaoImpl.java | 126 +++++++++++++++++++
 .../src/com/cloud/api/query/vo/HostTagVO.java   |  61 +++++++++
 .../com/cloud/server/ManagementServerImpl.java  |   3 +-
 12 files changed, 419 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/api/src/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java
new file mode 100644
index 0000000..5f55ada
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java
@@ -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.
+ */
+package org.apache.cloudstack.api.command.admin.host;
+
+import org.apache.log4j.Logger;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.HostTagResponse;
+
+@APICommand(name = "listHostTags", description = "Lists host tags", responseObject = HostTagResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ListHostTagsCmd extends BaseListCmd {
+    public static final Logger s_logger = Logger.getLogger(ListHostTagsCmd.class.getName());
+
+    private static final String s_name = "listhosttagsresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Host;
+    }
+
+    @Override
+    public void execute() {
+        ListResponse<HostTagResponse> response = _queryService.searchForHostTags(this);
+
+        response.setResponseName(getCommandName());
+
+        setResponseObject(response);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/api/src/org/apache/cloudstack/api/response/HostTagResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/HostTagResponse.java b/api/src/org/apache/cloudstack/api/response/HostTagResponse.java
new file mode 100644
index 0000000..91b01af
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/HostTagResponse.java
@@ -0,0 +1,60 @@
+// 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.cloudstack.api.response;
+
+import com.google.gson.annotations.SerializedName;
+import com.cloud.serializer.Param;
+
+import org.apache.cloudstack.api.BaseResponse;
+
+public class HostTagResponse extends BaseResponse {
+    @SerializedName("id")
+    @Param(description = "the ID of the host tag")
+    private String id;
+
+    @SerializedName("hostid")
+    @Param(description = "the host ID of the host tag")
+    private long hostId;
+
+    @SerializedName("name")
+    @Param(description = "the name of the host tag")
+    private String name;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/api/src/org/apache/cloudstack/query/QueryService.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java
index b45b7c3..0013be8 100644
--- a/api/src/org/apache/cloudstack/query/QueryService.java
+++ b/api/src/org/apache/cloudstack/query/QueryService.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
+import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
 import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
 import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
 import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
@@ -50,6 +51,7 @@ import org.apache.cloudstack.api.response.DiskOfferingResponse;
 import org.apache.cloudstack.api.response.DomainRouterResponse;
 import org.apache.cloudstack.api.response.EventResponse;
 import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HostTagResponse;
 import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
 import org.apache.cloudstack.api.response.ListResponse;
@@ -128,5 +130,6 @@ public interface QueryService {
 
     ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd);
     public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd);
+    public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index e3e892b..3191bbf 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -299,6 +299,7 @@ deleteHost=3
 prepareHostForMaintenance=1
 cancelHostMaintenance=1
 listHosts=3
+listHostTags=7
 findHostsForMigration=1
 addSecondaryStorage=1
 updateHostPassword=1

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
----------------------------------------------------------------------
diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
index b21ff43..9dd5571 100644
--- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
+++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
@@ -263,6 +263,7 @@
   <bean id="storagePoolDetailsDaoImpl" class="com.cloud.storage.dao.StoragePoolDetailsDaoImpl" />
   <bean id="storagePoolJoinDaoImpl" class="com.cloud.api.query.dao.StoragePoolJoinDaoImpl" />
   <bean id="storageTagDaoImpl" class="com.cloud.api.query.dao.StorageTagDaoImpl" />
+  <bean id="hostTagDaoImpl" class="com.cloud.api.query.dao.HostTagDaoImpl" />
   <bean id="storagePoolWorkDaoImpl" class="com.cloud.storage.dao.StoragePoolWorkDaoImpl" />
   <bean id="templatePrimaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDaoImpl" />
   <bean id="uploadDaoImpl" class="com.cloud.storage.dao.UploadDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index 8809778..37abdcb 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -41,6 +41,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse;
 import org.apache.cloudstack.api.response.EventResponse;
 import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HostTagResponse;
 import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
 import org.apache.cloudstack.api.response.ProjectAccountResponse;
@@ -74,6 +75,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao;
 import com.cloud.api.query.dao.DiskOfferingJoinDao;
 import com.cloud.api.query.dao.DomainRouterJoinDao;
 import com.cloud.api.query.dao.HostJoinDao;
+import com.cloud.api.query.dao.HostTagDao;
 import com.cloud.api.query.dao.ImageStoreJoinDao;
 import com.cloud.api.query.dao.InstanceGroupJoinDao;
 import com.cloud.api.query.dao.ProjectAccountJoinDao;
@@ -96,6 +98,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
 import com.cloud.api.query.vo.EventJoinVO;
 import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.api.query.vo.HostTagVO;
 import com.cloud.api.query.vo.ImageStoreJoinVO;
 import com.cloud.api.query.vo.InstanceGroupJoinVO;
 import com.cloud.api.query.vo.ProjectAccountJoinVO;
@@ -390,6 +393,7 @@ public class ApiDBUtils {
     static VolumeJoinDao s_volJoinDao;
     static StoragePoolJoinDao s_poolJoinDao;
     static StorageTagDao s_tagDao;
+    static HostTagDao s_hostTagDao;
     static ImageStoreJoinDao s_imageStoreJoinDao;
     static AccountJoinDao s_accountJoinDao;
     static AsyncJobJoinDao s_jobJoinDao;
@@ -587,6 +591,8 @@ public class ApiDBUtils {
     @Inject
     private StorageTagDao tagDao;
     @Inject
+    private HostTagDao hosttagDao;
+    @Inject
     private ImageStoreJoinDao imageStoreJoinDao;
     @Inject
     private AccountJoinDao accountJoinDao;
@@ -725,6 +731,7 @@ public class ApiDBUtils {
         s_volJoinDao = volJoinDao;
         s_poolJoinDao = poolJoinDao;
         s_tagDao = tagDao;
+        s_hostTagDao = hosttagDao;
         s_imageStoreJoinDao = imageStoreJoinDao;
         s_accountJoinDao = accountJoinDao;
         s_jobJoinDao = jobJoinDao;
@@ -1744,6 +1751,10 @@ public class ApiDBUtils {
         return s_tagDao.newStorageTagResponse(vr);
     }
 
+    public static HostTagResponse newHostTagResponse(HostTagVO vr) {
+        return s_hostTagDao.newHostTagResponse(vr);
+    }
+
     public static StoragePoolResponse fillStoragePoolDetails(StoragePoolResponse vrData, StoragePoolJoinVO vr) {
         return s_poolJoinDao.setStoragePoolResponse(vrData, vr);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
index 0b4eb6c..77338f3 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -36,6 +36,7 @@ import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
 import org.apache.cloudstack.api.ResourceDetail;
 import org.apache.cloudstack.api.ResponseObject.ResponseView;
 import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
 import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
 import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
 import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin;
@@ -72,6 +73,7 @@ import org.apache.cloudstack.api.response.DiskOfferingResponse;
 import org.apache.cloudstack.api.response.DomainRouterResponse;
 import org.apache.cloudstack.api.response.EventResponse;
 import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HostTagResponse;
 import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
 import org.apache.cloudstack.api.response.ListResponse;
@@ -107,6 +109,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao;
 import com.cloud.api.query.dao.DiskOfferingJoinDao;
 import com.cloud.api.query.dao.DomainRouterJoinDao;
 import com.cloud.api.query.dao.HostJoinDao;
+import com.cloud.api.query.dao.HostTagDao;
 import com.cloud.api.query.dao.ImageStoreJoinDao;
 import com.cloud.api.query.dao.InstanceGroupJoinDao;
 import com.cloud.api.query.dao.ProjectAccountJoinDao;
@@ -129,6 +132,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
 import com.cloud.api.query.vo.EventJoinVO;
 import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.api.query.vo.HostTagVO;
 import com.cloud.api.query.vo.ImageStoreJoinVO;
 import com.cloud.api.query.vo.InstanceGroupJoinVO;
 import com.cloud.api.query.vo.ProjectAccountJoinVO;
@@ -291,6 +295,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
     private StorageTagDao _storageTagDao;
 
     @Inject
+    private HostTagDao _hostTagDao;
+
+    @Inject
     private ImageStoreJoinDao _imageStoreJoinDao;
 
     @Inject
@@ -2184,6 +2191,47 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
     }
 
     @Override
+    public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd) {
+        Pair<List<HostTagVO>, Integer> result = searchForHostTagsInternal(cmd);
+        ListResponse<HostTagResponse> response = new ListResponse<HostTagResponse>();
+        List<HostTagResponse> tagResponses = ViewResponseHelper.createHostTagResponse(result.first().toArray(new HostTagVO[result.first().size()]));
+
+        response.setResponses(tagResponses, result.second());
+
+        return response;
+    }
+
+    private Pair<List<HostTagVO>, Integer> searchForHostTagsInternal(ListHostTagsCmd cmd) {
+        Filter searchFilter = new Filter(HostTagVO.class, "id", Boolean.TRUE, null, null);
+
+        SearchBuilder<HostTagVO> sb = _hostTagDao.createSearchBuilder();
+
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+
+        SearchCriteria<HostTagVO> sc = sb.create();
+
+        // search host tag details by ids
+        Pair<List<HostTagVO>, Integer> uniqueTagPair = _hostTagDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueTagPair.second();
+
+        if (count.intValue() == 0) {
+            return uniqueTagPair;
+        }
+
+        List<HostTagVO> uniqueTags = uniqueTagPair.first();
+        Long[] vrIds = new Long[uniqueTags.size()];
+        int i = 0;
+
+        for (HostTagVO v : uniqueTags) {
+            vrIds[i++] = v.getId();
+        }
+
+        List<HostTagVO> vrs = _hostTagDao.searchByIds(vrIds);
+
+        return new Pair<List<HostTagVO>, Integer>(vrs, count);
+    }
+
+    @Override
     public ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd) {
         Pair<List<ImageStoreJoinVO>, Integer> result = searchForImageStoresInternal(cmd);
         ListResponse<ImageStoreResponse> response = new ListResponse<ImageStoreResponse>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/server/src/com/cloud/api/query/ViewResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java
index f31a308..bec0048 100644
--- a/server/src/com/cloud/api/query/ViewResponseHelper.java
+++ b/server/src/com/cloud/api/query/ViewResponseHelper.java
@@ -23,7 +23,6 @@ import java.util.LinkedHashMap;
 import java.util.List;
 
 import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.api.ApiConstants.HostDetails;
 import org.apache.cloudstack.api.ApiConstants.VMDetails;
@@ -35,6 +34,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse;
 import org.apache.cloudstack.api.response.EventResponse;
 import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HostTagResponse;
 import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
 import org.apache.cloudstack.api.response.ProjectAccountResponse;
@@ -61,6 +61,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
 import com.cloud.api.query.vo.EventJoinVO;
 import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.api.query.vo.HostTagVO;
 import com.cloud.api.query.vo.ImageStoreJoinVO;
 import com.cloud.api.query.vo.InstanceGroupJoinVO;
 import com.cloud.api.query.vo.ProjectAccountJoinVO;
@@ -301,6 +302,16 @@ public class ViewResponseHelper {
         return list;
     }
 
+    public static List<HostTagResponse> createHostTagResponse(HostTagVO... hostTags) {
+        ArrayList<HostTagResponse> list = new ArrayList<HostTagResponse>();
+
+        for (HostTagVO vr : hostTags) {
+            list.add(ApiDBUtils.newHostTagResponse(vr));
+        }
+
+        return list;
+    }
+
     public static List<ImageStoreResponse> createImageStoreResponse(ImageStoreJoinVO... stores) {
         Hashtable<Long, ImageStoreResponse> vrDataList = new Hashtable<Long, ImageStoreResponse>();
         // Initialise the vrdatalist with the input data

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/server/src/com/cloud/api/query/dao/HostTagDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/HostTagDao.java b/server/src/com/cloud/api/query/dao/HostTagDao.java
new file mode 100644
index 0000000..f54ddfa
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/HostTagDao.java
@@ -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.
+package com.cloud.api.query.dao;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.response.HostTagResponse;
+
+import com.cloud.api.query.vo.HostTagVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface HostTagDao extends GenericDao<HostTagVO, Long> {
+    HostTagResponse newHostTagResponse(HostTagVO hostTag);
+
+    List<HostTagVO> searchByIds(Long... hostTagIds);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/server/src/com/cloud/api/query/dao/HostTagDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/HostTagDaoImpl.java b/server/src/com/cloud/api/query/dao/HostTagDaoImpl.java
new file mode 100644
index 0000000..d73deb5
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/HostTagDaoImpl.java
@@ -0,0 +1,126 @@
+// 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 com.cloud.api.query.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.response.HostTagResponse;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.api.query.vo.HostTagVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+@Local(value = {HostTagDao.class})
+public class HostTagDaoImpl extends GenericDaoBase<HostTagVO, Long> implements HostTagDao {
+    public static final Logger s_logger = Logger.getLogger(HostTagDaoImpl.class);
+
+    @Inject
+    private ConfigurationDao _configDao;
+
+    private final SearchBuilder<HostTagVO> stSearch;
+    private final SearchBuilder<HostTagVO> stIdSearch;
+
+    protected HostTagDaoImpl() {
+        stSearch = createSearchBuilder();
+
+        stSearch.and("idIN", stSearch.entity().getId(), SearchCriteria.Op.IN);
+        stSearch.done();
+
+        stIdSearch = createSearchBuilder();
+
+        stIdSearch.and("id", stIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        stIdSearch.done();
+
+        _count = "select count(distinct id) from host_tags WHERE ";
+    }
+
+    @Override
+    public HostTagResponse newHostTagResponse(HostTagVO tag) {
+        HostTagResponse tagResponse = new HostTagResponse();
+
+        tagResponse.setName(tag.getName());
+        tagResponse.setHostId(tag.getHostId());
+
+        tagResponse.setObjectName("hosttag");
+
+        return tagResponse;
+    }
+
+    @Override
+    public List<HostTagVO> searchByIds(Long... stIds) {
+        String batchCfg = _configDao.getValue("detail.batch.query.size");
+
+        final int detailsBatchSize = batchCfg != null ? Integer.parseInt(batchCfg) : 2000;
+
+        // query details by batches
+        List<HostTagVO> uvList = new ArrayList<HostTagVO>();
+        int curr_index = 0;
+
+        if (stIds.length > detailsBatchSize) {
+            while ((curr_index + detailsBatchSize) <= stIds.length) {
+                Long[] ids = new Long[detailsBatchSize];
+
+                for (int k = 0, j = curr_index; j < curr_index + detailsBatchSize; j++, k++) {
+                    ids[k] = stIds[j];
+                }
+
+                SearchCriteria<HostTagVO> sc = stSearch.create();
+
+                sc.setParameters("idIN", (Object[])ids);
+
+                List<HostTagVO> vms = searchIncludingRemoved(sc, null, null, false);
+
+                if (vms != null) {
+                    uvList.addAll(vms);
+                }
+
+                curr_index += detailsBatchSize;
+            }
+        }
+
+        if (curr_index < stIds.length) {
+            int batch_size = (stIds.length - curr_index);
+            // set the ids value
+            Long[] ids = new Long[batch_size];
+
+            for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+                ids[k] = stIds[j];
+            }
+
+            SearchCriteria<HostTagVO> sc = stSearch.create();
+
+            sc.setParameters("idIN", (Object[])ids);
+
+            List<HostTagVO> vms = searchIncludingRemoved(sc, null, null, false);
+
+            if (vms != null) {
+                uvList.addAll(vms);
+            }
+        }
+
+        return uvList;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/server/src/com/cloud/api/query/vo/HostTagVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/HostTagVO.java b/server/src/com/cloud/api/query/vo/HostTagVO.java
new file mode 100644
index 0000000..60db16a
--- /dev/null
+++ b/server/src/com/cloud/api/query/vo/HostTagVO.java
@@ -0,0 +1,61 @@
+// 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 com.cloud.api.query.vo;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+/**
+ * Storage Tags DB view.
+ *
+ */
+@Entity
+@Table(name = "host_tags")
+public class HostTagVO extends BaseViewVO implements InternalIdentity {
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "tag")
+    private String name;
+
+    @Column(name = "host_id")
+    long hostId;
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59ea2e29/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 280009b..c320089 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -40,7 +40,6 @@ import javax.naming.ConfigurationException;
 import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.affinity.AffinityGroupProcessor;
 import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@@ -84,6 +83,7 @@ import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
 import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
 import org.apache.cloudstack.api.command.admin.host.DeleteHostCmd;
 import org.apache.cloudstack.api.command.admin.host.FindHostsForMigrationCmd;
+import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
 import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
 import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
 import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
@@ -2564,6 +2564,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(CancelMaintenanceCmd.class);
         cmdList.add(DeleteHostCmd.class);
         cmdList.add(ListHostsCmd.class);
+        cmdList.add(ListHostTagsCmd.class);
         cmdList.add(FindHostsForMigrationCmd.class);
         cmdList.add(PrepareForMaintenanceCmd.class);
         cmdList.add(ReconnectHostCmd.class);


[14/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
SAML2: add saml sso and slo apicmds skeleton, add classes to AuthManager

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/329b2096
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/329b2096
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/329b2096

Branch: refs/heads/saml2
Commit: 329b20960fc405c97bf2f9e27a1f25bd25ba44b6
Parents: 6a8f831
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Tue Aug 12 13:10:05 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:34 2014 +0200

----------------------------------------------------------------------
 .../org/apache/cloudstack/api/ApiConstants.java |  1 +
 .../api/auth/APIAuthenticationManagerImpl.java  |  2 +
 .../api/auth/SAML2LoginAPIAuthenticatorCmd.java | 94 ++++++++++++++++++++
 .../auth/SAML2LogoutAPIAuthenticatorCmd.java    | 71 +++++++++++++++
 4 files changed, 168 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/329b2096/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index f89aa14..6baa95c 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -514,6 +514,7 @@ public class ApiConstants {
     public static final String VMPROFILE_ID = "vmprofileid";
     public static final String VMGROUP_ID = "vmgroupid";
     public static final String CS_URL = "csurl";
+    public static final String IDP_URL = "idpurl";
     public static final String SCALEUP_POLICY_IDS = "scaleuppolicyids";
     public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids";
     public static final String SCALEUP_POLICIES = "scaleuppolicies";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/329b2096/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java b/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
index 886d277..ece2e03 100644
--- a/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
+++ b/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
@@ -57,6 +57,8 @@ public class APIAuthenticationManagerImpl extends ManagerBase implements APIAuth
             s_commandList = new ArrayList<Class<?>>();
             s_commandList.add(DefaultLoginAPIAuthenticatorCmd.class);
             s_commandList.add(DefaultLogoutAPIAuthenticatorCmd.class);
+            s_commandList.add(SAML2LoginAPIAuthenticatorCmd.class);
+            s_commandList.add(SAML2LogoutAPIAuthenticatorCmd.class);
         }
         return s_commandList;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/329b2096/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
new file mode 100644
index 0000000..beba4f1
--- /dev/null
+++ b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
@@ -0,0 +1,94 @@
+// 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 com.cloud.api.auth;
+
+import com.cloud.user.Account;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoginCmdResponse;
+import org.apache.log4j.Logger;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.util.Map;
+
+@APICommand(name = "samlsso", description = "SP initiated SAML Single Sign On", requestHasSensitiveInfo = true, responseObject = LoginCmdResponse.class, entityType = {})
+public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator {
+    public static final Logger s_logger = Logger.getLogger(SAML2LoginAPIAuthenticatorCmd.class.getName());
+    private static final String s_name = "loginresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @Parameter(name = ApiConstants.IDP_URL, type = CommandType.STRING, description = "Identity Provider SSO HTTP-Redirect binding URL", required = true)
+    private String idpUrl;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getIdpUrl() {
+        return idpUrl;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_TYPE_NORMAL;
+    }
+
+    @Override
+    public void execute() throws ServerApiException {
+        // We should never reach here
+        throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "This is an authentication api, cannot be used directly");
+    }
+
+    @Override
+    public String authenticate(String command, Map<String, Object[]> params, HttpSession session, String remoteAddress, String responseType, StringBuilder auditTrailSb, final HttpServletResponse resp) throws ServerApiException {
+
+        String response = null;
+        try {
+            resp.sendRedirect(getIdpUrl());
+
+            // TODO: create and send assertion with the URL as GET params
+
+        } catch (IOException e) {
+            auditTrailSb.append("SP initiated SAML authentication using HTTP redirection failed:");
+            auditTrailSb.append(e.getMessage());
+        }
+        return response;
+    }
+
+    @Override
+    public APIAuthenticationType getAPIType() {
+        return APIAuthenticationType.LOGIN_API;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/329b2096/server/src/com/cloud/api/auth/SAML2LogoutAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/SAML2LogoutAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/SAML2LogoutAPIAuthenticatorCmd.java
new file mode 100644
index 0000000..9119588
--- /dev/null
+++ b/server/src/com/cloud/api/auth/SAML2LogoutAPIAuthenticatorCmd.java
@@ -0,0 +1,71 @@
+// 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 com.cloud.api.auth;
+
+import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.user.Account;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LogoutCmdResponse;
+import org.apache.log4j.Logger;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.util.Map;
+
+@APICommand(name = "samlslo", description = "SAML Single Log Out API", responseObject = LogoutCmdResponse.class, entityType = {})
+public class SAML2LogoutAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator {
+    public static final Logger s_logger = Logger.getLogger(SAML2LogoutAPIAuthenticatorCmd.class.getName());
+    private static final String s_name = "logoutresponse";
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_TYPE_NORMAL;
+    }
+
+    @Override
+    public void execute() throws ServerApiException {
+        // We should never reach here
+        throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "This is an authentication api, cannot be used directly");
+    }
+
+    @Override
+    public String authenticate(String command, Map<String, Object[]> params, HttpSession session, String remoteAddress, String responseType, StringBuilder auditTrailSb, final HttpServletResponse resp) throws ServerApiException {
+        auditTrailSb.append("=== Logging out ===");
+        // TODO: check global config and do either local or global log out
+        LogoutCmdResponse response = new LogoutCmdResponse();
+        response.setDescription("success");
+        response.setResponseName(getCommandName());
+        return ApiResponseSerializer.toSerializedString(response, responseType);
+    }
+
+    @Override
+    public APIAuthenticationType getAPIType() {
+        return APIAuthenticationType.LOGOUT_API;
+    }
+}


[18/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
SAML2LoginAPIAuthenticatorCmd: Implement SAML SSO using HTTP Redirect binding

- Creates SAMLRequest and uses HTTP redirect binding (uses GET/302)
- Redirects to IdP for auth
- On successful auth, check for assertion
- Tries to get attributes based on standard LDAP attribute names
- Next, gets user using EntityManager, if not found creates one with NameID as UUID
- Finally tries to log in and redirect

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/cc9206c7
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/cc9206c7
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/cc9206c7

Branch: refs/heads/saml2
Commit: cc9206c70c5c8b1b1f9be16fbbb0eea594926322
Parents: 64ecfdf
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 03:43:58 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:35 2014 +0200

----------------------------------------------------------------------
 .../api/auth/SAML2LoginAPIAuthenticatorCmd.java | 289 ++++++++++---------
 1 file changed, 153 insertions(+), 136 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cc9206c7/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
index c6b0bb6..4e17d3d 100644
--- a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
@@ -17,7 +17,13 @@
 
 package com.cloud.api.auth;
 
+import com.cloud.api.ApiServerService;
+import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.exception.CloudAuthenticationException;
 import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.utils.HttpUtils;
+import com.cloud.utils.db.EntityManager;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -25,18 +31,26 @@ import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.LoginCmdResponse;
+import org.apache.cloudstack.context.CallContext;
 import org.apache.log4j.Logger;
 import org.joda.time.DateTime;
 import org.opensaml.Configuration;
 import org.opensaml.DefaultBootstrap;
 import org.opensaml.common.SAMLVersion;
 import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeStatement;
 import org.opensaml.saml2.core.AuthnContextClassRef;
 import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
 import org.opensaml.saml2.core.AuthnRequest;
 import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
 import org.opensaml.saml2.core.NameIDPolicy;
+import org.opensaml.saml2.core.NameIDType;
 import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.StatusCode;
 import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder;
 import org.opensaml.saml2.core.impl.AuthnRequestBuilder;
 import org.opensaml.saml2.core.impl.IssuerBuilder;
@@ -49,15 +63,15 @@ import org.opensaml.xml.io.MarshallingException;
 import org.opensaml.xml.io.Unmarshaller;
 import org.opensaml.xml.io.UnmarshallerFactory;
 import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.signature.Signature;
 import org.opensaml.xml.util.Base64;
 import org.opensaml.xml.util.XMLHelper;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
+import javax.inject.Inject;
+import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import javax.xml.parsers.DocumentBuilder;
@@ -71,6 +85,7 @@ import java.io.StringWriter;
 import java.math.BigInteger;
 import java.net.URLEncoder;
 import java.security.SecureRandom;
+import java.util.List;
 import java.util.Map;
 import java.util.zip.Deflater;
 import java.util.zip.DeflaterOutputStream;
@@ -86,6 +101,11 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
     @Parameter(name = ApiConstants.IDP_URL, type = CommandType.STRING, description = "Identity Provider SSO HTTP-Redirect binding URL", required = true)
     private String idpUrl;
 
+    @Inject
+    ApiServerService _apiServer;
+    @Inject
+    EntityManager _entityMgr;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -114,34 +134,30 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
         throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "This is an authentication api, cannot be used directly");
     }
 
-    public String buildAuthnRequestUrl(String resourceUrl) {
+    public String buildAuthnRequestUrl(String consumerUrl, String identityProviderUrl) {
         String randomId = new BigInteger(130, new SecureRandom()).toString(32);
-        // TODO: Add method to get this url from metadata
-        String identityProviderUrl = "https://idp.ssocircle.com:443/sso/SSORedirect/metaAlias/ssocircle";
-        String encodedAuthRequest = "";
-
+        String spId = "org.apache.cloudstack";
+        String redirectUrl = "";
         try {
             DefaultBootstrap.bootstrap();
-            AuthnRequest authnRequest = this.buildAuthnRequestObject(randomId, identityProviderUrl, resourceUrl); // SAML AuthRequest
-            encodedAuthRequest = encodeAuthnRequest(authnRequest);
+            AuthnRequest authnRequest = this.buildAuthnRequestObject(randomId, spId, identityProviderUrl, consumerUrl);
+            redirectUrl = identityProviderUrl + "?SAMLRequest=" + encodeAuthnRequest(authnRequest);
         } catch (ConfigurationException | FactoryConfigurationError | MarshallingException | IOException e) {
             s_logger.error("SAML AuthnRequest message building error: " + e.getMessage());
         }
-        return identityProviderUrl + "?SAMLRequest=" + encodedAuthRequest; // + "&RelayState=" + relayState;
+        return redirectUrl;
     }
 
-    private AuthnRequest buildAuthnRequestObject(String authnId, String idpUrl, String consumerUrl) {
+    private AuthnRequest buildAuthnRequestObject(String authnId, String spId, String idpUrl, String consumerUrl) {
         // Issuer object
         IssuerBuilder issuerBuilder = new IssuerBuilder();
         Issuer issuer = issuerBuilder.buildObject();
-        //SAMLConstants.SAML20_NS,
-        //        "Issuer", "samlp");
-        issuer.setValue("apache-cloudstack");
+        issuer.setValue(spId);
 
         // NameIDPolicy
         NameIDPolicyBuilder nameIdPolicyBuilder = new NameIDPolicyBuilder();
         NameIDPolicy nameIdPolicy = nameIdPolicyBuilder.buildObject();
-        nameIdPolicy.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
+        nameIdPolicy.setFormat(NameIDType.PERSISTENT);
         nameIdPolicy.setSPNameQualifier("Apache CloudStack");
         nameIdPolicy.setAllowCreate(true);
 
@@ -156,16 +172,13 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
         RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder();
         RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
         requestedAuthnContext
-                .setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
+                .setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM);
         requestedAuthnContext.getAuthnContextClassRefs().add(
                 authnContextClassRef);
 
-
         // Creation of AuthRequestObject
         AuthnRequestBuilder authRequestBuilder = new AuthnRequestBuilder();
         AuthnRequest authnRequest = authRequestBuilder.buildObject();
-        //SAMLConstants.SAML20P_NS,
-        //        "AuthnRequest", "samlp");
         authnRequest.setID(authnId);
         authnRequest.setDestination(idpUrl);
         authnRequest.setVersion(SAMLVersion.VERSION_20);
@@ -174,154 +187,158 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
         authnRequest.setIssuer(issuer);
         authnRequest.setIssueInstant(new DateTime());
         authnRequest.setProviderName("Apache CloudStack");
-        authnRequest.setProtocolBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
+        authnRequest.setProtocolBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); //SAML2_ARTIFACT_BINDING_URI);
         authnRequest.setAssertionConsumerServiceURL(consumerUrl);
-        //authnRequest.setNameIDPolicy(nameIdPolicy);
-        //authnRequest.setRequestedAuthnContext(requestedAuthnContext);
+        authnRequest.setNameIDPolicy(nameIdPolicy);
+        authnRequest.setRequestedAuthnContext(requestedAuthnContext);
 
         return authnRequest;
     }
 
     private String encodeAuthnRequest(AuthnRequest authnRequest)
             throws MarshallingException, IOException {
-
-        Marshaller marshaller = null;
-        org.w3c.dom.Element authDOM = null;
-        StringWriter requestWriter = null;
-        String requestMessage = null;
-        Deflater deflater = null;
-        ByteArrayOutputStream byteArrayOutputStream = null;
-        DeflaterOutputStream deflaterOutputStream = null;
-        String encodedRequestMessage = null;
-
-        marshaller = org.opensaml.Configuration.getMarshallerFactory()
-                .getMarshaller(authnRequest); // object to DOM converter
-
-        authDOM = marshaller.marshall(authnRequest); // converting to a DOM
-
-        requestWriter = new StringWriter();
+        Marshaller marshaller = Configuration.getMarshallerFactory()
+                .getMarshaller(authnRequest);
+        Element authDOM = marshaller.marshall(authnRequest);
+        StringWriter requestWriter = new StringWriter();
         XMLHelper.writeNode(authDOM, requestWriter);
-        requestMessage = requestWriter.toString(); // DOM to string
-
-        deflater = new Deflater(Deflater.DEFLATED, true);
-        byteArrayOutputStream = new ByteArrayOutputStream();
-        deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream,
-                deflater);
-        deflaterOutputStream.write(requestMessage.getBytes()); // compressing
+        String requestMessage = requestWriter.toString();
+        Deflater deflater = new Deflater(Deflater.DEFLATED, true);
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
+        deflaterOutputStream.write(requestMessage.getBytes());
         deflaterOutputStream.close();
-
-        encodedRequestMessage = Base64.encodeBytes(byteArrayOutputStream
-                .toByteArray(), Base64.DONT_BREAK_LINES);
-        encodedRequestMessage = URLEncoder.encode(encodedRequestMessage,
-                "UTF-8").trim(); // encoding string
-
+        String encodedRequestMessage = Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);
+        encodedRequestMessage = URLEncoder.encode(encodedRequestMessage, "UTF-8").trim();
         return encodedRequestMessage;
     }
 
-
-    public String processResponseMessage(String responseMessage) {
-
+    public Response processSAMLResponse(String responseMessage) {
         XMLObject responseObject = null;
-
         try {
-
             responseObject = this.unmarshall(responseMessage);
 
         } catch (ConfigurationException | ParserConfigurationException | SAXException | IOException | UnmarshallingException e) {
-            e.printStackTrace();
+            s_logger.error("SAMLResponse processing error: " + e.getMessage());
         }
-
-        return this.getResult(responseObject);
+        return (Response) responseObject;
     }
 
     private XMLObject unmarshall(String responseMessage)
             throws ConfigurationException, ParserConfigurationException,
             SAXException, IOException, UnmarshallingException {
-
-        DocumentBuilderFactory documentBuilderFactory = null;
-        DocumentBuilder docBuilder = null;
-        Document document = null;
-        Element element = null;
-        UnmarshallerFactory unmarshallerFactory = null;
-        Unmarshaller unmarshaller = null;
-
-        DefaultBootstrap.bootstrap();
-
-        documentBuilderFactory = DocumentBuilderFactory.newInstance();
-
+        try {
+            DefaultBootstrap.bootstrap();
+        } catch (ConfigurationException | FactoryConfigurationError e) {
+            s_logger.error("SAML response message decoding error: " + e.getMessage());
+        }
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
         documentBuilderFactory.setNamespaceAware(true);
-
-        docBuilder = documentBuilderFactory.newDocumentBuilder();
-
-        document = docBuilder.parse(new ByteArrayInputStream(responseMessage
-                .trim().getBytes())); // response to DOM
-
-        element = document.getDocumentElement(); // the DOM element
-
-        unmarshallerFactory = Configuration.getUnmarshallerFactory();
-
-        unmarshaller = unmarshallerFactory.getUnmarshaller(element);
-
-        return unmarshaller.unmarshall(element); // Response object
-
-    }
-
-    private String getResult(XMLObject responseObject) {
-
-        Element ele = null;
-        NodeList statusNodeList = null;
-        Node statusNode = null;
-        NamedNodeMap statusAttr = null;
-        Node valueAtt = null;
-        String statusValue = null;
-
-        String[] word = null;
-        String result = null;
-
-        NodeList nameIDNodeList = null;
-        Node nameIDNode = null;
-        String nameID = null;
-
-        // reading the Response Object
-        ele = responseObject.getDOM();
-        statusNodeList = ele.getElementsByTagName("samlp:StatusCode");
-        statusNode = statusNodeList.item(0);
-        statusAttr = statusNode.getAttributes();
-        valueAtt = statusAttr.item(0);
-        statusValue = valueAtt.getNodeValue();
-
-        word = statusValue.split(":");
-        result = word[word.length - 1];
-
-        nameIDNodeList = ele.getElementsByTagNameNS(
-                "urn:oasis:names:tc:SAML:2.0:assertion", "NameID");
-        nameIDNode = nameIDNodeList.item(0);
-        nameID = nameIDNode.getFirstChild().getNodeValue();
-
-        result = nameID + ":" + result;
-
-        return result;
+        DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
+        byte[] base64DecodedResponse = Base64.decode(responseMessage);
+        Document document = docBuilder.parse(new ByteArrayInputStream(base64DecodedResponse));
+        Element element = document.getDocumentElement();
+        UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
+        Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
+        return unmarshaller.unmarshall(element);
     }
 
-
-
     @Override
-    public String authenticate(String command, Map<String, Object[]> params, HttpSession session, String remoteAddress, String responseType, StringBuilder auditTrailSb, final HttpServletResponse resp) throws ServerApiException {
-        String response = null;
+    public String authenticate(final String command, final Map<String, Object[]> params, final HttpSession session, final String remoteAddress, final String responseType, final StringBuilder auditTrailSb, final HttpServletResponse resp) throws ServerApiException {
         try {
-            String redirectUrl = buildAuthnRequestUrl("http://localhost:8080/client/api?command=login");
-            resp.sendRedirect(redirectUrl);
-
-            //resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
-            //resp.setHeader("Location", redirectUrl);
-
-            // TODO: create and send assertion with the URL as GET params
-
+            if (!params.containsKey("SAMLResponse")) {
+                final String[] idps = (String[])params.get("idpurl");
+                String redirectUrl = buildAuthnRequestUrl("http://localhost:8080/client/api?command=samlsso", idps[0]);
+                resp.sendRedirect(redirectUrl);
+                return "";
+            } else {
+                final String samlResponse = ((String[])params.get("SAMLResponse"))[0];
+                Response processedSAMLResponse = processSAMLResponse(samlResponse);
+                String statusCode = processedSAMLResponse.getStatus().getStatusCode().getValue();
+                if (!statusCode.equals(StatusCode.SUCCESS_URI)) {
+                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                            "Identity Provider send a non-successful authentication status code",
+                            params, responseType));
+                }
+
+                Signature sig = processedSAMLResponse.getSignature();
+                //SignatureValidator validator = new SignatureValidator(credential);
+                //validator.validate(sig);
+
+                String uniqueUserId = null;
+                String accountName = "admin"; //GET from config, try, fail
+                Long domainId = 1L; // GET from config, try, fail
+                String username = null;
+                String password = "";
+                String firstName = "";
+                String lastName = "";
+                String timeZone = "";
+                String email = "";
+
+                Assertion assertion = processedSAMLResponse.getAssertions().get(0);
+                NameID nameId = assertion.getSubject().getNameID();
+
+                if (nameId.getFormat().equals(NameIDType.PERSISTENT) || nameId.getFormat().equals(NameIDType.EMAIL)) {
+                    username = nameId.getValue();
+                    uniqueUserId = "saml-" + username;
+                    if (nameId.getFormat().equals(NameIDType.EMAIL)) {
+                        email = username;
+                    }
+                }
+
+                String issuer = assertion.getIssuer().getValue();
+                String audience = assertion.getConditions().getAudienceRestrictions().get(0).getAudiences().get(0).getAudienceURI();
+                AttributeStatement attributeStatement = assertion.getAttributeStatements().get(0);
+                List<Attribute> attributes = attributeStatement.getAttributes();
+
+                // Try capturing standard LDAP attributes
+                for (Attribute attribute: attributes) {
+                    String attributeName = attribute.getName();
+                    String attributeValue = attribute.getAttributeValues().get(0).getDOM().getTextContent();
+                    if (attributeName.equalsIgnoreCase("uid") && uniqueUserId == null) {
+                        username = attributeValue;
+                        uniqueUserId = "saml-" + username;
+                    } else if (attributeName.equalsIgnoreCase("givenName")) {
+                        firstName = attributeValue;
+                    } else if (attributeName.equalsIgnoreCase(("sn"))) {
+                        lastName = attributeValue;
+                    } else if (attributeName.equalsIgnoreCase("mail")) {
+                        email = attributeValue;
+                    }
+                }
+
+                User user = _entityMgr.findByUuid(User.class, uniqueUserId);
+                if (user == null && uniqueUserId != null && username != null
+                        && accountName != null && domainId != null) {
+                    CallContext.current().setEventDetails("UserName: " + username + ", FirstName :" + password + ", LastName: " + lastName);
+                    user = _accountService.createUser(username, password, firstName, lastName, email, timeZone, accountName, domainId, uniqueUserId);
+                }
+
+                if (user != null) {
+                    try {
+                        if (_apiServer.verifyUser(user.getId())) {
+                            LoginCmdResponse loginResponse = (LoginCmdResponse) _apiServer.loginUser(session, username, user.getPassword(), domainId, null, remoteAddress, params);
+                            resp.addCookie(new Cookie("userid", loginResponse.getUserId()));
+                            resp.addCookie(new Cookie("domainid", loginResponse.getDomainId()));
+                            resp.addCookie(new Cookie("role", loginResponse.getType()));
+                            resp.addCookie(new Cookie("username", URLEncoder.encode(loginResponse.getUsername(), HttpUtils.UTF_8)));
+                            resp.addCookie(new Cookie("sessionKey", URLEncoder.encode(loginResponse.getSessionKey(), HttpUtils.UTF_8)));
+                            resp.addCookie(new Cookie("account", URLEncoder.encode(loginResponse.getAccount(), HttpUtils.UTF_8)));
+                            //resp.sendRedirect("http://localhost:8080/client");
+                            return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
+
+                        }
+                    } catch (final CloudAuthenticationException ignored) {
+                    }
+                }
+            }
         } catch (IOException e) {
             auditTrailSb.append("SP initiated SAML authentication using HTTP redirection failed:");
             auditTrailSb.append(e.getMessage());
         }
-        return response;
+        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                "Unable to authenticate or retrieve user while performing SAML based SSO",
+                params, responseType));
     }
 
     @Override


[05/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
GUI modifications related to host tags


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/aadb5f4a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/aadb5f4a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/aadb5f4a

Branch: refs/heads/saml2
Commit: aadb5f4ad57b1c77f80ff511f8838911b500c0ab
Parents: 8bc7ae6
Author: seif <se...@gmail.com>
Authored: Mon Aug 18 06:40:16 2014 +0200
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Sun Aug 17 23:44:35 2014 -0600

----------------------------------------------------------------------
 ui/scripts/system.js                | 68 ++++++++++++++++++++++++++++++--
 ui/scripts/ui/widgets/detailView.js |  3 +-
 2 files changed, 65 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aadb5f4a/ui/scripts/system.js
----------------------------------------------------------------------
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index db1629f..f0e97e5 100644
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -15173,9 +15173,39 @@
                                     //always appear (begin)
                                     hosttags: {
                                         label: 'label.host.tags',
+                                        isTokenInput: true,
                                         docID: 'helpHostTags',
                                         validation: {
                                             required: false
+                                        },
+                                        dataProvider: function(args) {
+                                            $.ajax({
+                                                url: createURL("listHostTags"),
+                                                dataType: "json",
+                                                success: function(json) {
+                                                    var item = json.listhosttagsresponse.hosttag;
+                                                    var tags = [];
+
+                                                    if (item != null)
+                                                    {
+                                                        tags = $.map(item, function(tag) {
+                                                            return {
+                                                                       id: tag.name,
+                                                                       name: tag.name
+                                                                   };
+                                                        });
+                                                    }
+
+                                                    args.response.success({
+                                                        data: tags
+                                                    });
+                                                },
+                                                error: function(XMLHttpResponse) {
+                                                    var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
+
+                                                    args.response.error(errorMsg);
+                                                }
+                                            });
                                         }
                                     }
                                     //always appear (end)
@@ -15739,7 +15769,37 @@
                                     },
                                     hosttags: {
                                         label: 'label.host.tags',
-                                        isEditable: true
+                                        isEditable: true,
+                                        isTokenInput: true,
+                                        dataProvider: function(args) {
+                                            $.ajax({
+                                                url: createURL("listHostTags"),
+                                                dataType: "json",
+                                                success: function(json) {
+                                                    var item = json.listhosttagsresponse.hosttag;
+                                                    var tags = [];
+
+                                                    if (item != null)
+                                                    {
+                                                        tags = $.map(item, function(tag) {
+                                                            return {
+                                                                       id: tag.name,
+                                                                       name: tag.name
+                                                                   };
+                                                        });
+                                                    }
+
+                                                    args.response.success({
+                                                        data: tags
+                                                    });
+                                                },
+                                                error: function(XMLHttpResponse) {
+                                                    var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
+
+                                                    args.response.error(errorMsg);
+                                                }
+                                            });
+                                        }
                                     },
                                     hahost: {
                                         label: 'label.ha.enabled',
@@ -16895,7 +16955,7 @@
                                             $.ajax({
                                                 url: createURL("listStorageTags"),
                                                 dataType: "json",
-                                                success: function (json) {
+                                                success: function(json) {
                                                     var item = json.liststoragetagsresponse.storagetag;
                                                     var tags = [];
 
@@ -16913,7 +16973,7 @@
                                                         data: tags
                                                     });
                                                 },
-                                                error: function (XMLHttpResponse) {
+                                                error: function(XMLHttpResponse) {
                                                     var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
 
                                                     args.response.error(errorMsg);
@@ -17272,7 +17332,7 @@
                                                         data: tags
                                                     });
                                                 },
-                                                error: function (XMLHttpResponse) {
+                                                error: function(XMLHttpResponse) {
                                                     var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
 
                                                     args.response.error(errorMsg);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aadb5f4a/ui/scripts/ui/widgets/detailView.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js
index 33d0d14..92f1e2c 100644
--- a/ui/scripts/ui/widgets/detailView.js
+++ b/ui/scripts/ui/widgets/detailView.js
@@ -487,7 +487,7 @@
                         {
                             $token = $value;
                         }
-                        else if ($input.attr('name') === "tags")
+                        else if (($input.attr('name') === "tags") || ($input.attr('name') === "hosttags"))
                         {
                             tags_value = $input.attr('value');
                         }
@@ -570,7 +570,6 @@
                         }
                     });
 
-                    data['token-input-'] = data['tags'];
                     $editButton.fadeOut('fast', function() {
                         $editButton.remove();
                     });


[19/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
ApiServlet: Fix NPE while inserting to auditTrail

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/9ed7b124
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/9ed7b124
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/9ed7b124

Branch: refs/heads/saml2
Commit: 9ed7b12485357fe286c8aaa0f5515f1396225c27
Parents: cc9206c
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 03:50:18 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:35 2014 +0200

----------------------------------------------------------------------
 server/src/com/cloud/api/ApiServlet.java | 3 ---
 1 file changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9ed7b124/server/src/com/cloud/api/ApiServlet.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java
index 5484b1e..8dff6eb 100644
--- a/server/src/com/cloud/api/ApiServlet.java
+++ b/server/src/com/cloud/api/ApiServlet.java
@@ -201,9 +201,6 @@ public class ApiServlet extends HttpServlet {
                             } catch (final IllegalStateException ignored) {
                             }
                         }
-                    } else {
-                        auditTrailSb.insert(0, "(userId=" + session.getAttribute("userid") + " accountId=" + ((Account) session.getAttribute("accountobj")).getId() +
-                                " sessionId=" + session.getId() + ")");
                     }
                     HttpUtils.writeHttpResponse(resp, responseString, httpResponseCode, responseType);
                     return;


[20/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
ui: Unbox extra quotes from sessionKey cookie value

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/f80f6686
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/f80f6686
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/f80f6686

Branch: refs/heads/saml2
Commit: f80f6686a5f051fbefcf76aa13e31c8037c49bd2
Parents: 9ed7b12
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 04:20:03 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:35 2014 +0200

----------------------------------------------------------------------
 ui/scripts/cloudStack.js | 7 +++++++
 1 file changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f80f6686/ui/scripts/cloudStack.js
----------------------------------------------------------------------
diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js
index b6dd559..420c137 100644
--- a/ui/scripts/cloudStack.js
+++ b/ui/scripts/cloudStack.js
@@ -131,6 +131,13 @@
            */
                     g_mySession = $.cookie('JSESSIONID');
                     g_sessionKey = $.cookie('sessionKey');
+                    // Unbox quotes from sessionKey cookie value
+                    if (g_sessionKey[0] === '"' && g_sessionKey[g_sessionKey.length-1] === '"') {
+                        g_sessionKey = g_sessionKey.slice(1, g_sessionKey.length-1);
+                        $.cookie('sessionKey', g_sessionKey, {
+                            expires: 1
+                        });
+                    }
                     g_role = $.cookie('role');
                     g_username = $.cookie('username');
                     g_userid = $.cookie('userid');


[21/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
SAML2LoginAPIAuthenticatorCmd: Set all necessary cookies and redirect to UI

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ce285f6b
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ce285f6b
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ce285f6b

Branch: refs/heads/saml2
Commit: ce285f6bbea3ee3fa1c9e6f921b2baaa58983314
Parents: f80f668
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 04:20:54 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:35 2014 +0200

----------------------------------------------------------------------
 server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce285f6b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
index 4e17d3d..1f88c1c 100644
--- a/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/SAML2LoginAPIAuthenticatorCmd.java
@@ -324,7 +324,9 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
                             resp.addCookie(new Cookie("username", URLEncoder.encode(loginResponse.getUsername(), HttpUtils.UTF_8)));
                             resp.addCookie(new Cookie("sessionKey", URLEncoder.encode(loginResponse.getSessionKey(), HttpUtils.UTF_8)));
                             resp.addCookie(new Cookie("account", URLEncoder.encode(loginResponse.getAccount(), HttpUtils.UTF_8)));
-                            //resp.sendRedirect("http://localhost:8080/client");
+                            resp.addCookie(new Cookie("timezone", URLEncoder.encode(loginResponse.getTimeZone(), HttpUtils.UTF_8)));
+                            resp.addCookie(new Cookie("userfullname", URLEncoder.encode(loginResponse.getFirstName() + " " + loginResponse.getLastName(), HttpUtils.UTF_8)));
+                            resp.sendRedirect("http://localhost:8080/client");
                             return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
 
                         }


[06/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
CLOUDSTACK-7359. Make sure timeout value is set for the MigrateVolumeCommand. This will
make sure the agent waits for the resource to complete (success/failure) migration of
volume on the hypervisor.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/f099732b
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/f099732b
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/f099732b

Branch: refs/heads/saml2
Commit: f099732be70c8ffa6d69870cc4b57f1ac3142cc0
Parents: 1c688f4
Author: Devdeep Singh <de...@gmail.com>
Authored: Mon Aug 18 11:36:28 2014 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Mon Aug 18 11:38:29 2014 +0530

----------------------------------------------------------------------
 core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java | 6 ++++--
 .../cloudstack/storage/motion/AncientDataMotionStrategy.java   | 5 ++++-
 2 files changed, 8 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f099732b/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java b/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java
index 85f0bf4..e5ba211 100644
--- a/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java
+++ b/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java
@@ -30,17 +30,19 @@ public class MigrateVolumeCommand extends Command {
     StorageFilerTO pool;
     String attachedVmName;
 
-    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool) {
+    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, int timeout) {
         this.volumeId = volumeId;
         this.volumePath = volumePath;
         this.pool = new StorageFilerTO(pool);
+        this.setWait(timeout);
     }
 
-    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, String attachedVmName) {
+    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, String attachedVmName, int timeout) {
         this.volumeId = volumeId;
         this.volumePath = volumePath;
         this.pool = new StorageFilerTO(pool);
         this.attachedVmName = attachedVmName;
+        this.setWait(timeout);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f099732b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
index 415a077..5b01f95 100644
--- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -370,9 +370,12 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
     }
 
     protected Answer migrateVolumeToPool(DataObject srcData, DataObject destData) {
+        String value = configDao.getValue(Config.MigrateWait.key());
+        int waitInterval = NumbersUtil.parseInt(value, Integer.parseInt(Config.MigrateWait.getDefaultValue()));
+
         VolumeInfo volume = (VolumeInfo)srcData;
         StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destData.getDataStore().getId(), DataStoreRole.Primary);
-        MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool, volume.getAttachedVmName());
+        MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool, volume.getAttachedVmName(), waitInterval);
         EndPoint ep = selector.select(srcData, StorageAction.MIGRATEVOLUME);
         Answer answer = null;
         if (ep == null) {


[13/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
DefaultLoginAPIAuthenticatorCmd: move createLoginResponse to ApiServer

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/64ecfdfd
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/64ecfdfd
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/64ecfdfd

Branch: refs/heads/saml2
Commit: 64ecfdfdcc4f89395d7eae35ac95ab42f11080eb
Parents: d169d21
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 03:43:37 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:34 2014 +0200

----------------------------------------------------------------------
 .../auth/DefaultLoginAPIAuthenticatorCmd.java   | 56 +-------------------
 1 file changed, 2 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/64ecfdfd/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
index f5d633e..243ad9b 100644
--- a/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
@@ -25,7 +25,6 @@ import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.LoginCmdResponse;
 import org.apache.log4j.Logger;
@@ -33,7 +32,6 @@ import org.apache.log4j.Logger;
 import javax.inject.Inject;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
-import java.util.Enumeration;
 import java.util.Map;
 
 @APICommand(name = "login", description = "Logs a user into the CloudStack. A successful login attempt will generate a JSESSIONID cookie value that can be passed in subsequent Query command calls until the \"logout\" command has been issued or the session has expired.", requestHasSensitiveInfo = true, responseObject = LoginCmdResponse.class, entityType = {})
@@ -100,54 +98,6 @@ public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthe
         throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "This is an authentication api, cannot be used directly");
     }
 
-    private String createLoginResponse(HttpSession session, String responseType) {
-        LoginCmdResponse response = new LoginCmdResponse();
-        response.setTimeout(session.getMaxInactiveInterval());
-
-        final String user_UUID = (String)session.getAttribute("user_UUID");
-        session.removeAttribute("user_UUID");
-        response.setUserId(user_UUID);
-
-        final String domain_UUID = (String)session.getAttribute("domain_UUID");
-        session.removeAttribute("domain_UUID");
-        response.setDomainId(domain_UUID);
-
-        // FIXME: the while loop mess
-        final Enumeration attrNames = session.getAttributeNames();
-        if (attrNames != null) {
-            while (attrNames.hasMoreElements()) {
-                final String attrName = (String) attrNames.nextElement();
-                final Object attrObj = session.getAttribute(attrName);
-                if (ApiConstants.USERNAME.equalsIgnoreCase(attrName)) {
-                    response.setUsername(attrObj.toString());
-                }
-                if (ApiConstants.ACCOUNT.equalsIgnoreCase(attrName)) {
-                    response.setAccount(attrObj.toString());
-                }
-                if (ApiConstants.FIRSTNAME.equalsIgnoreCase(attrName)) {
-                    response.setFirstName(attrObj.toString());
-                }
-                if (ApiConstants.LASTNAME.equalsIgnoreCase(attrName)) {
-                    response.setLastName(attrObj.toString());
-                }
-                if (ApiConstants.TYPE.equalsIgnoreCase(attrName)) {
-                    response.setType((attrObj.toString()));
-                }
-                if (ApiConstants.TIMEZONE.equalsIgnoreCase(attrName)) {
-                    response.setTimeZone(attrObj.toString());
-                }
-                if (ApiConstants.REGISTERED.equalsIgnoreCase(attrName)) {
-                    response.setRegistered(attrObj.toString());
-                }
-                if (ApiConstants.SESSIONKEY.equalsIgnoreCase(attrName)) {
-                    response.setSessionKey(attrObj.toString());
-                }
-            }
-        }
-        response.setResponseName(getCommandName());
-        return ApiResponseSerializer.toSerializedString((ResponseObject) response, responseType);
-    }
-
     @Override
     public String authenticate(String command, Map<String, Object[]> params, HttpSession session, String remoteAddress, String responseType, StringBuilder auditTrailSb, final HttpServletResponse resp) throws ServerApiException {
 
@@ -197,10 +147,8 @@ public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthe
         if (username != null) {
             final String pwd = ((password == null) ? null : password[0]);
             try {
-                _apiServer.loginUser(session, username[0], pwd, domainId, domain, remoteAddress, params);
-                auditTrailSb.insert(0, "(userId=" + session.getAttribute("userid") + " accountId=" + ((Account) session.getAttribute("accountobj")).getId() +
-                        " sessionId=" + session.getId() + ")");
-                return createLoginResponse(session, responseType);
+                return ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, username[0], pwd, domainId, domain, remoteAddress, params),
+                        responseType);
             } catch (final CloudAuthenticationException ex) {
                 // TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401)
                 try {


[16/22] git commit: updated refs/heads/saml2 to 54986d5

Posted by bh...@apache.org.
ApiServer: change loginUser method signature to return ResponseObject

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d169d211
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d169d211
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d169d211

Branch: refs/heads/saml2
Commit: d169d211bece4246c63b52d2b90f3186be087cb2
Parents: 40abe1d
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Aug 18 03:35:11 2014 +0200
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Aug 18 11:42:34 2014 +0200

----------------------------------------------------------------------
 server/src/com/cloud/api/ApiServer.java        | 53 ++++++++++++++++++++-
 server/src/com/cloud/api/ApiServerService.java | 13 +++--
 server/src/com/cloud/api/ApiServlet.java       |  3 ++
 3 files changed, 60 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d169d211/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 5d6c925..fc55026 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -32,6 +32,7 @@ import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -54,6 +55,7 @@ import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import com.cloud.utils.HttpUtils;
+import org.apache.cloudstack.api.response.LoginCmdResponse;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.http.ConnectionClosedException;
 import org.apache.http.HttpException;
@@ -932,8 +934,55 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             return null;
     }
 
+    private ResponseObject createLoginResponse(HttpSession session) {
+        LoginCmdResponse response = new LoginCmdResponse();
+        response.setTimeout(session.getMaxInactiveInterval());
+
+        final String user_UUID = (String)session.getAttribute("user_UUID");
+        session.removeAttribute("user_UUID");
+        response.setUserId(user_UUID);
+
+        final String domain_UUID = (String)session.getAttribute("domain_UUID");
+        session.removeAttribute("domain_UUID");
+        response.setDomainId(domain_UUID);
+
+        final Enumeration attrNames = session.getAttributeNames();
+        if (attrNames != null) {
+            while (attrNames.hasMoreElements()) {
+                final String attrName = (String) attrNames.nextElement();
+                final Object attrObj = session.getAttribute(attrName);
+                if (ApiConstants.USERNAME.equalsIgnoreCase(attrName)) {
+                    response.setUsername(attrObj.toString());
+                }
+                if (ApiConstants.ACCOUNT.equalsIgnoreCase(attrName)) {
+                    response.setAccount(attrObj.toString());
+                }
+                if (ApiConstants.FIRSTNAME.equalsIgnoreCase(attrName)) {
+                    response.setFirstName(attrObj.toString());
+                }
+                if (ApiConstants.LASTNAME.equalsIgnoreCase(attrName)) {
+                    response.setLastName(attrObj.toString());
+                }
+                if (ApiConstants.TYPE.equalsIgnoreCase(attrName)) {
+                    response.setType((attrObj.toString()));
+                }
+                if (ApiConstants.TIMEZONE.equalsIgnoreCase(attrName)) {
+                    response.setTimeZone(attrObj.toString());
+                }
+                if (ApiConstants.REGISTERED.equalsIgnoreCase(attrName)) {
+                    response.setRegistered(attrObj.toString());
+                }
+                if (ApiConstants.SESSIONKEY.equalsIgnoreCase(attrName)) {
+                    response.setSessionKey(attrObj.toString());
+                }
+            }
+        }
+        response.setResponseName("loginresponse");
+        return response;
+    }
+
     @Override
-    public void loginUser(final HttpSession session, final String username, final String password, Long domainId, final String domainPath, final String loginIpAddress,
+    public ResponseObject loginUser(final HttpSession session, final String username, final String password, Long domainId, final String domainPath, final String loginIpAddress,
             final Map<String, Object[]> requestParameters) throws CloudAuthenticationException {
         // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist
         // we will default to ROOT
@@ -1003,7 +1052,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             final String sessionKey = Base64.encodeBase64String(sessionKeyBytes);
             session.setAttribute("sessionkey", sessionKey);
 
-            return;
+            return createLoginResponse(session);
         }
         throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials");
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d169d211/server/src/com/cloud/api/ApiServerService.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServerService.java b/server/src/com/cloud/api/ApiServerService.java
index 5d078c3..aa3b8f7 100644
--- a/server/src/com/cloud/api/ApiServerService.java
+++ b/server/src/com/cloud/api/ApiServerService.java
@@ -16,21 +16,20 @@
 // under the License.
 package com.cloud.api;
 
-import java.util.Map;
-
-import javax.servlet.http.HttpSession;
-
+import com.cloud.exception.CloudAuthenticationException;
+import org.apache.cloudstack.api.ResponseObject;
 import org.apache.cloudstack.api.ServerApiException;
 
-import com.cloud.exception.CloudAuthenticationException;
+import javax.servlet.http.HttpSession;
+import java.util.Map;
 
 public interface ApiServerService {
     public boolean verifyRequest(Map<String, Object[]> requestParameters, Long userId) throws ServerApiException;
 
     public Long fetchDomainId(String domainUUID);
 
-    public void loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, String loginIpAddress,
-        Map<String, Object[]> requestParameters) throws CloudAuthenticationException;
+    public ResponseObject loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, String loginIpAddress,
+                                    Map<String, Object[]> requestParameters) throws CloudAuthenticationException;
 
     public void logoutUser(long userId);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d169d211/server/src/com/cloud/api/ApiServlet.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java
index 8dff6eb..5484b1e 100644
--- a/server/src/com/cloud/api/ApiServlet.java
+++ b/server/src/com/cloud/api/ApiServlet.java
@@ -201,6 +201,9 @@ public class ApiServlet extends HttpServlet {
                             } catch (final IllegalStateException ignored) {
                             }
                         }
+                    } else {
+                        auditTrailSb.insert(0, "(userId=" + session.getAttribute("userid") + " accountId=" + ((Account) session.getAttribute("accountobj")).getId() +
+                                " sessionId=" + session.getId() + ")");
                     }
                     HttpUtils.writeHttpResponse(resp, responseString, httpResponseCode, responseType);
                     return;