cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jessicaw...@apache.org
Subject git commit: updated refs/heads/master to 57f611d
Date Fri, 08 Aug 2014 17:57:28 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/master ffe0f2f60 -> 57f611df1


CLOUDSTACK-6695: Added support to the UI for uploading a chain of certificates

In the "SSL Certificate" dialog we added:
- new field for the root certificate;
- a button to add intermediate certificates if necessary; when this is pressed, a new field,
called "Intermediate certificate 1" is added; pressed again, "Intermediate certificate 2"
field is added, and so on.

We upload the certificates in order: first the root certificate (with id=1), then the intermediate
certificates (with id=2,3,..) and finally the server certificate.
When uploading a certificate, we wait for the upload to be completed successfully and only
then we proceed to uploading the next one. If one fails, we report failure and don't continue
with the remaining.

Signed-off-by: Mihaela Stoica <mihaela.stoica@citrix.com>


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

Branch: refs/heads/master
Commit: 57f611df16c48419e582f41c1e630faa739c11c5
Parents: ffe0f2f
Author: Mihaela Stoica <mihaela.stoica@citrix.com>
Authored: Tue Aug 5 21:59:15 2014 +0100
Committer: Jessica Wang <jessicawang@apache.org>
Committed: Fri Aug 8 10:57:12 2014 -0700

----------------------------------------------------------------------
 .../classes/resources/messages.properties       |   7 +-
 ui/css/cloudstack3.css                          |  20 +-
 ui/dictionary.jsp                               |   5 +-
 ui/scripts/ui-custom/physicalResources.js       | 187 ++++++++++++++-----
 4 files changed, 168 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57f611df/client/WEB-INF/classes/resources/messages.properties
----------------------------------------------------------------------
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index a0205e1..475fe6c 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -313,6 +313,7 @@ label.add.firewall=Add firewall rule
 label.add.guest.network=Add guest network
 label.add.host=Add Host
 label.add.ingress.rule=Add Ingress Rule
+label.add.intermediate.certificate=Add intermediate certificate
 label.add.ip.range=Add IP Range
 label.add.load.balancer=Add Load Balancer
 label.add.more=Add More
@@ -431,7 +432,7 @@ label.cancel=Cancel
 label.capacity=Capacity
 label.capacity.bytes=Capacity Bytes
 label.capacity.iops=Capacity IOPS
-label.certificate=Certificate
+label.certificate=Server certificate
 label.change.service.offering=Change service offering
 label.change.value=Change value
 label.character=Character
@@ -678,6 +679,7 @@ label.instance.limits=Instance Limits
 label.instance.name=Instance Name
 label.instance=Instance
 label.instances=Instances
+label.intermediate.certificate=Intermediate certificate {0}
 label.internal.dns.1=Internal DNS 1
 label.internal.dns.2=Internal DNS 2
 label.internal.name=Internal name
@@ -1020,6 +1022,7 @@ label.retry.interval=Retry Interval
 label.review=Review
 label.revoke.project.invite=Revoke invitation
 label.role=Role
+label.root.certificate=Root certificate
 label.root.disk.controller=Root disk controller
 label.root.disk.offering=Root Disk Offering
 label.round.robin=Round-robin
@@ -1820,7 +1823,7 @@ message.tooltip.reserved.system.netmask=The network prefix that defines
the pod
 message.tooltip.zone.name=A name for the zone.
 message.update.os.preference=Please choose a OS preference for this host.  All virtual instances
with similar preferences will be first allocated to this host before choosing another.
 message.update.resource.count=Please confirm that you want to update resource counts for
this account.
-message.update.ssl=Please submit a new X.509 compliant SSL certificate to be updated to each
console proxy and secondary storage virtual instance\:
+message.update.ssl=Please submit a new X.509 compliant SSL certificate chain to be updated
to each console proxy and secondary storage virtual instance\:
 message.validate.instance.name=Instance name can not be longer than 63 characters. Only ASCII
letters a~z, A~Z, digits 0~9, hyphen are allowed. Must start with a letter and end with a
letter or a digit.
 message.virtual.network.desc=A dedicated virtualized network for your account.  The broadcast
domain is contained within a VLAN and all public network access is routed out by a virtual
router.
 message.vm.create.template.confirm=Create Template will reboot the VM automatically.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57f611df/ui/css/cloudstack3.css
----------------------------------------------------------------------
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index 23681a7..6e649f7 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -4053,7 +4053,7 @@ Dialogs*/
   display: inline-block;
 }
 
-.ui-dialog div.form-container div.value input {
+.ui-dialog div.form-container div.value input, textarea {
   width: 98%;
   font-size: 14px;
   padding: 4px;
@@ -12984,3 +12984,21 @@ div.gpugroups div.list-view {
   padding: 12px 12px 5px;
 }
 
+.ui-dialog .ui-button.add {
+    background: linear-gradient(to bottom, #f7f7f7 1%, #eaeaea 100%) repeat scroll 0px 0px
transparent;
+    font-size: 12px;
+    height: 12px;
+    width: auto;
+    margin: 0px 0px 12px;
+    padding: 5px 7px 5px 6px;
+}
+
+.ui-dialog .ui-button.add:hover {
+    background: none repeat scroll 0px 0px #e5e5e5;
+    box-shadow: 0px 0px 5px #c3c3c3 inset;
+}
+
+.ui-dialog .ui-button.add span {
+    background: url("../images/icons.png") no-repeat scroll -626px -209px transparent;
+    padding: 0 0 3px 18px;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57f611df/ui/dictionary.jsp
----------------------------------------------------------------------
diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp
index 10aeaf9..3b85b1f 100644
--- a/ui/dictionary.jsp
+++ b/ui/dictionary.jsp
@@ -1898,7 +1898,10 @@ dictionary = {
 'message.confirm.enable.vpc.offering': '<fmt:message key="message.confirm.enable.vpc.offering"
/>',
 'message.enabling.vpc.offering': '<fmt:message key="message.enabling.vpc.offering" />',
 'message.confirm.remove.vpc.offering': '<fmt:message key="message.confirm.remove.vpc.offering"
/>',
-'message.confirm.disable.vpc.offering': '<fmt:message key="message.confirm.disable.vpc.offering"
/>'
+'message.confirm.disable.vpc.offering': '<fmt:message key="message.confirm.disable.vpc.offering"
/>',
+'label.root.certificate': '<fmt:message key="label.root.certificate" />',
+'label.intermediate.certificate': '<fmt:message key="label.intermediate.certificate" />',
+'label.add.intermediate.certificate': '<fmt:message key="label.add.intermediate.certificate"
/>'
 
 };
 </script>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57f611df/ui/scripts/ui-custom/physicalResources.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui-custom/physicalResources.js b/ui/scripts/ui-custom/physicalResources.js
index ac379b4..110945e 100644
--- a/ui/scripts/ui-custom/physicalResources.js
+++ b/ui/scripts/ui-custom/physicalResources.js
@@ -96,72 +96,165 @@
                     form: {
                         title: 'label.update.ssl',
                         desc: 'message.update.ssl',
+                        preFilter: function (args) {
+                            var $form = args.$form;
+
+                            // insert the "Add intermediate certificate" button
+                            var $addButton = $('<div>')
+                                .addClass('add ui-button')
+                                .append(
+                                    $('<span>').html(_l('label.add.intermediate.certificate'))
+                                );
+                            var $servercertificate = $form.find('.form-item[rel=certificate]');
+                            $addButton.insertBefore($servercertificate);
+                            var count = 0;
+                            var $intermediatecertificate = $form.find('.form-item[rel=intermediatecertificate]');
+
+                            $addButton.click(function() {
+                                // clone the template intermediate certificate and make it
visible
+                                var $newcertificate = $intermediatecertificate.clone().attr('id','intermediate'+count);
+                                $newcertificate.insertBefore($addButton);
+                                $newcertificate.css('display', 'inline-block');
+                                $newcertificate.addClass('sslcertificate');
+                                count++;
+                                // change label
+                                var $label = $newcertificate.find('label');
+                                $label.html($label.html().replace('{0}', count)); // 'Intermediate
certificate ' + count + ':'
+                            });
+                        },
                         fields: {
+                            rootcertificate: {
+                                label: 'label.root.certificate',
+                                isTextarea: true,
+                                validation: { required: true }
+                            },
+                            intermediatecertificate: { // this is the template 'intermediate
certificate', always hidden
+                                label: 'label.intermediate.certificate',
+                                isTextarea: true,
+                                isHidden: true
+                            },
                             certificate: {
                                 label: 'label.certificate',
-                                isTextarea: true
+                                isTextarea: true,
+                                validation: { required: true }
                             },
                             privatekey: {
                                 label: 'label.privatekey',
-                                isTextarea: true
+                                isTextarea: true,
+                                validation: { required: true }
                             },
                             domainsuffix: {
-                                label: 'label.domain.suffix'
+                                label: 'label.domain.suffix',
+                                validation: { required: true }
                             }
                         }
                     },
                     after: function(args) {
                         var $loading = $('<div>').addClass('loading-overlay');
                         $('.system-dashboard-view:visible').prepend($loading);
-                        $.ajax({
-                            type: "POST",
-                            url: createURL('uploadCustomCertificate'),
-                            data: {
-                                certificate: args.data.certificate,
-                                privatekey: args.data.privatekey,
+
+                        // build a list with all certificates that need to be uploaded
+                        var certificates = [];
+                        certificates.push(args.data.rootcertificate);
+                        if ($.isArray(args.data.intermediatecertificate))
+                        {
+                            $.merge(certificates, args.data.intermediatecertificate);
+                        }
+                        else
+                        {
+                            certificates.push(args.data.intermediatecertificate);
+                        }
+                        certificates.push(args.data.certificate);
+
+                        // Recursively uploads certificates.
+                        // When the upload succeeds, proceeds to uploading the next certificate.
+                        // When the upload fails, stops and reports failure.
+                        var uploadCertificate = function(index) {
+                            if (index >=  certificates.length)
+                            {
+                                return;
+                            }
+                            if ( !$.trim(certificates[index])) // skip empty certificate
+                            {
+                                uploadCertificate(index + 1);
+                                return;
+                            }
+
+                            // build certificate data
+                            var certificateData = {
+                                id: index + 1, // id start from 1
+                                certificate: certificates[index],
                                 domainsuffix: args.data.domainsuffix
-                            },
-                            dataType: 'json',
-                            success: function(json) {
-                                var jid = json.uploadcustomcertificateresponse.jobid;
-                                var uploadCustomCertificateIntervalID = setInterval(function()
{
-                                    $.ajax({
-                                        url: createURL("queryAsyncJobResult&jobId=" +
jid),
-                                        dataType: "json",
-                                        success: function(json) {
-                                            var result = json.queryasyncjobresultresponse;
-                                            if (result.jobstatus == 0) {
-                                                return; //Job has not completed
-                                            } else {
-                                                clearInterval(uploadCustomCertificateIntervalID);
-                                                if (result.jobstatus == 1) {
-                                                    cloudStack.dialog.notice({
-                                                        message: 'Update SSL Certificate
succeeded'
-                                                    });
-                                                } else if (result.jobstatus == 2) {
-                                                    cloudStack.dialog.notice({
-                                                        message: 'Failed to update SSL Certificate.
' + _s(result.jobresult.errortext)
-                                                    });
+                            };
+                            switch (index) {
+                                case (0): //first certificate is the root certificate
+                                    certificateData['name'] = 'root';
+                                    break;
+                                case (certificates.length - 1): // last certificate is the
server certificate
+                                    certificateData['privatekey'] = args.data.privatekey;
+                                    break;
+                                default: // intermediate certificates
+                                    certificateData['name'] = 'intermediate' + index;
+                            }
+
+                            $.ajax({
+                                type: "POST",
+                                url: createURL('uploadCustomCertificate'),
+                                data:  certificateData,
+                                dataType: 'json',
+                                success: function(json) {
+                                    var jid = json.uploadcustomcertificateresponse.jobid;
+                                    var uploadCustomCertificateIntervalID = setInterval(function()
{
+                                        $.ajax({
+                                            url: createURL("queryAsyncJobResult&jobId="
+ jid),
+                                            dataType: "json",
+                                            success: function(json) {
+                                                var result = json.queryasyncjobresultresponse;
+                                                if (result.jobstatus == 0) {
+                                                    return; //Job has not completed
+                                                } else {
+                                                    clearInterval(uploadCustomCertificateIntervalID);
+                                                    if (result.jobstatus == 1) {
+                                                        if (index ==  certificates.length
- 1) // last one, report success
+                                                        {
+                                                            cloudStack.dialog.notice({
+                                                                message: 'Update SSL Certificates
succeeded'
+                                                            });
+                                                            $loading.remove();
+                                                        }
+                                                        else // upload next certificate
+                                                        {
+                                                            uploadCertificate(index + 1);
+                                                        }
+                                                    } else if (result.jobstatus == 2) {
+                                                        cloudStack.dialog.notice({
+                                                            message: 'Failed to update SSL
Certificate. ' + _s(result.jobresult.errortext)
+                                                        });
+                                                        $loading.remove();
+                                                    }
                                                 }
+                                            },
+                                            error: function(XMLHttpResponse) {
+                                                cloudStack.dialog.notice({
+                                                    message: 'Failed to update SSL Certificate.
' + parseXMLHttpResponse(XMLHttpResponse)
+                                                });
                                                 $loading.remove();
                                             }
-                                        },
-                                        error: function(XMLHttpResponse) {
-                                            cloudStack.dialog.notice({
-                                                message: 'Failed to update SSL Certificate.
' + parseXMLHttpResponse(XMLHttpResponse)
-                                            });
-                                            $loading.remove();
-                                        }
+                                        });
+                                    }, g_queryAsyncJobResultInterval);
+                                },
+                                error: function(XMLHttpResponse) {
+                                    cloudStack.dialog.notice({
+                                        message: 'Failed to update SSL Certificate. ' + parseXMLHttpResponse(XMLHttpResponse)
                                     });
-                                }, g_queryAsyncJobResultInterval);
-                            },
-                            error: function(XMLHttpResponse) {
-                                cloudStack.dialog.notice({
-                                    message: 'Failed to update SSL Certificate. ' + parseXMLHttpResponse(XMLHttpResponse)
-                                });
-                                $loading.remove();
-                            }
-                        });
+                                    $loading.remove();
+                                }
+                            });
+                            return;
+                        };
+
+                        // start uploading the certificates
+                        uploadCertificate(0);
                     },
                     context: {}
                 });


Mime
View raw message