apply deployment filtering logic to InstanceAdmin
diff --git a/xos/core/admin.py b/xos/core/admin.py
index 8f8f007..9f6b9d3 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -1307,6 +1307,42 @@
             # dead code was eliminated here
             yield inline.get_formset(request, obj)
 
+    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
+        deployment_nodes = []
+        for node in Node.objects.all():
+            deployment_nodes.append( (node.site_deployment.deployment.id, node.id, node.name) )
+
+        deployment_flavors = []
+        for flavor in Flavor.objects.all():
+            for deployment in flavor.deployments.all():
+                deployment_flavors.append( (deployment.id, flavor.id, flavor.name) )
+
+        deployment_images = []
+        for image in Image.objects.all():
+            for deployment_image in image.imagedeployments.all():
+                deployment_images.append( (deployment_image.deployment.id, image.id, image.name) )
+
+        site_login_bases = []
+        for site in Site.objects.all():
+            site_login_bases.append((site.id, site.login_base))
+
+        context["deployment_nodes"] = deployment_nodes
+        context["deployment_flavors"] = deployment_flavors
+        context["deployment_images"] = deployment_images
+        context["site_login_bases"] = site_login_bases
+        return super(InstanceAdmin, self).render_change_form(request, context, add, change, form_url, obj)
+
+    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
+        if db_field.name == 'deployment':
+           kwargs['queryset'] = Deployment.select_by_acl(request.user).filter(sitedeployments__nodes__isnull=False).distinct()
+           kwargs['widget'] = forms.Select(attrs={'onChange': "instance_deployment_changed(this);"})
+        if db_field.name == 'flavor':
+           kwargs['widget'] = forms.Select(attrs={'onChange': "instance_flavor_changed(this);"})
+
+        field = super(InstanceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+
+        return field
+
     #def save_model(self, request, obj, form, change):
     #    # update openstack connection to use this site/tenant
     #    auth = request.session.get('auth', {})
diff --git a/xos/templates/admin/core/instance/change_form.html b/xos/templates/admin/core/instance/change_form.html
new file mode 100644
index 0000000..4b5439c
--- /dev/null
+++ b/xos/templates/admin/core/instance/change_form.html
@@ -0,0 +1,114 @@
+{% extends 'admin/change_form.html' %}
+{% block extrahead %}
+{{ block.super }} 
+<script>
+deployment_nodes = [
+{% for dn in deployment_nodes %}
+   [{{ dn.0 }}, {{ dn.1 }} , "{{ dn.2 }}"],
+{% endfor %}
+];
+
+deployment_flavors = [
+{% for dn in deployment_flavors %}
+   [{{ dn.0 }}, {{ dn.1 }} , "{{ dn.2 }}"],
+{% endfor %}
+];
+
+deployment_images = [
+{% for dn in deployment_images %}
+   [{{ dn.0 }}, {{ dn.1 }} , "{{ dn.2 }}"],
+{% endfor %}
+];
+
+site_login_bases = [
+{% for s in site_login_bases %}
+  [{{ s.0 }}, "{{ s.1 }}"],
+{% endfor %}
+];
+
+function option_html(val, text, selected) {
+    if (selected) {
+        return '<option value="' + val + '" selected>' + text + '</option>\n';
+    } else {
+        return '<option value="' + val + '">' + text + '</option>\n';
+    }
+}
+
+function update_nodes(deployment_select, flavor_select, node_select) {
+    deployment_id = $(deployment_select).val();
+    node_id = $(node_select).val();
+    flavor_name = $(flavor_select).children(":selected").text()
+    html="";
+    for (i in deployment_nodes) {
+        // this is for EC2, where the node hostnames imply the flavor.
+        dn = deployment_nodes[i];
+        if ((dn[0] == deployment_id) && (dn[2].lastIndexOf(flavor_name,0) === 0)) {
+            html = html + option_html(dn[1], dn[2], dn[1]==node_id);
+        }
+    }
+    if (!html) {
+        // now try it without the flavor hostname prefix matching
+        for (i in deployment_nodes) {
+            dn = deployment_nodes[i];
+            if (dn[0] == deployment_id) {
+                html = html + option_html(dn[1], dn[2], dn[1]==node_id);
+            }
+        }
+    }
+    html = "<option value=''>---------</option>\n" + html;
+    node_select.empty().append(html);
+}
+
+function update_flavors(deployment_select, flavor_select) {
+    deployment_id = $(deployment_select).val();
+    flavor_id = $(flavor_select).val();
+    html = "<option value=''>---------</option>\n";
+    for (i in deployment_flavors) {
+        dn = deployment_flavors[i];
+        if (dn[0] == deployment_id) {
+            html = html + option_html(dn[1], dn[2], dn[1] == flavor_id);
+        }
+    }
+    flavor_select.empty().append(html);
+}
+
+function update_images(deployment_select, image_select) {
+    deployment_id = $(deployment_select).val();
+    image_id = $(image_select).val();
+    html = "<option value=''>---------</option>\n";
+    for (i in deployment_images) {
+        dn = deployment_images[i];
+        if (dn[0] == deployment_id) {
+            html = html + option_html(dn[1], dn[2], dn[1] == image_id);
+        }
+    }
+    image_select.empty().append(html);
+}
+
+function instance_deployment_changed(any_control) {
+   /* This function handles someone changing the deployment control
+      It updates the flavors and nodes dialogs
+      accordingly.
+   */
+
+    deployment_select = $("#id_deployment");
+    node_select = $("#id_node");
+    flavor_select = $("#id_flavor");
+    image_select = $("#id_image");
+
+    update_nodes(deployment_select, flavor_select, node_select);
+    update_flavors(deployment_select, flavor_select);
+    update_images(deployment_select, image_select);
+}
+
+function instance_flavor_changed(any_control) {
+    deployment_select = $("#id_deployment");
+    node_select = $("#id_node");
+    flavor_select = $("#id_flavor");
+    update_nodes(deployment_select, flavor_select, node_select);
+}
+
+</script>
+
+{% endblock %}
+