Merge branch 'master' of github.com:open-cloud/xos
diff --git a/xos/services/cord/admin.py b/xos/services/cord/admin.py
index 56e46ae..4195aaa 100644
--- a/xos/services/cord/admin.py
+++ b/xos/services/cord/admin.py
@@ -351,6 +351,7 @@
downlink_speed = forms.CharField(required = False)
status = forms.ChoiceField(choices=CordSubscriberRoot.status_choices, required=True)
enable_uverse = forms.BooleanField(required=False)
+ cdn_enable = forms.BooleanField(required=False)
def __init__(self,*args,**kwargs):
super (CordSubscriberRootForm,self ).__init__(*args,**kwargs)
@@ -361,6 +362,7 @@
self.fields['downlink_speed'].initial = self.instance.downlink_speed
self.fields['status'].initial = self.instance.status
self.fields['enable_uverse'].initial = self.instance.enable_uverse
+ self.fields['cdn_enable'].initial = self.instance.cdn_enable
if (not self.instance) or (not self.instance.pk):
# default fields for an 'add' form
self.fields['kind'].initial = CORD_SUBSCRIBER_KIND
@@ -368,6 +370,7 @@
self.fields['downlink_speed'].initial = CordSubscriberRoot.get_default_attribute("downlink_speed")
self.fields['status'].initial = CordSubscriberRoot.get_default_attribute("status")
self.fields['enable_uverse'].initial = CordSubscriberRoot.get_default_attribute("enable_uverse")
+ self.fields['cdn_enable'].initial = CordSubscriberRoot.get_default_attribute("cdn_enable")
def save(self, commit=True):
self.instance.url_filter_level = self.cleaned_data.get("url_filter_level")
@@ -375,6 +378,7 @@
self.instance.downlink_speed = self.cleaned_data.get("downlink_speed")
self.instance.status = self.cleaned_data.get("status")
self.instance.enable_uverse = self.cleaned_data.get("enable_uverse")
+ self.instance.cdn_enable = self.cleaned_data.get("cdn_enable")
return super(CordSubscriberRootForm, self).save(commit=commit)
class Meta:
@@ -384,7 +388,7 @@
list_display = ('backend_status_icon', 'id', 'name', )
list_display_links = ('backend_status_icon', 'id', 'name', )
fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'name', 'service_specific_id', # 'service_specific_attribute',
- 'url_filter_level', "uplink_speed", "downlink_speed", "status", "enable_uverse"],
+ 'url_filter_level', "uplink_speed", "downlink_speed", "status", "enable_uverse", "cdn_enable"],
'classes':['suit-tab suit-tab-general']})]
readonly_fields = ('backend_status_text', 'service_specific_attribute',)
form = CordSubscriberRootForm
diff --git a/xos/services/exampleservice/admin.py b/xos/services/exampleservice/admin.py
index d4f6248..f679e4e 100644
--- a/xos/services/exampleservice/admin.py
+++ b/xos/services/exampleservice/admin.py
@@ -9,25 +9,40 @@
from services.exampleservice.models import *
+class ExampleServiceForm(forms.ModelForm):
+
+ class Meta:
+ model = ExampleService
+
+ def __init__(self, *args, **kwargs):
+ super(ExampleServiceForm, self).__init__(*args, **kwargs)
+
+ if self.instance:
+ self.fields['service_message'].initial = self.instance.service_message
+
+ def save(self, commit=True):
+ self.instance.service_message = self.cleaned_data.get('service_message')
+ return super(ExampleServiceForm, self).save(commit=commit)
+
class ExampleServiceAdmin(ReadOnlyAwareAdmin):
model = ExampleService
verbose_name = SERVICE_NAME_VERBOSE
verbose_name_plural = SERVICE_NAME_VERBOSE_PLURAL
+ form = ExampleServiceForm
+ inlines = [SliceInline]
- list_display = ('backend_status_icon', 'name', 'enabled',)
- list_display_links = ('backend_status_icon', 'name', )
+ list_display = ('backend_status_icon', 'name', 'service_message', 'enabled')
+ list_display_links = ('backend_status_icon', 'name', 'service_message' )
fieldsets = [(None, {
- 'fields': ['backend_status_text', 'name', 'enabled', 'versionNumber', 'description',],
+ 'fields': ['backend_status_text', 'name', 'enabled', 'versionNumber', 'service_message', 'description',],
'classes':['suit-tab suit-tab-general',],
})]
readonly_fields = ('backend_status_text', )
user_readonly_fields = ['name', 'enabled', 'versionNumber', 'description',]
- inlines = [SliceInline]
-
extracontext_registered_admins = True
suit_form_tabs = (
diff --git a/xos/services/exampleservice/models.py b/xos/services/exampleservice/models.py
index 6305b54..5d3e258 100644
--- a/xos/services/exampleservice/models.py
+++ b/xos/services/exampleservice/models.py
@@ -16,7 +16,8 @@
class Meta:
app_label = SERVICE_NAME
verbose_name = SERVICE_NAME_VERBOSE
- proxy = True
+
+ service_message = models.CharField(max_length=254, help_text="Service Message to Display")
class ExampleTenant(TenantWithContainer):
diff --git a/xos/synchronizers/base/ansible.py b/xos/synchronizers/base/ansible.py
index d92835a..b6f1ca2 100644
--- a/xos/synchronizers/base/ansible.py
+++ b/xos/synchronizers/base/ansible.py
@@ -69,7 +69,7 @@
total_unreachable += unreachable
total_failed += failed
return {'unreachable':total_unreachable,'failed':total_failed}
-
+
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
@@ -86,8 +86,17 @@
objname = opts["ansible_tag"]
- os.system('mkdir -p %s' % os.path.join(sys_dir, path))
- return (opts, os.path.join(sys_dir,path,objname))
+ pathed_sys_dir = os.path.join(sys_dir, path)
+ if not os.path.isdir(pathed_sys_dir):
+ os.makedirs(pathed_sys_dir)
+
+ # symlink steps/roles into sys/roles so that playbooks can access roles
+ roledir = os.path.join(step_dir,"roles")
+ rolelink = os.path.join(pathed_sys_dir, "roles")
+ if os.path.isdir(roledir) and not os.path.islink(rolelink):
+ os.symlink(roledir,rolelink)
+
+ return (opts, os.path.join(pathed_sys_dir,objname))
def run_template(name, opts, path='', expected_num=None, ansible_config=None, ansible_hosts=None, run_ansible_script=None):
template = os_template_env.get_template(name)
diff --git a/xos/synchronizers/exampleservice/steps/exampletenant_playbook.yaml b/xos/synchronizers/exampleservice/steps/exampletenant_playbook.yaml
index 9da06f5..89e4617 100644
--- a/xos/synchronizers/exampleservice/steps/exampletenant_playbook.yaml
+++ b/xos/synchronizers/exampleservice/steps/exampletenant_playbook.yaml
@@ -6,13 +6,11 @@
user: ubuntu
sudo: yes
gather_facts: no
+ vars:
+ - tenant_message: "{{ tenant_message }}"
+ - service_message: "{{ service_message }}"
- tasks:
- - name: install apache
- apt:
- name=apache2
- update_cache=yes
-
- - name: write message
- shell: echo "{{ tenant_message }}" > /var/www/html/index.html
+ roles:
+ - install_apache
+ - create_index
diff --git a/xos/synchronizers/exampleservice/steps/roles/create_index/tasks/main.yml b/xos/synchronizers/exampleservice/steps/roles/create_index/tasks/main.yml
new file mode 100644
index 0000000..91c6029
--- /dev/null
+++ b/xos/synchronizers/exampleservice/steps/roles/create_index/tasks/main.yml
@@ -0,0 +1,7 @@
+---
+
+- name: Write index.html file to apache document root
+ template:
+ src=index.html.j2
+ dest=/var/www/html/index.html
+
diff --git a/xos/synchronizers/exampleservice/steps/roles/create_index/templates/index.html.j2 b/xos/synchronizers/exampleservice/steps/roles/create_index/templates/index.html.j2
new file mode 100644
index 0000000..9cec084
--- /dev/null
+++ b/xos/synchronizers/exampleservice/steps/roles/create_index/templates/index.html.j2
@@ -0,0 +1,4 @@
+ExampleService
+ Service Message: "{{ service_message }}"
+ Tenant Message: "{{ tenant_message }}"
+
diff --git a/xos/synchronizers/exampleservice/steps/roles/install_apache/tasks/main.yml b/xos/synchronizers/exampleservice/steps/roles/install_apache/tasks/main.yml
new file mode 100644
index 0000000..d9a155c
--- /dev/null
+++ b/xos/synchronizers/exampleservice/steps/roles/install_apache/tasks/main.yml
@@ -0,0 +1,7 @@
+---
+
+- name: Install apache using apt
+ apt:
+ name=apache2
+ update_cache=yes
+
diff --git a/xos/synchronizers/exampleservice/steps/sync_exampletenant.py b/xos/synchronizers/exampleservice/steps/sync_exampletenant.py
index bc4169b..fbde96f 100644
--- a/xos/synchronizers/exampleservice/steps/sync_exampletenant.py
+++ b/xos/synchronizers/exampleservice/steps/sync_exampletenant.py
@@ -33,8 +33,23 @@
return objs
+ def get_exampleservice(self, o):
+ if not o.provider_service:
+ return None
+
+ exampleservice = ExampleService.get_service_objects().filter(id=o.provider_service.id)
+
+ if not exampleservice:
+ return None
+
+ return exampleservice[0]
+
# Gets the attributes that are used by the Ansible template but are not
# part of the set of default attributes.
def get_extra_attributes(self, o):
- return {"tenant_message": o.tenant_message}
+ fields = {}
+ fields['tenant_message'] = o.tenant_message
+ exampleservice = self.get_exampleservice(o)
+ fields['service_message'] = exampleservice.service_message
+ return fields
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant.py b/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
index 2e8e0c6..a8c6b4f 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
+++ b/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
@@ -66,38 +66,52 @@
vcpe_service = self.get_vcpe_service(o)
dnsdemux_ip = None
- if vcpe_service.backend_network_label:
- # Connect to dnsdemux using the network specified by
- # vcpe_service.backend_network_label
- for service in HpcService.objects.all():
- for slice in service.slices.all():
- if "dnsdemux" in slice.name:
- for instance in slice.instances.all():
- for ns in instance.ports.all():
- if ns.ip and ns.network.labels and (vcpe_service.backend_network_label in ns.network.labels):
- dnsdemux_ip = ns.ip
- if not dnsdemux_ip:
- logger.info("failed to find a dnsdemux on network %s" % vcpe_service.backend_network_label)
+ cdn_prefixes = []
+
+ cdn_config_fn = "/opt/xos/synchronizers/vcpe/cdn_config"
+ if os.path.exists(cdn_config_fn):
+ # manual CDN configuration
+ # the first line is the address of dnsredir
+ # the remaining lines are domain names, one per line
+ lines = file(cdn_config_fn).readlines()
+ if len(lines)>=2:
+ dnsdemux_ip = lines[0].strip()
+ cdn_prefixes = [x.strip() for x in lines[1:] if x.strip()]
else:
- # Connect to dnsdemux using the instance's public address
- for service in HpcService.objects.all():
- for slice in service.slices.all():
- if "dnsdemux" in slice.name:
- for instance in slice.instances.all():
- if dnsdemux_ip=="none":
- try:
- dnsdemux_ip = socket.gethostbyname(instance.node.name)
- except:
- pass
- if not dnsdemux_ip:
- logger.info("failed to find a dnsdemux with a public address")
+ # automatic CDN configuiration
+ # it learns everything from CDN objects in XOS
+ # not tested on pod.
+ if vcpe_service.backend_network_label:
+ # Connect to dnsdemux using the network specified by
+ # vcpe_service.backend_network_label
+ for service in HpcService.objects.all():
+ for slice in service.slices.all():
+ if "dnsdemux" in slice.name:
+ for instance in slice.instances.all():
+ for ns in instance.ports.all():
+ if ns.ip and ns.network.labels and (vcpe_service.backend_network_label in ns.network.labels):
+ dnsdemux_ip = ns.ip
+ if not dnsdemux_ip:
+ logger.info("failed to find a dnsdemux on network %s" % vcpe_service.backend_network_label)
+ else:
+ # Connect to dnsdemux using the instance's public address
+ for service in HpcService.objects.all():
+ for slice in service.slices.all():
+ if "dnsdemux" in slice.name:
+ for instance in slice.instances.all():
+ if dnsdemux_ip=="none":
+ try:
+ dnsdemux_ip = socket.gethostbyname(instance.node.name)
+ except:
+ pass
+ if not dnsdemux_ip:
+ logger.info("failed to find a dnsdemux with a public address")
+
+ for prefix in CDNPrefix.objects.all():
+ cdn_prefixes.append(prefix.prefix)
dnsdemux_ip = dnsdemux_ip or "none"
- cdn_prefixes = []
- for prefix in CDNPrefix.objects.all():
- cdn_prefixes.append(prefix.prefix)
-
# Broadbandshield can either be set up internally, using vcpe_service.bbs_slice,
# or it can be setup externally using vcpe_service.bbs_server.
diff --git a/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2 b/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2
index 2f93777..0b3c807 100644
--- a/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2
+++ b/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2
@@ -3,11 +3,13 @@
no-resolv
{% if cdn_enable %}
+{% if cdn_prefixes %}
# CDN
{% for prefix in cdn_prefixes %}
server=/{{ prefix }}/{{ dnsdemux_ip }}
{% endfor %}
{% endif %}
+{% endif %}
# use OpenDNS service
server=208.67.222.123
diff --git a/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2 b/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2
index 3682cdf..004576f 100644
--- a/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2
+++ b/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2
@@ -3,11 +3,13 @@
no-resolv
{% if cdn_enable %}
+{% if cdn_prefixes %}
# CDN
{% for prefix in cdn_prefixes %}
server=/{{ prefix }}/{{ dnsdemux_ip }}
{% endfor %}
{% endif %}
+{% endif %}
# use google's DNS service
{% for dns_server in dns_servers %}