Merge "Restrict Postgres to version 10"
authorTrevor Bramwell <tbramwell@linuxfoundation.org>
Thu, 1 Nov 2018 23:18:47 +0000 (23:18 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Thu, 1 Nov 2018 23:18:47 +0000 (23:18 +0000)
dashboard/src/api/models.py
dashboard/src/booking/views.py
dashboard/src/dashboard/tasks.py
dashboard/src/templates/booking/booking_detail.html
dashboard/src/templates/booking/booking_table.html
dashboard/src/templates/booking/steps/booking_meta.html
dashboard/src/templates/dashboard/multiple_select_filter_widget.html
dashboard/src/workflow/forms.py

index 7448ac4..9afc89a 100644 (file)
@@ -321,10 +321,10 @@ class AccessConfig(TaskConfig):
 
     def to_dict(self):
         d = {}
-        d['access_type'] =  self.access_type
+        d['access_type'] = self.access_type
         d['user'] = self.user.id
         d['revoke'] = self.revoke
-        d['context'] = self.context
+        d['context'] = json.loads(self.context)
         return d
 
     def get_delta(self):
@@ -363,7 +363,7 @@ class AccessConfig(TaskConfig):
         self.delta = json.dumps(d)
 
     def set_context(self, context):
-        self.context = context
+        self.context = json.dumps(context)
         d = json.loads(self.delta)
         d['context'] = context
         self.delta = json.dumps(d)
@@ -608,18 +608,28 @@ class JobFactory(object):
                 hosts=hosts,
                 job=job
                 )
+        all_users = list(booking.collaborators.all())
+        all_users.append(booking.owner)
         cls.makeAccessConfig(
-                users=booking.collaborators.all(),
-                access_type="vpn",
-                revoke=False,
-                job=job
-                )
-        cls.makeAccessConfig(
-                users=[booking.owner],
+                users=all_users,
                 access_type="vpn",
                 revoke=False,
                 job=job
                 )
+        for user in all_users:
+            try:
+                cls.makeAccessConfig(
+                        users=[user],
+                        access_type="ssh",
+                        revoke=False,
+                        job=job,
+                        context={
+                            "key": user.userprofile.ssh_public_key.read(),
+                            "hosts": [host.labid for host in hosts]
+                            }
+                        )
+            except Exception:
+                continue
 
     @classmethod
     def makeHardwareConfigs(cls, hosts=[], job=Job()):
@@ -646,13 +656,15 @@ class JobFactory(object):
             hardware_config.save()
 
     @classmethod
-    def makeAccessConfig(cls, users, access_type, revoke=False, job=Job()):
+    def makeAccessConfig(cls, users, access_type, revoke=False, job=Job(), context=False):
         for user in users:
             relation = AccessRelation()
             relation.job = job
             config = AccessConfig()
             config.access_type = access_type
             config.user = user
+            if context:
+                config.set_context(context)
             config.save()
             relation.config = config
             relation.save()
@@ -709,6 +721,3 @@ class JobFactory(object):
             return software_relation
         except:
             return None
-
-    def makeAccess(cls, user, access_type, revoke):
-        pass
index 9b9860f..a0ea31d 100644 (file)
@@ -103,6 +103,10 @@ def booking_detail_view(request, booking_id):
         return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
 
     booking = get_object_or_404(Booking, id=booking_id)
+    allowed_users = set(list(booking.collaborators.all()))
+    allowed_users.add(booking.owner)
+    if user not in allowed_users:
+        return render(request, "dashboard/login.html", {'title': 'This page is private'})
     return render(request, "booking/booking_detail.html", {
         'title': 'Booking Details',
         'booking': booking,
index 48008b6..0f7af1c 100644 (file)
@@ -73,7 +73,11 @@ def booking_poll():
 
     def cleanup_access(qs):
         for relation in qs:
-            pass # TODO
+            if "vpn" in relation.config.access_type.lower():
+                relation.config.set_revoke(True)
+                relation.config.save()
+                relation.status = JobStatus.NEW
+                relation.save()
 
     cleanup_set = Booking.objects.filter(end__lte=timezone.now()).filter(job__complete=False)
 
index 126aaab..cae0e25 100644 (file)
 
 {% block extrahead %}
     {{block.super}}
-    <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?lang=yaml"></script>
+<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?lang=yaml"></script>
 <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
 {% endblock %}
 
 {% block content %}
 <div class="container-fluid">
     <div class="row">
-    <div class="col-lg-6">
-        <div class="panel panel-default">
-            <div class="panel-heading clearfix">
-                <h4 style="display: inline;">Overview</h4>
-               <a data-toggle="collapse" data-target="#panel_overview" class="btn pull-right" style="line-height: 1;" >Expand</a>
-            </div>
-            <div class="panel-body" id="panel_overview">
-                <table class="table">
-                    <tr>
-                        <td>Purpose</td>
-                        <td>{{ booking.purpose }}</td>
-                    </tr>
-                    <tr>
-                        <td>Project</td>
-                        <td>{{ booking.project }}</td>
-                    </tr>
-                    <tr>
-                        <td>Start Time</td>
-                        <td>{{ booking.start }}</td>
-                    </tr>
-                    <tr>
-                        <td>End Time</td>
-                        <td>{{ booking.end }}</td>
-                    </tr>
-                    <tr>
-                        <td>Pod Definition</td>
-                        <td>{{ booking.resource.template }}</td>
-                    </tr>
-                    <tr>
-                        <td>Pod Configuration</td>
-                        <td>{{ booking.config_bundle }}</td>
-                    </tr>
-                    <tr>
-                        <td>Lab Deployed At</td>
-                        <td>{{ booking.lab }}</td>
-                    </tr>
-                </table>
-            </div>
-        </div>
-    <div class="row">
-
         <div class="col-lg-6">
-
             <div class="panel panel-default">
-            <div class="panel-heading clearfix">
-                <h4 style="display: inline;">Pod</h4>
-
-               <a data-toggle="collapse" data-target="#pod_panel" class="btn pull-right" style="line-height: 1;" >Expand</a>
+                <div class="panel-heading clearfix">
+                    <h4 style="display: inline;">Overview</h4>
+                    <a data-toggle="collapse" data-target="#panel_overview" class="btn pull-right" style="line-height: 1;" >Expand</a>
+                </div>
+                <div class="panel-body" id="panel_overview">
+                    <table class="table">
+                        <tr>
+                            <td>Purpose</td>
+                            <td>{{ booking.purpose }}</td>
+                        </tr>
+                        <tr>
+                            <td>Project</td>
+                            <td>{{ booking.project }}</td>
+                        </tr>
+                        <tr>
+                            <td>Start Time</td>
+                            <td>{{ booking.start }}</td>
+                        </tr>
+                        <tr>
+                            <td>End Time</td>
+                            <td>{{ booking.end }}</td>
+                        </tr>
+                        <tr>
+                            <td>Pod Definition</td>
+                            <td>{{ booking.resource.template }}</td>
+                        </tr>
+                        <tr>
+                            <td>Pod Configuration</td>
+                            <td>{{ booking.config_bundle }}</td>
+                        </tr>
+                        <tr>
+                            <td>Lab Deployed At</td>
+                            <td>{{ booking.lab }}</td>
+                        </tr>
+                    </table>
+                </div>
             </div>
-            <div class="panel-body pod_panel" id="pod_panel">
-                <table class="table">
-                {% for host in booking.resource.hosts.all %}
-                <tr>
-                    <td><h4>{{host.template.resource.name}}</h4></td>
-                    <td>
-                        <table class="table">
-                            <tr>
-                                <td>Hostname:</td>
-                                <td>{{host.template.resource.name}}</td>
-                            </tr>
-                            <tr>
-                                <td>Profile:</td>
-                                <td>{{host.name}}</td>
-                            </tr>
-                            <tr>
-                                <td>Role:</td>
-                                <td>{{host.config.opnfvRole}}</td>
-                            </tr>
-                            <tr>
-                                <td>Image:</td>
-                                <td>{{host.config.image}}</td>
-                            </tr>
-                            <tr>
-                                <td>RAM:</td>
-                                <td>{{host.profile.ramprofile.first.amount}}G,
-                                    {{host.profile.ramprofile.first.channels}} channels</td>
-                            </tr>
+            <div class="row">
+
+                <div class="col-lg-6">
+
+                    <div class="panel panel-default">
+                        <div class="panel-heading clearfix">
+                            <h4 style="display: inline;">Pod</h4>
+                            <a data-toggle="collapse" data-target="#pod_panel" class="btn pull-right" style="line-height: 1;" >Expand</a>
+                        </div>
+                        <div class="panel-body pod_panel" id="pod_panel">
+                            <table class="table">
+                            {% for host in booking.resource.hosts.all %}
                             <tr>
-                                <td>CPU:</td>
+                                <td><h4>{{host.template.resource.name}}</h4></td>
                                 <td>
                                     <table class="table">
                                         <tr>
-                                            <td>Arch:</td>
-                                            <td>{{host.profile.cpuprofile.first.architecture}}</td>
+                                            <td>Hostname:</td>
+                                            <td>{{host.template.resource.name}}</td>
                                         </tr>
                                         <tr>
-                                            <td>Cores:</td>
-                                            <td>{{host.profile.cpuprofile.first.cores}}</td>
+                                            <td>Profile:</td>
+                                            <td>{{host.name}}</td>
                                         </tr>
                                         <tr>
-                                            <td>Sockets:</td>
-                                            <td>{{host.profile.cpuprofile.first.cpus}}</td>
+                                            <td>Role:</td>
+                                            <td>{{host.config.opnfvRole}}</td>
                                         </tr>
-                                    </table>
-                                </td>
-                            </tr>
-                            <tr>
-                                <td>DISK:</td>
-                                <td>
-                                    <table class="table">
                                         <tr>
-                                            <td>Size:</td>
-                                            <td>{{host.profile.diskprofile.first.size}}GiB</td>
+                                            <td>Image:</td>
+                                            <td>{{host.config.image}}</td>
                                         </tr>
                                         <tr>
-                                            <td>Type:</td>
-                                            <td>{{host.profile.diskprofile.first.media_type}}</td>
+                                            <td>RAM:</td>
+                                            <td>{{host.profile.ramprofile.first.amount}}G,
+                                                {{host.profile.ramprofile.first.channels}} channels</td>
                                         </tr>
                                         <tr>
-                                            <td>Mount Point:</td>
-                                            <td>{{host.profile.diskprofile.first.name}}</td>
+                                            <td>CPU:</td>
+                                            <td>
+                                                <table class="table">
+                                                    <tr>
+                                                        <td>Arch:</td>
+                                                        <td>{{host.profile.cpuprofile.first.architecture}}</td>
+                                                    </tr>
+                                                    <tr>
+                                                        <td>Cores:</td>
+                                                        <td>{{host.profile.cpuprofile.first.cores}}</td>
+                                                    </tr>
+                                                    <tr>
+                                                        <td>Sockets:</td>
+                                                        <td>{{host.profile.cpuprofile.first.cpus}}</td>
+                                                    </tr>
+                                                </table>
+                                            </td>
                                         </tr>
+                                        <tr>
+                                            <td>DISK:</td>
+                                            <td>
+                                                <table class="table">
+                                                    <tr>
+                                                        <td>Size:</td>
+                                                        <td>{{host.profile.diskprofile.first.size}}GiB</td>
+                                                    </tr>
+                                                    <tr>
+                                                        <td>Type:</td>
+                                                        <td>{{host.profile.diskprofile.first.media_type}}</td>
+                                                    </tr>
+                                                    <tr>
+                                                        <td>Mount Point:</td>
+                                                        <td>{{host.profile.diskprofile.first.name}}</td>
+                                                    </tr>
+                                                </table>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>Interfaces:</td>
+                                            <td>
+                                                <style>
+                                                    .borderless td {
+                                                        border: none !important;
+                                                    }
+                                                </style>
+                                                <table class="table">
+                                                {% for intprof in host.profile.interfaceprofile.all %}
+                                                <tr>
+                                                    <td>
+                                                    <table class="table borderless">
+                                                        <tr>
+                                                            <td>Name:</td>
+                                                            <td>{{intprof.name}}</td>
+                                                        </tr>
+                                                        <tr>
+                                                            <td>Speed:</td>
+                                                            <td>{{intprof.speed}}</td>
+                                                        </tr>
+                                                    </table>
+                                                    </td>
+                                                </tr>
+                                                {% endfor %}
+                                                </table>
+                                            </td>
+                                        </tr>
+
+
                                     </table>
+
                                 </td>
+                            {% endfor %}
                             </tr>
-                            <tr>
-                                <td>Interfaces:</td>
-                                <td>
-                                    <style>
-                                        .borderless td {
-                                            border: none !important;
-                                        }
-                                    </style>
-                                    <table class="table">
-                                    {% for intprof in host.profile.interfaceprofile.all %}
-                                    <tr>
-                                        <td>
-                                        <table class="table borderless">
-                                            <tr>
-                                                <td>Name:</td>
-                                                <td>{{intprof.name}}</td>
-                                            </tr>
-                                            <tr>
-                                                <td>Speed:</td>
-                                                <td>{{intprof.speed}}</td>
-                                            </tr>
-                                        </table>
-                                        </td>
-                                    </tr>
-                                    {% endfor %}
-                                    </table>
-                                </td>
-                            </tr>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-lg-6">
 
+                    <div class="panel panel-default">
+                        <div class="panel-heading clearfix">
+                            <h4 style="display: inline;">PDF</h4>
+                            <a data-toggle="collapse" data-target="#pdf_panel" class="btn pull-right" style="line-height: 1;" >Expand</a>
+                        </div>
 
-                        </table>
-
-                    </td>
-                {% endfor %}
-                </tr>
-                </table>
+                        <div class="panel-body" id="pdf_panel" style="padding: 0px;">
+                            <pre class="prettyprint lang-yaml" style="margin: 0px; padding: 0px; border: none;">
+{{pdf}}
+                            </pre>
+                        </div>
+                    </div>
+                </div>
             </div>
         </div>
-      </div>
         <div class="col-lg-6">
+            <div class="panel panel-default">
+                <div class="panel-heading clearfix">
+                    <h4 style="display: inline;">Deployment Progress</h4>
+                    <p style="display: inline; margin-left: 10px;">  These are the different tasks that have to be completed before your deployment is ready</p>
+                   <a data-toggle="collapse" data-target="#panel_tasks" class="btn pull-right" style="line-height: 1;" >Expand</a>
+                </div>
 
-        <div class="panel panel-default">
-            <div class="panel-heading clearfix">
-                <h4 style="display: inline;">PDF</h4>
-            <a data-toggle="collapse" data-target="#pdf_panel" class="btn pull-right" style="line-height: 1;" >Expand</a>
-            </div>
-
-            <div class="panel-body" id="pdf_panel" style="padding: 0px;">
-                <pre class="prettyprint lang-yaml" style="margin: 0px; padding: 0px; border: none;">
-
-                    {{pdf}}
-
-
-                </pre>
-            </div>
-        </div>
-        </div>
-        </div>
-    </div>
-
-
+                <div class="panel-body" id="panel_tasks">
+                    <table class="table">
+                        <style>
+                            .progress {
+                                display: inline-block;
+                                border: 3px solid #f3f3f3;
+                                border-radius: 50%;
+                                border-top: 3px solid #12aebb;
+                                width: 20px;
+                                height: 20px;
+                                -webkit-animation: spin 2s linear infinite; /* Safari */
+                                animation: spin 2s linear infinite;
+                              }
 
-    <div class="col-lg-6">
-        <div class="panel panel-default">
-            <div class="panel-heading clearfix">
-                <h4 style="display: inline;">Deployment Progress</h4>
-                <p style="display: inline; margin-left: 10px;">  These are the different tasks that have to be completed before your deployment is ready</p>
-               <a data-toggle="collapse" data-target="#panel_tasks" class="btn pull-right" style="line-height: 1;" >Expand</a>
-            </div>
+                              @keyframes spin {
+                                  0% {transform: rotate(0deg);}
+                                  100% {transform: rotate(360deg);}
+                              }
 
-            <div class="panel-body" id="panel_tasks">
-                <table class="table">
-                    <style>
-                        .progress {
-                            display: inline-block;
-                            border: 3px solid #f3f3f3;
-                            border-radius: 50%;
-                            border-top: 3px solid #12aebb;
-                            width: 20px;
-                            height: 20px;
-                            -webkit-animation: spin 2s linear infinite; /* Safari */
-                            animation: spin 2s linear infinite;
-                          }
+                              .new {
+                                  display: inline-block;
+                                  width: 20px;
+                                  height: 20px;
+                                  background: #f3f3f3;
+                                  border-radius: 50%;
+                                  animation: fadeInOut 1s infinite alternate;
 
-                          @keyframes spin {
-                              0% {transform: rotate(0deg);}
-                              100% {transform: rotate(360deg);}
-                          }
 
-                          .new {
-                              display: inline-block;
-                              width: 20px;
-                              height: 20px;
-                              background: #f3f3f3;
-                              border-radius: 50%;
-                              animation: fadeInOut 1s infinite alternate;
+                              }
+                              @keyframes fadeInOut {
+                                  from { opacity: 0;}
+                              }
+                              .done {
+                                  display: inline-block;
+                                  width: 20px;
+                                  height: 20px;
+                                  background: #40B976;
+                                  border-radius: 50%;
+                              }
+                            </style>
+                        <tr>
+                            <th></th>
+                            <th>Status</th>
+                            <th>Lab Response</th>
+                            <th>Type</th>
+                        </tr>
+                        {% for task in booking.job.get_tasklist %}
+                        <tr>
+                            <td>
+                                {% if task.status < 100 %}
+                                    <div class="new"></div>
+                                {% elif task.status < 200 %}
+                                    <div class="progress"></div>
+                                {% else %}
+                                    <div class="done"></div>
+                                {% endif %}
+                                </td>
 
 
-                          }
-                          @keyframes fadeInOut {
-                              from { opacity: 0;}
-                          }
-                          .done {
-                              display: inline-block;
-                              width: 20px;
-                              height: 20px;
-                              background: #40B976;
-                              border-radius: 50%;
-                          }
-                        </style>
-                    <tr>
-                        <th></th>
-                        <th>Status</th>
-                        <th>Lab Response</th>
-                        <th>Type</th>
-                    </tr>
-                    {% for task in booking.job.get_tasklist %}
-                    <tr>
-                        <td>
-                            {% if task.status < 100 %}
-                                <div class="new"></div>
-                            {% elif task.status < 200 %}
-                                <div class="progress"></div>
-                            {% else %}
-                                <div class="done"></div>
-                            {% endif %}
+                            <td>
+                                {% if task.status < 100 %}
+                                    PENDING
+                                {% elif task.status < 200 %}
+                                    IN PROGRESS
+                                {% else %}
+                                    DONE
+                                {% endif %}
                             </td>
+                            <td>
 
+                                {% if task.message %}
+                                {% if task.type_str == "Access Task" and user_id != task.config.user.id %}
+                                Message from Lab: <pre>--secret--</pre>
+                                {% else %}
+                                Message from Lab: <pre>{{ task.message }}</pre>
+                                {% endif %}
+                                {% else %}
+                                No response provided (yet)
+                                {% endif %}
+                            </td>
+                            <td>
+                                {{ task.type_str }}
 
-                        <td>
-                            {% if task.status < 100 %}
-                                PENDING
-                            {% elif task.status < 200 %}
-                                IN PROGRESS
-                            {% else %}
-                                DONE
-                            {% endif %}
-                        </td>
-                        <td>
-
-                            {% if task.message %}
-                            {% if task.type_str == "Access Task" and user_id != task.config.user.id %}
-                            Message from Lab: <pre>--secret--</pre>
-                            {% else %}
-                            Message from Lab: <pre>{{ task.message }}</pre>
-                            {% endif %}
-                            {% else %}
-                            No response provided (yet)
-                            {% endif %}
-                        </td>
-                        <td>
-                            {{ task.type_str }}
-
-                        </td>
-                    </tr>
-                    {% endfor %}
-                </table>
+                            </td>
+                        </tr>
+                        {% endfor %}
+                    </table>
+                </div>
             </div>
         </div>
-
-    </div>
     </div>
 </div>
 
index af2248c..5e82645 100644 (file)
@@ -3,7 +3,7 @@
 
 <thead>
 <tr>
-    <th>User</th>
+    <th>Owner</th>
     <th>Purpose</th>
     <th>Start</th>
     <th>End</th>
@@ -16,7 +16,7 @@
 {% for booking in bookings %}
     <tr>
         <td>
-            {{ booking.user.username }}
+            {{ booking.owner.username }}
         </td>
         <td>
             {{ booking.purpose }}
index fa8f7a9..a42e158 100644 (file)
@@ -43,7 +43,8 @@
     <div class="panel panel_center">
     </div>
     <div class="panel">
-        {% bootstrap_field form.users %}
+        <p>You may add collaborators on your booking to share resources with coworkers.</p>
+        {% bootstrap_field form.users label="Collaborators" %}
     </div>
 
     {% buttons %}
index ed29ed6..31b8f33 100644 (file)
@@ -337,6 +337,7 @@ function add_item_prepopulate(node, prepopulate){
     button.appendChild(document.createTextNode("Remove"));
     div.appendChild(button);
     document.getElementById("dropdown_wrapper").appendChild(div);
+    updateObjectResult(div);
     return div;
 }
 
index c770e38..d4abbc3 100644 (file)
@@ -189,6 +189,7 @@ class BookingMetaForm(forms.Form):
             default_user = kwargs.pop("default_user")
         else:
             default_user = "you"
+        self.default_user = default_user
         if "chosen_users" in kwargs:
             chosen_users = kwargs.pop("chosen_users")
         elif data and "users" in data:
@@ -212,7 +213,7 @@ class BookingMetaForm(forms.Form):
         """
         try:
             users = {}
-            d_qset = UserProfile.objects.select_related('user').all();
+            d_qset = UserProfile.objects.select_related('user').all().exclude(user__username=self.default_user);
             for userprofile in d_qset:
                 user = {
                     'id':userprofile.user.id,
@@ -237,7 +238,6 @@ class BookingMetaForm(forms.Form):
             'selectable_limit': -1,
             'name': "users",
             'placeholder': "username",
-            'default_entry': default_user,
             'initial': chosen_users,
             'edit': False
         }