Browse Source

deployment node type

Change-Id: I412969ee3f25ed7e02609a0457e67fb12e526740
Kanagaraj Manickam 3 years ago
parent
commit
350f37bbc5

+ 1
- 0
config-generator.conf View File

@@ -7,3 +7,4 @@ namespace = oslo.middleware
7 7
 namespace = oslo.db
8 8
 namespace = oslo.log
9 9
 namespace = oslo.service.service
10
+namespace = os_namos

+ 2
- 2
etc/namos.conf View File

@@ -11,7 +11,7 @@ rabbit_hosts = 172.241.0.101
11 11
 connection = mysql+pymysql://root:password@172.241.0.101/namos?charset=utf8
12 12
 
13 13
 [os_manager]
14
-workers=3
14
+workers=20
15 15
 
16 16
 [os_namos]
17
-region_name=RegionTwo
17
+region_name=RegionTwo

+ 44
- 26
etc/oslo-config-schema.sync View File

@@ -1,27 +1,45 @@
1 1
 # List of config generator conf files for syncing the conf with namos
2
-heat=/opt/stack/heat/config-generator.conf
3
-namos=/home/manickan/workspace/namos/openstack/namos/config-generator.conf
4
-os_namos=/home/manickan/workspace/namos/openstack/os-namos/config-generator.conf
5
-keystone=/opt/stack/keystone/config-generator/keystone.conf
6
-neutron-bgp-dragent=/opt/stack/neutron/etc/oslo-config-generator/bgp_dragent.ini
7
-neutron-dhcp-agent=/opt/stack/neutron/etc/oslo-config-generator/dhcp_agent.ini
8
-neutron-l3-agent=/opt/stack/neutron/etc/oslo-config-generator/l3_agent.ini
9
-neutron-linuxbridge-agent=/opt/stack/neutron/etc/oslo-config-generator/linuxbridge_agent.ini
10
-neutron-metadata-agent=/opt/stack/neutron/etc/oslo-config-generator/metadata_agent.ini
11
-neutron-metering-agent=/opt/stack/neutron/etc/oslo-config-generator/metering_agent.ini
12
-neutron-ml2=/opt/stack/neutron/etc/oslo-config-generator/ml2_conf.ini
13
-neutron-ml2-sriov=/opt/stack/neutron/etc/oslo-config-generator/ml2_conf_sriov.ini
14
-neutron=/opt/stack/neutron/etc/oslo-config-generator/neutron.conf
15
-neutron-openvswitch-agent=/opt/stack/neutron/etc/oslo-config-generator/openvswitch_agent.ini
16
-neutron-sriov-agent=/opt/stack/neutron/etc/oslo-config-generator/sriov_agent.ini
17
-lbaas-agent=/opt/stack/neutron-lbaas/etc/oslo-config-generator/lbaas_agent.ini
18
-neutron-lbaas=/opt/stack/neutron-lbaas/etc/oslo-config-generator/neutron_lbaas.conf
19
-services-lbaas=/opt/stack/neutron-lbaas/etc/oslo-config-generator/services_lbaas.conf
20
-glance-api=/opt/stack/glance/etc/oslo-config-generator/glance-api.conf
21
-glance-cache=/opt/stack/glance/etc/oslo-config-generator/glance-cache.conf
22
-glance-glare=/opt/stack/glance/etc/oslo-config-generator/glance-glare.conf
23
-glance-registry=/opt/stack/glance/etc/oslo-config-generator/glance-registry.conf
24
-glance-scrubber=/opt/stack/glance/etc/oslo-config-generator/glance-scrubber.conf
25
-glance-manage=/opt/stack/glance/etc/oslo-config-generator/glance-manage.conf
26
-nova=/opt/stack/nova/etc/nova/nova-config-generator.conf
27
-cinder=/opt/stack/cinder/cinder/config/cinder-config-generator.conf
2
+[namos]
3
+namos.conf=/home/manickan/workspace/namos/openstack/namos/config-generator.conf
4
+
5
+[heat]
6
+heat.conf=/opt/stack/heat/config-generator.conf
7
+
8
+[keystone]
9
+keystone.conf=/opt/stack/keystone/config-generator/keystone.conf
10
+
11
+[neutron]
12
+bgp_dragent.ini=/opt/stack/neutron/etc/oslo-config-generator/bgp_dragent.ini
13
+dhcp_agent.ini=/opt/stack/neutron/etc/oslo-config-generator/dhcp_agent.ini
14
+l3_agent.ini=/opt/stack/neutron/etc/oslo-config-generator/l3_agent.ini
15
+linuxbridge_agent.ini=/opt/stack/neutron/etc/oslo-config-generator/linuxbridge_agent.ini
16
+metadata_agent.ini=/opt/stack/neutron/etc/oslo-config-generator/metadata_agent.ini
17
+metering_agent.ini=/opt/stack/neutron/etc/oslo-config-generator/metering_agent.ini
18
+ml2_conf.ini=/opt/stack/neutron/etc/oslo-config-generator/ml2_conf.ini
19
+ml2_conf_sriov.ini=/opt/stack/neutron/etc/oslo-config-generator/ml2_conf_sriov.ini
20
+neutron.conf=/opt/stack/neutron/etc/oslo-config-generator/neutron.conf
21
+openvswitch_agent.ini=/opt/stack/neutron/etc/oslo-config-generator/openvswitch_agent.ini
22
+sriov_agent.ini=/opt/stack/neutron/etc/oslo-config-generator/sriov_agent.ini
23
+lbaas_agent.ini=/opt/stack/neutron-lbaas/etc/oslo-config-generator/lbaas_agent.ini
24
+neutron_lbaas.conf=/opt/stack/neutron-lbaas/etc/oslo-config-generator/neutron_lbaas.conf
25
+services_lbaas.conf=/opt/stack/neutron-lbaas/etc/oslo-config-generator/services_lbaas.conf
26
+
27
+[glance]
28
+glance-api.conf=/opt/stack/glance/etc/oslo-config-generator/glance-api.conf
29
+glance-cache.conf=/opt/stack/glance/etc/oslo-config-generator/glance-cache.conf
30
+glance-glare.conf=/opt/stack/glance/etc/oslo-config-generator/glance-glare.conf
31
+glance-registry.conf=/opt/stack/glance/etc/oslo-config-generator/glance-registry.conf
32
+glance-scrubber.conf=/opt/stack/glance/etc/oslo-config-generator/glance-scrubber.conf
33
+glance-manage.conf=/opt/stack/glance/etc/oslo-config-generator/glance-manage.conf
34
+
35
+[nova]
36
+nova.conf=/opt/stack/nova/etc/nova/nova-config-generator.conf
37
+
38
+[cinder]
39
+cinder.conf=/opt/stack/cinder/cinder/config/cinder-config-generator.conf
40
+
41
+[ceilometer]
42
+ceilometer.conf=/opt/stack/ceilometer/etc/ceilometer/ceilometer-config-generator.conf
43
+
44
+[aodh]
45
+aodh.conf=/opt/stack/aodh/aodh-config-generator.conf

+ 83
- 0
namos/cmd/api.py View File

@@ -0,0 +1,83 @@
1
+# -*- encoding: utf-8 -*-
2
+#
3
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
4
+# All Rights Reserved.
5
+#
6
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
7
+#    not use this file except in compliance with the License. You may obtain
8
+#    a copy of the License at
9
+#
10
+#         http://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+#    Unless required by applicable law or agreed to in writing, software
13
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+#    License for the specific language governing permissions and limitations
16
+#    under the License.
17
+
18
+from bottle import route
19
+from bottle import run
20
+
21
+from namos.conductor import rpcapi
22
+from oslo_context import context
23
+
24
+
25
+@route('/v1/regions')
26
+def regions():
27
+    regions = rpcapi.ConductorAPI().region_get_all(
28
+        context.get_admin_context())
29
+
30
+    return {'regions': regions}
31
+
32
+
33
+@route('/v1/view_360')
34
+def infra():
35
+    _infra = rpcapi.ConductorAPI().view_360(
36
+        context.get_admin_context(), True, True, True)
37
+    return {'view_360': _infra}
38
+
39
+
40
+@route('/v1/config_schema/<service>')
41
+def config_schema(service):
42
+    schema = dict()
43
+    c = rpcapi.ConductorAPI()
44
+    schema = c.config_schema(context.RequestContext(),
45
+                             project=service,
46
+                             with_file_link=True)
47
+
48
+    return dict(config_schema=schema)
49
+
50
+
51
+# Openstack view
52
+@route('/v1/regions/<region_id>/services')
53
+def perspective_region_service_list(region_id):
54
+    _region = rpcapi.ConductorAPI().region_perspective_get(
55
+        context.get_admin_context(), region_id)
56
+    return {'services': _region['services']}
57
+
58
+
59
+# Data center view
60
+@route('/v1/regions/<region_id>/devices')
61
+def perspective_region_device_list(region_id):
62
+    _region = rpcapi.ConductorAPI().region_perspective_get(
63
+        context.get_admin_context(), region_id)
64
+    return {'devices': _region['devices']}
65
+
66
+
67
+# Openstack service view
68
+@route('/v1/services/<service_id>')
69
+def perspective_region_service(service_id):
70
+    _srv = rpcapi.ConductorAPI().service_perspective_get(
71
+        context.get_admin_context(), service_id)
72
+    return {'service': _srv}
73
+
74
+
75
+# Data center device view
76
+@route('/v1/devices/<device_id>')
77
+def perspective_region_device(device_id):
78
+    _dvc = rpcapi.ConductorAPI().device_perspective_get(
79
+        context.get_admin_context(), device_id)
80
+    return {'device': _dvc}
81
+
82
+
83
+run(host='localhost', port=9999)

+ 75
- 65
namos/cmd/manage.py View File

@@ -19,6 +19,7 @@ from oslo_config import cfg
19 19
 from namos.common import config
20 20
 from namos.common import exception
21 21
 from namos.common import utils
22
+
22 23
 from namos.db import api
23 24
 from namos.db import sample
24 25
 from namos.db.sqlalchemy import migration
@@ -30,30 +31,37 @@ MANAGE_COMMAND_NAME = 'namos-manage'
30 31
 
31 32
 class HeartBeat(object):
32 33
     def report_status(self):
33
-        # TODO(mrkanag) Make like Node: Service: worker: status
34
-        for sw in api.service_worker_get_all(None):
35
-            # TODO(mrkanag) Move this to db layer and query non deleted entries
36
-            if sw.deleted_at is not None:
37
-                continue
38
-
39
-            msg = '[%s] [%s] %s %s' % (
40
-                'T' if sw.is_launcher else 'F',
41
-                'T' if utils.find_status(sw) else 'F',
42
-                sw.name,
43
-                sw.host)
44
-            print (msg)
34
+        print_format = "%-20s%-15s%-15s%-35s%-10s"
35
+        strip = 90 * '-'
36
+        print(strip)
37
+        print(print_format % ('Node',
38
+                              'Type',
39
+                              'Service',
40
+                              'Component',
41
+                              'Status'))
42
+        print(strip)
43
+        for k, s in api.get_status(None).items():
44
+            print(print_format % (s['node'],
45
+                                  s['type'],
46
+                                  s['service'],
47
+                                  s['component'],
48
+                                  s['status']))
49
+        print(strip)
45 50
 
46 51
 
47 52
 class OsloConfigSchemaManager(object):
48 53
     def gen_schema(self):
49 54
         import json
50 55
         cfg_ns = dict()
51
-        for cfg_ in api.config_schema_get_all(None):
52
-            if cfg_.namespace not in cfg_ns:
53
-                cfg_ns[cfg_.namespace] = dict()
54
-            if cfg_.group_name not in cfg_ns[cfg_.namespace]:
55
-                cfg_ns[cfg_.namespace][cfg_.group_name] = dict()
56
-            cfg_ns[cfg_.namespace][cfg_.group_name][cfg_.name] = cfg_.to_dict()
56
+
57
+        if CONF.command.by_namespace:
58
+            for cfg_ in api.config_schema_get_all(None):
59
+                if cfg_.namespace not in cfg_ns:
60
+                    cfg_ns[cfg_.namespace] = dict()
61
+                if cfg_.group_name not in cfg_ns[cfg_.namespace]:
62
+                    cfg_ns[cfg_.namespace][cfg_.group_name] = dict()
63
+                cfg_ns[cfg_.namespace][cfg_.group_name][
64
+                    cfg_.name] = cfg_.to_dict()
57 65
 
58 66
         open(CONF.command.outputfile, 'w').write(json.dumps(cfg_ns))
59 67
 
@@ -62,53 +70,54 @@ class OsloConfigSchemaManager(object):
62 70
             self.gen_schema()
63 71
             return
64 72
 
65
-        sync_map = {}
66
-        with open(CONF.command.syncfile) as f:
67
-            for line in f:
68
-                if line.startswith("#"):
69
-                    continue
70
-                kv = line.split("=")
71
-                sync_map[kv[0]] = kv[1].replace("\n", "")
72
-
73
-        for k, v in sync_map.items():
74
-            out_file = '%s/%s.json' % (CONF.command.outputdir or '/tmp', k)
75
-            cmd = ('oslo-config-generator --config-file %s '
76
-                   '--output-file %s --output-format json' %
77
-                   (v, out_file))
78
-            print ("\nSyncing %s " % cmd)
79
-            import os
80
-            os.system(cmd)
81
-
82
-            if CONF.command.dbsync:
83
-                import json
84
-                conf_dict = json.loads(open(out_file).read())
85
-                for grp, namespaces in conf_dict.items():
86
-                    for namespace, opts in namespaces.items():
87
-                        for name, opt in opts.items():
88
-                            conf_ = dict(
89
-                                namespace=namespace,
90
-                                group_name=grp,
91
-                                name=name,
92
-                                default_value=opt['default'],
93
-                                type=opt['type']['name'],
94
-                                help=opt['help'],
95
-                                required=opt['required'],
96
-                                secret=opt['secret'],
97
-                                mutable=opt['mutable']
98
-                            )
99
-
100
-                            try:
101
-                                api.config_schema_create(None,
102
-                                                         conf_)
103
-                                _a = 'T'
104
-                            except exception.AlreadyExist:
105
-                                _a = 'F'
106
-
107
-                            msg = '[%s] %s::%s::%s' % (_a,
108
-                                                       namespace,
109
-                                                       grp,
110
-                                                       name)
111
-                            print (msg)
73
+        sync_map = utils.file_to_configs(CONF.command.syncfile)
74
+
75
+        for srv, confs in sync_map.items():
76
+            for conf, gen_conf in confs.items():
77
+                out_file = '%s/%s.json' % (CONF.command.outputdir or '/tmp',
78
+                                           conf)
79
+                cmd = ('oslo-config-generator --config-file %s '
80
+                       '--output-file %s --output-format json' %
81
+                       (gen_conf, out_file))
82
+                print ("\nSyncing %s " % cmd)
83
+                import os
84
+                os.system(cmd)
85
+
86
+                if CONF.command.dbsync:
87
+                    import json
88
+                    conf_dict = json.loads(open(out_file).read())
89
+                    for grp, namespaces in conf_dict.items():
90
+                        for namespace, opts in namespaces.items():
91
+                            for name, opt in opts.items():
92
+                                conf_ = dict(
93
+                                    namespace=namespace,
94
+                                    project=srv,
95
+                                    file_name=conf,
96
+                                    group_name=grp,
97
+                                    name=name.replace('-', '_'),
98
+                                    default_value=opt['default'],
99
+                                    type=opt['type']['name'],
100
+                                    help=opt['help'],
101
+                                    required=opt['required'],
102
+                                    secret=opt['secret'],
103
+                                    mutable=opt['mutable']
104
+                                )
105
+
106
+                                try:
107
+                                    api.config_schema_create(None,
108
+                                                             conf_)
109
+                                    _a = 'T'
110
+                                except exception.AlreadyExist:
111
+                                    _a = 'F'
112
+
113
+                                msg = '[%s] %s::%s::%s::%s::%s' % (
114
+                                    _a,
115
+                                    srv,
116
+                                    conf,
117
+                                    namespace,
118
+                                    grp,
119
+                                    name)
120
+                                print (msg)
112 121
 
113 122
 
114 123
 class DBCommand(object):
@@ -180,6 +189,7 @@ def add_command_parsers(subparsers):
180 189
     parser.add_argument('-j', '--outputfile')
181 190
     parser.add_argument('-s', '--dbsync', action='store_true')
182 191
     parser.add_argument('-g', '--gen', action='store_true')
192
+    parser.add_argument('-n', '--by-namespace', action='store_true')
183 193
     parser.set_defaults(func=OsloConfigSchemaManager().sync)
184 194
 
185 195
     parser = subparsers.add_parser('status')

+ 27
- 0
namos/common/config.py View File

@@ -21,8 +21,35 @@ PROJECT_NAME = 'namos'
21 21
 VERSION = namos.__version__
22 22
 MESSAGE_QUEUE_CONDUCTOR_TOPIC = '%s.conductor' % PROJECT_NAME
23 23
 CONF = cfg.CONF
24
+SCvsNT = dict(
25
+    controller=['nova-api', 'nova-cert', 'nova-conductor', 'nova-consoleauth',
26
+                'nova-scheduler',
27
+                'cinder-api', 'cinder-scheduler',
28
+                'neutron-server',
29
+                'glance-api', 'glance-registry',
30
+                'keystone-all',
31
+                'heat-api', 'heat-api-cfn', 'heat-api-cloudwatch',
32
+                'heat-engine',
33
+                'namos-manager',
34
+                'ceilometer-api', 'ceilometer-polling', 'ceilometer-collector',
35
+                'ceilometer-agent-notification',
36
+                'tacker-server'
37
+                ],
38
+    compute=['nova-compute', 'neutron-openvswitch-agent',
39
+             'ceilometer-agent-compute'],
40
+    storage=['cinder-volume'],
41
+    network=['neutron-dhcp-agent', 'neutron-l3-agent', 'neutron-lbaas-agent',
42
+             'neutron-metadata-agent']
43
+)
24 44
 
25 45
 
46
+def find_type(name):
47
+    for key, value in SCvsNT.items():
48
+        if name in value:
49
+            return key
50
+
51
+    return 'UNKNOWN'
52
+
26 53
 conductor_opts = [
27 54
     cfg.IntOpt('workers',
28 55
                default=1,

+ 48
- 0
namos/common/utils.py View File

@@ -27,3 +27,51 @@ def find_status(sw, report_interval=60):
27 27
             status = True
28 28
 
29 29
     return status
30
+
31
+
32
+def _to_list(list_in_str):
33
+    '''string [a,b,c] -> python list [a, b ,c].'''
34
+    def strip_out(s):
35
+        start_idx = 0
36
+        end_idx = len(s)
37
+        if s[start_idx] == '[' \
38
+                or s[start_idx] == '\'' \
39
+                or s[start_idx] == '"':
40
+            start_idx += 1
41
+        if s[end_idx - 1] == ']' \
42
+                or s[end_idx - 1] == '\'' \
43
+                or s[end_idx - 1] == '"':
44
+            end_idx -= 1
45
+        return s[start_idx:end_idx]
46
+
47
+    l = []
48
+    for s in strip_out(list_in_str.strip()).split(','):
49
+        s = str(strip_out(s.strip()))
50
+        l.append(s)
51
+
52
+    return l
53
+
54
+
55
+def file_to_configs(file_path):
56
+    with open(file_path, 'r') as file:
57
+        section = ''
58
+        conf_dict = dict()
59
+
60
+        for line in file:
61
+            if len(line.strip()) == 0:
62
+                continue
63
+
64
+            if line.strip().startswith('#'):
65
+                continue
66
+
67
+            if line.strip().startswith('['):
68
+                section = line.replace('[', '').replace(']', '').strip()
69
+                conf_dict[section] = dict()
70
+                continue
71
+            if section:
72
+                kv = line.strip().split('=')
73
+                # TODO(mrkanag) if values required, enable it here
74
+                conf_dict[section][kv[0].strip()] = kv[1].strip().replace(
75
+                    "\n", "")
76
+
77
+    return conf_dict

+ 433
- 210
namos/conductor/manager.py View File

@@ -19,7 +19,7 @@ from oslo_context import context
19 19
 from oslo_log import log
20 20
 from oslo_utils import timeutils
21 21
 
22
-from namos.common import config
22
+from namos.common import config as namos_config
23 23
 from namos.common import exception
24 24
 from namos.common import messaging
25 25
 from namos.common import utils
@@ -28,7 +28,7 @@ from namos.db import openstack_drivers
28 28
 
29 29
 LOG = log.getLogger(__name__)
30 30
 
31
-config.register_conductor_opts()
31
+namos_config.register_conductor_opts()
32 32
 
33 33
 CONF = cfg.CONF
34 34
 
@@ -46,73 +46,125 @@ def request_context(func):
46 46
 
47 47
 class ConductorManager(object):
48 48
     RPC_API_VERSION = '1.0'
49
-    TOPIC = config.MESSAGE_QUEUE_CONDUCTOR_TOPIC
49
+    TOPIC = namos_config.MESSAGE_QUEUE_CONDUCTOR_TOPIC
50 50
 
51 51
     @request_context
52 52
     def add_region(self, context, region):
53
-        # Move this try except to wrpper fn of the db layer
54
-        try:
55
-            db_api.region_create(context, region)
56
-        except:  # noqa
57
-            raise exception.NamosException()
53
+        return db_api.region_create(context, region)
54
+
55
+    @request_context
56
+    def region_get(self, context, region_id):
57
+        return db_api.region_get(context. region_id)
58
+
59
+    @request_context
60
+    def region_update(self, context, region_id, region):
61
+        return db_api.region_update(context. region_id, region)
58 62
 
59 63
     @request_context
60 64
     def region_get_all(self, context):
61 65
         return db_api.region_get_all(context)
62 66
 
67
+    @request_context
68
+    def region_delete(self, context, region_id):
69
+        return db_api.region_delete(context. region_id)
70
+
71
+    @request_context
72
+    def add_service_node(self, context, service_node):
73
+        return db_api.service_node_create(context, service_node)
74
+
75
+    @request_context
76
+    def service_node_get(self, context, service_node_id):
77
+        return db_api.service_node_get(context. service_node_id)
78
+
79
+    @request_context
80
+    def service_node_update(self, context, service_node_id, service_node):
81
+        return db_api.service_node_update(context.
82
+                                          service_node_id,
83
+                                          service_node)
84
+
85
+    @request_context
86
+    def service_node_get_all(self, context):
87
+        return db_api.service_node_get_all(context)
88
+
89
+    @request_context
90
+    def service_node_delete(self, context, service_node_id):
91
+        return db_api.service_node_delete(context. service_node_id)
92
+
63 93
     @request_context
64 94
     def register_myself(self, context, registration_info):
65
-        LOG.info("REGISTER [%s.%s.%s] START" % (
95
+        LOG.info("REGISTER [%s.%s.%s] START\n%s" % (
66 96
             registration_info['project_name'],
67 97
             registration_info['prog_name'],
68
-            registration_info['identification']
98
+            registration_info['identification'],
99
+            registration_info
69 100
         ))
70 101
 
102
+        # Region processing
103
+        rp = RegionProcessor(context,
104
+                             self,
105
+                             registration_info)
106
+        region_id = rp.process_region()
107
+
71 108
         # Service processing
72 109
         sp = ServiceProcessor(context,
73 110
                               self,
111
+                              region_id,
74 112
                               registration_info)
75
-        service_component_id, service_worker_id = sp.process_service(context)
76
-
113
+        service_component_id, service_worker_id = sp.process_service()
114
+
115
+        # COnfig processing
116
+        cp = ConfigProcessor(context,
117
+                             self,
118
+                             registration_info,
119
+                             service_worker_id)
120
+        cp.process_configs()
77 121
         #  Device Driver processing
78
-        dp = DriverProcessor(service_worker_id,
79
-                             registration_info['config_dict'])
80
-        dp.process_drivers(context)
122
+        # TODO(mrkanag) if this to be per service component??
123
+        dp = DriverProcessor(context,
124
+                             self,
125
+                             service_worker_id,
126
+                             region_id)
127
+        dp.process_drivers()
128
+
129
+        self._regisgration_ackw(context,
130
+                                registration_info['identification'])
131
+
81 132
         LOG.info("REGISTER [%s.%s.%s] DONE" % (
82 133
             registration_info['project_name'],
83 134
             registration_info['prog_name'],
84 135
             registration_info['identification']
85 136
         ))
86
-        self._regisgration_ackw(context,
87
-                                registration_info['identification'])
88 137
 
89
-        sp.cleanup(service_component_id)
138
+        # TODO(mrkanag) Move this to periofic task, before deleting each
139
+        # sw, make usre its created atleast 5 mins before
140
+        # sp.cleanup(service_component_id)
90 141
         return service_worker_id
91 142
 
92 143
     def _regisgration_ackw(self, context, identification):
93 144
         client = messaging.get_rpc_client(topic='namos.CONF.%s' %
94 145
                                                 identification,
95 146
                                           version=self.RPC_API_VERSION,
96
-                                          exchange=config.PROJECT_NAME)
147
+                                          exchange=namos_config.PROJECT_NAME)
97 148
         client.cast(context,
98 149
                     'regisgration_ackw',
99 150
                     identification=identification)
100 151
         LOG.info("REGISTER [%s] ACK" % identification)
101 152
 
102
-    def _ping(self, context, identification):
153
+    @request_context
154
+    def ping(self, context, identification):
103 155
         client = messaging.get_rpc_client(
104 156
             topic='namos.CONF.%s' % identification,
105 157
             version=self.RPC_API_VERSION,
106
-            exchange=config.PROJECT_NAME)
158
+            exchange=namos_config.PROJECT_NAME)
107 159
         try:
108 160
             client.call(context,
109 161
                         'ping_me',
110 162
                         identification=identification)
111 163
 
112
-            LOG.debug("PING [%s] SUCCESSFUL" % identification)
164
+            LOG.info("PING [%s] SUCCESSFUL" % identification)
113 165
             return True
114 166
         except:  # noqa
115
-            LOG.debug("PING [%s] FAILED" % identification)
167
+            LOG.info("PING [%s] FAILED" % identification)
116 168
             return False
117 169
 
118 170
     @request_context
@@ -169,8 +221,20 @@ class ConductorManager(object):
169 221
         return db_api.infra_perspective_get(context)
170 222
 
171 223
     @request_context
172
-    def view_360(self, context):
173
-        return db_api.view_360(context)
224
+    def view_360(self, context,
225
+                 include_conf_file=False,
226
+                 include_status=False,
227
+                 include_file_entry=False):
228
+        view = db_api.view_360(context, include_conf_file, include_status)
229
+        if include_file_entry:
230
+            view['config_file_entry'] = dict()
231
+            for f in list(view['config_file']):
232
+                view['config_file_entry'][f] = self.config_file_get(
233
+                    context,
234
+                    config_file_id=f
235
+                )['entry']
236
+
237
+        return view
174 238
 
175 239
     @request_context
176 240
     def config_get_by_name_for_service_worker(self,
@@ -183,8 +247,45 @@ class ConductorManager(object):
183 247
                                                             name,
184 248
                                                             only_configured)
185 249
 
250
+    @request_context
251
+    def get_status(self, context):
252
+        return db_api.get_status(context)
186 253
 
187
-class ServiceProcessor(object):
254
+    @request_context
255
+    def config_file_get(self, context, config_file_id):
256
+        file = db_api.config_file_get(context, config_file_id)
257
+
258
+        cfg_es = db_api.config_file_entry_get_all_by(
259
+            context,
260
+            oslo_config_file_id=config_file_id
261
+        )
262
+        return dict(file=file, entry=cfg_es)
263
+
264
+    @request_context
265
+    def config_schema(self, context, project, with_file_link=False):
266
+        # provide the manage oslo_config_schema --gen
267
+        file_schema = dict()
268
+        for cfg_s in db_api.config_schema_get_all_by(context, project=project):
269
+            if cfg_s.file_name not in file_schema:
270
+                file_schema[cfg_s.file_name] = dict()
271
+
272
+            if cfg_s.group_name not in file_schema[cfg_s.file_name]:
273
+                file_schema[cfg_s.file_name][cfg_s.group_name] = dict()
274
+
275
+            file_schema[cfg_s.file_name][cfg_s.group_name][cfg_s.name] = cfg_s
276
+
277
+            if with_file_link:
278
+                cfg_es = db_api.config_file_entry_get_all_by(
279
+                    context,
280
+                    oslo_config_schema_id=cfg_s.id
281
+                )
282
+                file_schema[cfg_s.file_name][cfg_s.group_name][
283
+                    cfg_s.name]['entries'] = cfg_es
284
+
285
+        return file_schema
286
+
287
+
288
+class RegionProcessor(object):
188 289
     def __init__(self,
189 290
                  context,
190 291
                  manager,
@@ -193,30 +294,7 @@ class ServiceProcessor(object):
193 294
         self.manager = manager
194 295
         self.context = context
195 296
 
196
-    def file_to_configs(self, file_content):
197
-        tmp_file_path = '/tmp/sample-namos-config.conf'
198
-        with open(tmp_file_path, 'w') as file:
199
-            file.write(file_content)
200
-
201
-        with open(tmp_file_path, 'r') as file:
202
-            section = ''
203
-            conf_dict = dict()
204
-
205
-            for line in file:
206
-                if line.strip().startswith('['):
207
-                    section = line.replace('[', '').replace(']', '').strip()
208
-                    continue
209
-                if section:
210
-                    kv = line.strip().split('=')
211
-                    conf_dict[
212
-                        '%s::%s' % (section, kv[0].strip())] = None
213
-
214
-        import os
215
-        os.remove(tmp_file_path)
216
-
217
-        return conf_dict
218
-
219
-    def process_service(self, context):
297
+    def process_region(self):
220 298
         # region
221 299
         # If region is not provided, make it as belongs to namos's region
222 300
         if not self.registration_info.get('region_name'):
@@ -225,31 +303,46 @@ class ServiceProcessor(object):
225 303
 
226 304
         try:
227 305
             region = db_api.region_create(
228
-                context,
306
+                self.context,
229 307
                 dict(name=self.registration_info.get('region_name'))
230 308
             )
231 309
             LOG.info('Region %s is created' % region)
232 310
         except exception.AlreadyExist:
233 311
             region = db_api.region_get_by_name(
234
-                context,
312
+                self.context,
235 313
                 name=self.registration_info.get('region_name')
236 314
             )
237 315
             LOG.info('Region %s is existing' % region)
238 316
 
317
+        return region.id
318
+
319
+
320
+class ServiceProcessor(object):
321
+    def __init__(self,
322
+                 context,
323
+                 manager,
324
+                 region_id,
325
+                 registration_info):
326
+        self.registration_info = registration_info
327
+        self.manager = manager
328
+        self.context = context
329
+        self.region_id = region_id
330
+
331
+    def process_service(self):
239 332
         # Service Node
240 333
         try:
241 334
             # TODO(mrkanag) user proper node name instead of fqdn
242 335
             node = db_api.service_node_create(
243
-                context,
336
+                self.context,
244 337
                 dict(name=self.registration_info.get('fqdn'),
245 338
                      fqdn=self.registration_info.get('fqdn'),
246
-                     region_id=region.id))
247
-
339
+                     region_id=self.region_id,
340
+                     extra={'ips': self.registration_info.get('ips')}))
248 341
             LOG.info('Service node %s is created' % node)
249 342
         except exception.AlreadyExist:
250 343
             # TODO(mrkanag) is this to be region specifc search
251 344
             node = db_api.service_node_get_by_name(
252
-                context,
345
+                self.context,
253 346
                 self.registration_info.get('fqdn'))
254 347
             LOG.info('Service node %s is existing' % node)
255 348
 
@@ -257,7 +350,7 @@ class ServiceProcessor(object):
257 350
         try:
258 351
             s_id = 'b9c2549f-f685-4bc2-92e9-ba8af9c18591'
259 352
             service = db_api.service_create(
260
-                context,
353
+                self.context,
261 354
                 # TODO(mrkanag) use keystone python client and
262 355
                 # use real service id here
263 356
                 dict(name=self.registration_info.get('project_name'),
@@ -266,22 +359,24 @@ class ServiceProcessor(object):
266 359
             LOG.info('Service %s is created' % service)
267 360
         except exception.AlreadyExist:
268 361
             service = db_api.service_get_by_name(
269
-                context,
362
+                self.context,
270 363
                 self.registration_info.get('project_name'))
271 364
             LOG.info('Service %s is existing' % service)
272 365
 
273 366
         # Service Component
274 367
         try:
275 368
             service_component = db_api.service_component_create(
276
-                context,
369
+                self.context,
277 370
                 dict(name=self.registration_info['prog_name'],
278 371
                      node_id=node.id,
279
-                     service_id=service.id))
372
+                     service_id=service.id,
373
+                     type=namos_config.find_type(self.registration_info[
374
+                         'prog_name'])))
280 375
             LOG.info('Service Component %s is created' % service_component)
281 376
         except exception.AlreadyExist:
282 377
             service_components = \
283 378
                 db_api.service_component_get_all_by_node_for_service(
284
-                    context,
379
+                    self.context,
285 380
                     node_id=node.id,
286 381
                     service_id=service.id,
287 382
                     name=self.registration_info['prog_name']
@@ -295,7 +390,7 @@ class ServiceProcessor(object):
295 390
         # Service Worker
296 391
         try:
297 392
             service_worker = db_api.service_worker_create(
298
-                context,
393
+                self.context,
299 394
                 # TODO(mrkanag) Fix the name, device driver proper !
300 395
                 dict(name='%s@%s' % (self.registration_info['pid'],
301 396
                                      service_component.name),
@@ -307,36 +402,106 @@ class ServiceProcessor(object):
307 402
                      ))
308 403
             LOG.info('Service Worker %s is created' % service_worker)
309 404
         except exception.AlreadyExist:
405
+            service_worker = db_api.service_worker_get_all_by(
406
+                self.context,
407
+                pid=self.registration_info['identification'],
408
+                service_component_id=service_component.id
409
+            )[0]
310 410
             LOG.info('Service Worker %s is existing' %
311
-                     db_api.service_worker_get_all_by(
312
-                         context,
313
-                         pid=self.registration_info['identification'],
314
-                         service_component_id=service_component.id
315
-                     )[0])
411
+                     service_worker)
412
+
413
+        return service_component.id, service_worker.id
414
+
415
+    def cleanup(self, service_component_id):
416
+        # clean up the dead service workers
417
+        #  TODO(mrkanag) Make this into thread
418
+        service_workers = \
419
+            db_api.service_worker_get_all_by(
420
+                self.context,
421
+                service_component_id=service_component_id
422
+            )
423
+
424
+        for srv_wkr in service_workers:
425
+            # TODO(mrkanag) Move this to db layer and query non deleted entries
426
+            if srv_wkr.deleted_at is not None:
427
+                continue
428
+
429
+            # TODO(mrkanag) is this interval ok
430
+            if utils.find_status(srv_wkr, report_interval=60):
431
+                LOG.info('Service Worker %s is live'
432
+                         % srv_wkr.id)
433
+                continue
434
+            else:
435
+                confs = db_api.config_get_by_name_for_service_worker(
436
+                    self.context,
437
+                    service_worker_id=srv_wkr.id
438
+                )
439
+
440
+                for conf in confs:
441
+                    db_api.config_delete(self.context, conf.id)
442
+                    LOG.info('Config %s is deleted'
443
+                             % conf.id)
444
+
445
+                db_api.service_worker_delete(self.context, srv_wkr.id)
446
+                LOG.info('Service Worker %s is deleted'
447
+                         % srv_wkr.id)
448
+
449
+
450
+class ConfigProcessor(object):
451
+    def __init__(self, context, manager, registration_info, service_worker_id):
452
+        self.context = context
453
+        self.manager = manager
454
+        self.registration_info = registration_info
455
+        self.service_worker_id = service_worker_id
456
+        self.service_component_id = db_api.service_worker_get(
457
+            self.context,
458
+            self.service_worker_id).service_component_id
459
+        sc = db_api.service_component_get(
460
+            self.context,
461
+            self.service_component_id
462
+        )
463
+        self.service_node_id = sc.node_id
464
+        self.project = db_api.service_get(self.context, sc.service_id).name
316 465
 
466
+    def file_to_configs(self, file_content):
467
+        import uuid
468
+        tmp_file_path = '/tmp/%s.conf' % str(uuid.uuid4())
469
+        with open(tmp_file_path, 'w') as file:
470
+            file.write(file_content)
471
+
472
+        conf_dict = utils.file_to_configs(tmp_file_path)
473
+
474
+        import os
475
+        os.remove(tmp_file_path)
476
+
477
+        return conf_dict
478
+
479
+    def _form_config_name(self, group, key):
480
+        return '%s.%s' % (group, key)
481
+
482
+    def process_config_files(self):
317 483
         # config file
318
-        conf_files = dict()
319
-        for cfg_f in self.registration_info['config_file_list']:
484
+        conf_name_to_file_id = dict()
485
+        for cfg_f in self.registration_info['config_file_dict'].keys():
320 486
             try:
321 487
                 config_file = db_api.config_file_create(
322
-                    context,
488
+                    self.context,
323 489
                     dict(name=cfg_f,
324 490
                          file=self.registration_info[
325 491
                              'config_file_dict'][cfg_f],
326
-                         service_component_id=service_component.id,
327
-                         service_node_id=node.id))
492
+                         service_node_id=self.service_node_id))
328 493
                 LOG.info('Oslo config file %s is created' % config_file)
329 494
             except exception.AlreadyExist:
330 495
                 config_files = \
331 496
                     db_api.config_file_get_by_name_for_service_node(
332
-                        context,
333
-                        service_node_id=node.id,
497
+                        self.context,
498
+                        service_node_id=self.service_node_id,
334 499
                         name=cfg_f
335 500
                     )
336 501
                 if len(config_files) == 1:
337 502
                     config_file = \
338 503
                         db_api.config_file_update(
339
-                            context,
504
+                            self.context,
340 505
                             config_files[0].id,
341 506
                             dict(file=self.registration_info[
342 507
                                 'config_file_dict'][cfg_f]))
@@ -344,126 +509,208 @@ class ServiceProcessor(object):
344 509
                              % config_file)
345 510
 
346 511
             config_dict = self.file_to_configs(
347
-                self.registration_info['config_file_dict'][cfg_f]
512
+                config_file.file
348 513
             )
349 514
 
350
-            conf_files[config_file.id] = config_dict
515
+            # config file entry
516
+            for grp, keys in config_dict.items():
517
+                for key, value in keys.items():
518
+                    # find config schema
519
+                    cfg_schs = db_api.config_schema_get_by(
520
+                        context=self.context,
521
+                        group=grp,
522
+                        name=key,
523
+                        project=self.project
524
+                    )
525
+
526
+                    cfg_sche = None
527
+                    if len(cfg_schs) == 0:
528
+                        LOG.debug("[%s] No Config Schema is existing, so "
529
+                                  "no schema is associated for Config Entry "
530
+                                  "%s::%s" %
531
+                                  (self.service_component_id,
532
+                                   grp,
533
+                                   key))
534
+                    elif len(cfg_schs) > 1:
535
+                        LOG.debug("[%s] More than one Config Schema is "
536
+                                  "existing, so no schema is associated for "
537
+                                  "Config Entry %s::%s" %
538
+                                  (self.service_component_id,
539
+                                   grp,
540
+                                   key))
541
+                    else:
542
+                        cfg_sche = cfg_schs[0]
543
+                        LOG.debug("[%s] Config Schema %s is existing and is "
544
+                                  "used to associated for Config Entry"
545
+                                  " %s::%s" %
546
+                                  (self.service_component_id,
547
+                                   cfg_sche.id,
548
+                                   grp,
549
+                                   key))
550
+
551
+                    # config file entry
552
+                    cfg_name = self._form_config_name(grp, key)
553
+
554
+                    cfg_obj_ = dict(
555
+                        service_component_id=self.service_component_id,
556
+                        name=cfg_name,
557
+                        value=value,
558
+                        oslo_config_schema_id=cfg_sche.id if
559
+                        cfg_sche else None,
560
+                        oslo_config_file_id=config_file.id
561
+                    )
351 562
 
563
+                    try:
564
+                        config = db_api.config_file_entry_create(
565
+                            self.context,
566
+                            cfg_obj_)
567
+                        LOG.debug("Config Entry %s is created" % config)
568
+                    except exception.AlreadyExist:
569
+                        configs = db_api.config_file_entry_get_all_by(
570
+                            self.context,
571
+                            service_component_id=cfg_obj_[
572
+                                'service_component_id'],
573
+                            oslo_config_file_id=config_file.id,
574
+                            name=cfg_obj_['name'])
575
+                        if len(configs) == 1:
576
+                            config = db_api.config_file_entry_update(
577
+                                self.context,
578
+                                configs[0].id,
579
+                                cfg_obj_)
580
+                            LOG.debug("Config Entry %s is existing and is "
581
+                                      "updated" % config)
582
+
583
+                    conf_name_to_file_id[cfg_name] = config.id
584
+
585
+        return conf_name_to_file_id
586
+
587
+    def process_configs(self):
588
+        conf_name_to_file_id = self.process_config_files()
352 589
         # Config
353
-        # TODO(mrkanag) Optimize the config like per service_component
354
-        # or per service_worker,
355
-        for cfg_name, cfg_obj in self.registration_info[
356
-            'config_dict'].iteritems():
357
-
358
-            cfg_schs = db_api.config_schema_get_by(
359
-                context=context,
360
-                group=cfg_obj['group'],
361
-                name=cfg_obj['name']
362
-            )
590
+        for cfg_obj in self.registration_info['config_list']:
591
+            # This format is used by DriverProcessor
592
+            cfg_name = self._form_config_name(cfg_obj['group'],
593
+                                              cfg_obj['name'])
594
+
595
+            if not conf_name_to_file_id.get(cfg_name):
596
+                cfg_schm_id = None
597
+                cfg_f_entry = None
598
+
599
+                # find config schema
600
+                # ignore the config file_name right now !!, assumed conf unique
601
+                # across the service wth given group and name
602
+                cfg_schs = db_api.config_schema_get_by(
603
+                    context=self.context,
604
+                    group=cfg_obj['group'],
605
+                    name=cfg_obj['name'],
606
+                    project=self.project
607
+                )
363 608
 
364
-            if len(cfg_schs) > 1:
365
-                cfg_sche = cfg_schs[0]
366
-                LOG.debug("Config Schema %s is existing and is updated" %
367
-                          cfg_sche)
368
-            else:
369
-                try:
370
-                    cfg_sche = db_api.config_schema_create(
371
-                        context,
372
-                        dict(
373
-                            namespace='UNKNOWN-NAMOS',
374
-                            default_value=cfg_obj['default_value'],
375
-                            type=cfg_obj['type'],
376
-                            help=cfg_obj['help'],
377
-                            required=cfg_obj['required'],
378
-                            secret=cfg_obj['secret'],
379
-                            mutable=False,
380
-                            group_name=cfg_obj['group'],
381
-                            name=cfg_obj['name']
382
-                        )
383
-                    )
384
-                    LOG.debug("Config Schema %s is created" % cfg_sche)
385
-                except exception.AlreadyExist:
386
-                    cfg_schs = db_api.config_schema_get_by(
387
-                        context=context,
388
-                        group=cfg_obj['group'],
389
-                        name=cfg_obj['name'],
390
-                        namespace='UNKNOWN-NAMOS'
391
-                    )
609
+                if len(cfg_schs) == 0:
610
+                    LOG.debug("[%s] No Config Schema is existing, so "
611
+                              "no schema is associated for Config %s::%s" %
612
+                              (self.service_worker_id,
613
+                               cfg_obj['group'],
614
+                               cfg_obj['name']))
615
+                elif len(cfg_schs) > 1:
616
+                    LOG.debug("[%s] More than one Config Schema is existing, "
617
+                              "so no schema is associated for Config %s::%s" %
618
+                              (self.service_worker_id,
619
+                               cfg_obj['group'],
620
+                               cfg_obj['name']))
621
+                else:
622
+                    # try:
623
+                    #     cfg_sche = db_api.config_schema_create(
624
+                    #         self.context,
625
+                    #         dict(
626
+                    #             namespace='UNKNOWN-tagged-by-NAMOS',
627
+                    #             default_value=cfg_obj['default_value'],
628
+                    #             type=cfg_obj['type'],
629
+                    #             help=cfg_obj['help'],
630
+                    #             required=cfg_obj['required'],
631
+                    #             secret=cfg_obj['secret'],
632
+                    #             mutable=False,
633
+                    #             group_name=cfg_obj['group'],
634
+                    #             name=cfg_obj['name']
635
+                    #         )
636
+                    #     )
637
+                    #     LOG.info("Config Schema %s is created" % cfg_sche)
638
+                    # except exception.AlreadyExist:
639
+                    #     cfg_schs = db_api.config_schema_get_by(
640
+                    #         context=self.context,
641
+                    #         group=cfg_obj['group'],
642
+                    #         name=cfg_obj['name'],
643
+                    #         namespace='UNKNOWN-tagged-by-NAMOS'
644
+                    #     )
392 645
 
393 646
                     cfg_sche = cfg_schs[0]
394
-                    LOG.debug("Config Schema %s is existing and is updated" %
395
-                              cfg_sche)
396
-
397
-            # is it part of config file
398
-            cfg_name = "%s::%s" % (cfg_obj['group'], cfg_name)
399
-            file_id = None
400
-            for f_id, conf_keys in conf_files.items():
401
-                if cfg_name in conf_keys.keys():
402
-                    file_id = f_id
403
-                    break
647
+                    LOG.debug("[%s] Config Schema %s is existing and is used "
648
+                              "for Config %s::%s" %
649
+                              (self.service_worker_id,
650
+                               cfg_sche.id,
651
+                               cfg_obj['group'],
652
+                               cfg_obj['name']))
653
+                    cfg_schm_id = cfg_sche.id
654
+            else:
655
+                cfg_schm_id = None
656
+                cfg_f_entry = conf_name_to_file_id[cfg_name]
657
+
658
+            # config_file_entry_id = None
659
+            # for f_id, conf_groups in conf_name_to_file_id.items():
660
+            #     if cfg_obj['group'] in list(conf_groups):
661
+            #         if cfg_obj['name'] in list(conf_groups[cfg_obj[
662
+            #            'group']]):
663
+            #             config_entrys=db_api.config_file_entry_get_all_by(
664
+            #                 self.context,
665
+            #                 service_component_id=self.service_component_id,
666
+            #                 oslo_config_file_id=f_id,
667
+            #                 name=cfg_name)
668
+            #             if len(config_entrys) == 1:
669
+            #                 config_file_entry_id = config_entrys[0].id
670
+            #
671
+            #             break
404 672
 
405 673
             cfg_obj_ = dict(
406
-                service_worker_id=service_worker.id,
674
+                service_worker_id=self.service_worker_id,
407 675
                 name=cfg_name,
408
-                value=cfg_obj['value'],
409
-                oslo_config_schema_id=cfg_sche.id,
410
-                oslo_config_file_id=file_id
676
+                value=cfg_obj['value'] if cfg_obj['value'] else cfg_obj[
677
+                    'default_value'],
678
+                oslo_config_schema_id=cfg_schm_id,
679
+                oslo_config_file_entry_id=cfg_f_entry
411 680
             )
412 681
 
413 682
             try:
414
-                config = db_api.config_create(context, cfg_obj_)
683
+                config = db_api.config_create(self.context, cfg_obj_)
415 684
                 LOG.debug("Config %s is created" % config)
416 685
             except exception.AlreadyExist:
417 686
                 configs = db_api.config_get_by_name_for_service_worker(
418
-                    context,
687
+                    self.context,
419 688
                     service_worker_id=cfg_obj_['service_worker_id'],
420 689
                     name=cfg_obj_['name'])
421 690
                 if len(configs) == 1:
422
-                    config = db_api.config_update(context,
691
+                    config = db_api.config_update(self.context,
423 692
                                                   configs[0].id,
424 693
                                                   cfg_obj_)
425 694
                     LOG.debug("Config %s is existing and is updated" % config)
426 695
 
427
-        return service_component.id, service_worker.id
428
-
429
-    def cleanup(self, service_component_id):
430
-        # clean up the dead service workers
431
-        #  TODO(mrkanag) Make this into thread
432
-        service_workers = \
433
-            db_api.service_worker_get_all_by(
434
-                context,
435
-                service_component_id=service_component_id
436
-            )
437
-
438
-        for srv_wkr in service_workers:
439
-            # TODO(mrkanag) Move this to db layer and query non deleted entries
440
-            if srv_wkr.deleted_at is not None:
441
-                continue
442
-
443
-            if utils.find_status(srv_wkr):
444
-                LOG.info('Service Worker %s is live'
445
-                         % srv_wkr.id)
446
-                continue
447
-            else:
448
-                confs = db_api.config_get_by_name_for_service_worker(
449
-                    self.context,
450
-                    service_worker_id=srv_wkr.id
451
-                )
452
-
453
-                for conf in confs:
454
-                    db_api.config_delete(self.context, conf.id)
455
-                    LOG.debug('Config %s is deleted'
456
-                              % conf.id)
457
-
458
-                db_api.service_worker_delete(self.context, srv_wkr.id)
459
-                LOG.info('Service Worker %s is deleted'
460
-                         % srv_wkr.id)
461
-
462 696
 
463 697
 class DriverProcessor(object):
464
-    def __init__(self, service_worker_id, config_dict):
465
-        self.config_dict = config_dict
698
+    def __init__(self, context, manager, service_worker_id, region_id):
699
+        self.context = context
700
+        self.manager = manager
466 701
         self.service_worker_id = service_worker_id
702
+        self.region_id = region_id
703
+        self.config_dict = self._get_config_dict()
704
+
705
+    def _get_config_dict(self):
706
+        conf_dict = {}
707
+        for c in db_api.config_get_by_name_for_service_worker(
708
+            self.context,
709
+            self.service_worker_id
710
+        ):
711
+            conf_dict[c.name] = c.to_dict()
712
+
713
+        return conf_dict
467 714
 
468 715
     def _identify_drivers(self):
469 716
         return (set(openstack_drivers.get_drivers_config().keys()) &
@@ -477,8 +724,7 @@ class DriverProcessor(object):
477 724
             # Constant naming
478 725
             if name[0] == '#':
479 726
                 return name[1:]
480
-            return (self.config_dict[name].get('value') or
481
-                    self.config_dict[name].get('default_value'))
727
+            return (self.config_dict[name].get('value'))
482 728
         elif isinstance(name, tuple):
483 729
             fn = name[0]
484 730
             args = list()
@@ -490,35 +736,13 @@ class DriverProcessor(object):
490 736
             params = [self._get_value(param) for param in name[1:]]
491 737
             return fmt_str % tuple(params)
492 738
 
493
-    @staticmethod
494
-    def _to_list(list_in_str):
495
-        def strip_out(s):
496
-            start_idx = 0
497
-            end_idx = len(s)
498
-            if s[start_idx] == '[' \
499
-                    or s[start_idx] == '\'' \
500
-                    or s[start_idx] == '"':
501
-                start_idx += 1
502
-            if s[end_idx - 1] == ']' \
503
-                    or s[end_idx - 1] == '\'' \
504
-                    or s[end_idx - 1] == '"':
505
-                end_idx -= 1
506
-            return s[start_idx:end_idx]
507
-
508
-        l = []
509
-        for s in strip_out(list_in_str.strip()).split(','):
510
-            s = str(strip_out(s.strip()))
511
-            l.append(s)
512
-
513
-        return l
514
-
515
-    def process_drivers(self, context):
739
+    def process_drivers(self):
516 740
         for driver_key in self._identify_drivers():
517 741
             try:
518 742
                 drivers = self._get_value(driver_key)
519
-                drivers = DriverProcessor._to_list(drivers)
743
+                drivers = utils._to_list(drivers)
520 744
                 for driver_name in drivers:
521
-                    self.process_driver(context, driver_key, driver_name)
745
+                    self.process_driver(driver_key, driver_name)
522 746
             except KeyError:  # noqa
523 747
                 # TODO(mrkanag) run namos-manager and restart nova-scheduler
524 748
                 # KeyError: 'libvirt.virt_type' is thrown, fix it
@@ -526,7 +750,7 @@ class DriverProcessor(object):
526 750
                           (driver_key, self.service_worker_id))
527 751
                 continue
528 752
 
529
-    def process_driver(self, context, driver_key, driver_name):
753
+    def process_driver(self, driver_key, driver_name):
530 754
             driver_config = \
531 755
                 openstack_drivers.get_drivers_config()[driver_key][driver_name]
532 756
 
@@ -587,18 +811,17 @@ class DriverProcessor(object):
587 811
             # Device
588 812
             device_name = self._get_value(device_cfg['name'])
589 813
             try:
590
-                # TODO(mrkanag) region_id is hard-coded, fix it !
591
-                # Set the right status as well
814
+                # TODO(mrkanag) Set the right status
592 815
                 device = db_api.device_create(
593
-                    context,
816
+                    self.context,
594 817
                     dict(name=device_name,
595 818
                          status='active',
596
-                         region_id='f7dcd175-27ef-46b5-997f-e6e572f320b0'))
819
+                         region_id=self.region_id))
597 820
 
598 821
                 LOG.info('Device %s is created' % device)
599 822
             except exception.AlreadyExist:
600 823
                 device = db_api.device_get_by_name(
601
-                    context,
824
+                    self.context,
602 825
                     device_name)
603 826
                 LOG.info('Device %s is existing' % device)
604 827
 
@@ -609,7 +832,7 @@ class DriverProcessor(object):
609 832
                     d_name = '%s-%s' % (base_name, d_name)
610 833
                     try:
611 834
                         device = db_api.device_get_by_name(
612
-                            context,
835
+                            self.context,
613 836
                             d_name)
614 837
                         LOG.info('Device %s is existing' % device)
615 838
                     except exception.DeviceNotFound:
@@ -617,7 +840,7 @@ class DriverProcessor(object):
617 840
                         # Set the right status as well
618 841
                         r_id = 'f7dcd175-27ef-46b5-997f-e6e572f320b0'
619 842
                         device = db_api.device_create(
620
-                            context,
843
+                            self.context,
621 844
                             dict(name=d_name,
622 845
                                  status='active',
623 846
                                  parent_id=device.id,
@@ -631,7 +854,7 @@ class DriverProcessor(object):
631 854
                     connection[k] = self._get_value(k)
632 855
 
633 856
                 device_endpoint = db_api.device_endpoint_create(
634
-                    context,
857
+                    self.context,
635 858
                     dict(name=device_endpoint_name,
636 859
                          connection=connection,
637 860
                          type=endpoint_type,
@@ -639,7 +862,7 @@ class DriverProcessor(object):
639 862
                 LOG.info('Device Endpoint %s is created' % device_endpoint)
640 863
             except exception.AlreadyExist:
641 864
                 device_endpoints = db_api.device_endpoint_get_by_device_type(
642
-                    context,
865
+                    self.context,
643 866
                     device_id=device.id,
644 867
                     type=endpoint_type,
645 868
                     name=device_endpoint_name)
@@ -651,7 +874,7 @@ class DriverProcessor(object):
651 874
             # Device Driver Class
652 875
             try:
653 876
                 device_driver_class = db_api.device_driver_class_create(
654
-                    context,
877
+                    self.context,
655 878
                     dict(name=driver_name,
656 879
                          python_class=driver_name,
657 880
                          type=driver_def['type'],
@@ -663,7 +886,7 @@ class DriverProcessor(object):
663 886
                          device_driver_class)
664 887
             except exception.AlreadyExist:
665 888
                 device_driver_class = db_api.device_driver_class_get_by_name(
666
-                    context,
889
+                    self.context,
667 890
                     driver_name)
668 891
                 LOG.info('Device Driver Class %s is existing' %
669 892
                          device_driver_class)
@@ -671,7 +894,7 @@ class DriverProcessor(object):
671 894
             # Device Driver
672 895
             try:
673 896
                 device_driver = db_api.device_driver_create(
674
-                    context,
897
+                    self.context,
675 898
                     dict(device_id=device.id,
676 899
                          name=driver_name,
677 900
                          endpoint_id=device_endpoint.id,
@@ -683,7 +906,7 @@ class DriverProcessor(object):
683 906
             except exception.AlreadyExist:
684 907
                 device_drivers = \
685 908
                     db_api.device_driver_get_by_device_endpoint_service_worker(
686
-                        context,
909
+                        self.context,
687 910
                         device_id=device.id,
688 911
                         endpoint_id=device_endpoint.id,
689 912
                         device_driver_class_id=device_driver_class.id,

+ 110
- 19
namos/conductor/rpcapi.py View File

@@ -61,19 +61,73 @@ class ConductorAPI(object):
61 61
 
62 62
     @wrapper_function
63 63
     def add_region(self, context, region):
64
-        self.client.call(context, 'add_region', region=region)
64
+        return self.client.call(
65
+            context,
66
+            'region_create',
67
+            region=region)
68
+
69
+    @wrapper_function
70
+    def region_get(self, context, region_id):
71
+        return self.client.call(
72
+            context,
73
+            'region_get',
74
+            region_id=region_id)
75
+
76
+    @wrapper_function
77
+    def region_update(self, context, region_id, region):
78
+        return self.client.call(
79
+            context,
80
+            'region_update',
81
+            region_id=region_id,
82
+            region=region)
65 83
 
66 84
     @wrapper_function
67 85
     def region_get_all(self, context):
68
-        return self.client.call(context, 'region_get_all')
86
+        return self.client.call(
87
+            context,
88
+            'region_get_all')
69 89
 
70 90
     @wrapper_function
71
-    def service_perspective_get(self, context, service_id,
72
-                                include_details=False):
73
-        return self.client.call(context,
74
-                                'service_perspective_get',
75
-                                service_id=service_id,
76
-                                include_details=include_details)
91
+    def region_delete(self, context, region_id):
92
+        return self.client.call(
93
+            context,
94
+            'region_delete',
95
+            region_id=region_id)
96
+
97
+    @wrapper_function
98
+    def add_service_node(self, context, service_node):
99
+        return self.client.call(
100
+            context,
101
+            'service_node_create',
102
+            service_node=service_node)
103
+
104
+    @wrapper_function
105
+    def service_node_get(self, context, service_node_id):
106
+        return self.client.call(
107
+            context,
108
+            'service_node_get',
109
+            service_node_id=service_node_id)
110
+
111
+    @wrapper_function
112
+    def service_node_update(self, context, service_node_id, service_node):
113
+        return self.client.call(
114
+            context,
115
+            'service_node_update',
116
+            service_node_id=service_node_id,
117
+            service_node=service_node)
118
+
119
+    @wrapper_function
120
+    def service_node_get_all(self, context):
121
+        return self.client.call(
122
+            context,
123
+            'service_node_get_all')
124
+
125
+    @wrapper_function
126
+    def service_node_delete(self, context, service_node_id):
127
+        return self.client.call(
128
+            context,
129
+            'service_node_delete',
130
+            service_node_id=service_node_id)
77 131
 
78 132
     @wrapper_function
79 133
     def device_perspective_get(self, context, device_id,
@@ -97,9 +151,15 @@ class ConductorAPI(object):
97 151
                                 'infra_perspective_get')
98 152
 
99 153
     @wrapper_function
100
-    def view_360(self, context):
154
+    def view_360(self, context,
155
+                 include_conf_file=False,
156
+                 include_status=False,
157
+                 include_file_entry=False):
101 158
         return self.client.call(context,
102
-                                'view_360')
159
+                                'view_360',
160
+                                include_conf_file=include_conf_file,
161
+                                include_status=include_status,
162
+                                include_file_entry=include_file_entry)
103 163
 
104 164
     @wrapper_function
105 165
     def config_get_by_name_for_service_worker(self,
@@ -113,6 +173,31 @@ class ConductorAPI(object):
113 173
                                 name=name,
114 174
                                 only_configured=only_configured)
115 175
 
176
+    @wrapper_function
177
+    def get_status(self, context):
178
+        return self.client.call(context,
179
+                                'get_status')
180
+
181
+    @wrapper_function
182
+    def ping(self, context, identification):
183
+        return self.client.call(context,
184
+                                'ping',
185
+                                identification=identification)
186
+
187
+    @wrapper_function
188
+    def config_file_get(self, context, config_file_id):
189
+        return self.client.call(context,
190
+                                'config_file_get',
191
+                                config_file_id=config_file_id)
192
+
193
+    @wrapper_function
194
+    def config_schema(self, context, project, with_file_link=False):
195
+        return self.client.call(context,
196
+                                'config_schema',
197
+                                project=project,
198
+                                with_file_link=with_file_link)
199
+
200
+
116 201
 if __name__ == '__main__':
117 202
     # from namos.common import config
118 203
 
@@ -134,13 +219,19 @@ if __name__ == '__main__':
134 219
         print (json.dumps(c.infra_perspective_get(context.RequestContext())))
135 220
 
136 221
     def print_view_360():
137
-        print (json.dumps(c.view_360(context.RequestContext())))
138
-
139
-    def print_sample_conf():
140
-        for cf in c.config_get_by_name_for_service_worker(
141
-            context.RequestContext(),
142
-            service_worker_id='06e64e74-09b3-4721-8e5d-39ae40ed34f3'):
143
-            print ('%s %s' % (cf['name'], cf['value']))
144
-
222
+        with open('/tmp/view_360.json', 'w') as file:
223
+            view = c.view_360(context.RequestContext(), True, True, True)
224
+            file.write(json.dumps(view))
225
+
226
+    def print_config_schema():
227
+        for s in ['nova', 'cinder', 'glance', 'neutron', 'heat', 'namos',
228
+                  'keystone', 'ceilometer', 'tacker']:
229
+            with open('/tmp/config_schema_%s.json' % s, 'w') as file:
230
+                file.write(json.dumps(c.config_schema(
231
+                    context.RequestContext(),
232
+                    project=s,
233
+                    with_file_link=True
234
+                )))
235
+
236
+    print_config_schema()
145 237
     print_view_360()
146
-    # print_sample_conf()

+ 43
- 4
namos/db/api.py View File

@@ -312,6 +312,34 @@ def service_worker_delete(context, _id):
312 312
     return IMPL.service_worker_delete(context, _id)
313 313
 
314 314
 
315
+def config_file_entry_create(context, values):
316
+    return IMPL.config_file_entry_create(context, values)
317
+
318
+
319
+def config_file_entry_update(context, _id, values):
320
+    return IMPL.config_file_entry_update(context, _id, values)
321
+
322
+
323
+def config_file_entry_get(context, _id):
324
+    return IMPL.config_file_entry_get(context, _id)
325
+
326
+
327
+def config_file_entry_get_by_name(context, name):
328
+    return IMPL.config_file_entry_get_by_name(context, name)
329
+
330
+
331
+def config_file_entry_get_all(context):
332
+    return IMPL.config_file_entry_get_all(context)
333
+
334
+
335
+def config_file_entry_get_all_by(context, **kwargs):
336
+    return IMPL.config_file_entry_get_all_by(context, **kwargs)
337
+
338
+
339
+def config_file_entry_delete(context, _id):
340
+    return IMPL.config_file_entry_delete(context, _id)
341
+
342
+
315 343
 #  config schema
316 344
 def config_schema_create(context, values):
317 345
     return IMPL.config_schema_create(context, values)
@@ -332,14 +360,19 @@ def config_schema_get_by_name(context, name):
332 360
 def config_schema_get_by(context,
333 361
                          namespace=None,
334 362
                          group=None,
335
-                         name=None):
336
-    return IMPL.config_schema_get_by(context, namespace, group, name)
363
+                         name=None,
364
+                         project=None):
365
+    return IMPL.config_schema_get_by(context, namespace, group, name, project)
337 366
 
338 367
 
339 368
 def config_schema_get_all(context):
340 369
     return IMPL.config_schema_get_all(context)
341 370
 
342 371
 
372
+def config_schema_get_all_by(context, **kwargs):
373
+    return IMPL.config_schema_get_all_by(context, **kwargs)
374
+
375
+
343 376
 def config_schema_delete(context, _id):
344 377
     return IMPL.config_schema_delete(context, _id)
345 378
 
@@ -440,5 +473,11 @@ def infra_perspective_get(context):
440 473
     return IMPL.infra_perspective_get(context)
441 474
 
442 475
 
443
-def view_360(context):
444
-    return IMPL.view_360(context)
476
+def view_360(context, include_conf_file=False, include_status=False):
477
+    return IMPL.view_360(context,
478
+                         include_conf_file=include_conf_file,
479
+                         include_status=include_status)
480
+
481
+
482
+def get_status(context):
483
+    return IMPL.get_status(context)

+ 11
- 4
namos/db/sqlalchemy/alembic/versions/48ebec3cd6f6_initial_version.py View File

@@ -178,14 +178,21 @@ def upgrade():
178 178
 
179 179
 def downgrade():
180 180
     op.drop_table('oslo_config')
181
+    op.drop_table('oslo_config_file_entry')
181 182
     op.drop_table('oslo_config_file')
182 183
     op.drop_table('oslo_config_schema')
184
+
185
+    op.drop_table('os_capability')
186
+    op.drop_table('os_capability_schema')
187
+
183 188
     op.drop_table('device_driver')
189
+    op.drop_table('device_endpoint')
190
+    op.drop_table('device_driver_class')
191
+    op.drop_table('device')
192
+
184 193
     op.drop_table('service_worker')
185 194
     op.drop_table('service_component')
186
-    op.drop_table('device_endpoint')
187 195
     op.drop_table('service_node')
188
-    op.drop_table('device')
189
-    op.drop_table('region')
190
-    op.drop_table('device_driver_class')
191 196
     op.drop_table('service')
197
+
198
+    op.drop_table('region')

+ 109
- 9
namos/db/sqlalchemy/api.py View File

@@ -20,6 +20,7 @@ from oslo_db import exception as db_exception
20 20
 from oslo_db.sqlalchemy import session as db_session
21 21
 
22 22
 from namos.common import exception
23
+from namos.common import utils
23 24
 from namos.db.sqlalchemy import models
24 25
 
25 26
 
@@ -439,6 +440,8 @@ def service_component_get_all_by_node_for_service(context,
439 440
         query = query.filter_by(service_id=service_id)
440 441
     if name is not None:
441 442
         query = query.filter_by(name=name)
443
+
444
+    query = query.order_by(models.ServiceComponent.type)
442 445
     return query.all()
443 446
 
444 447
 
@@ -487,6 +490,7 @@ def service_worker_get_by_host_for_service_component(context,
487 490
         filter_by(service_component_id=service_component_id)
488 491
     if host is not None:
489 492
         query = query.filter_by(host=host)
493
+
490 494
     return query.all()
491 495
 
492 496
 
@@ -532,10 +536,12 @@ def config_schema_get_by_name(context, name):
532 536
     return config
533 537
 
534 538
 
539
+# TODO(mrkanag) fix it to take **kwargs
535 540
 def config_schema_get_by(context,
536 541
                          namespace=None,
537 542
                          group=None,
538
-                         name=None):
543
+                         name=None,
544
+                         project=None):
539 545
     query = _model_query(context, models.OsloConfigSchema)
540 546
     if name is not None:
541 547
         query = query.filter_by(name=name)
@@ -543,6 +549,9 @@ def config_schema_get_by(context,
543 549
         query = query.filter_by(group_name=group)
544 550
     if namespace is not None:
545 551
         query = query.filter_by(namespace=namespace)
552
+    if project is not None:
553
+        query = query.filter_by(project=project)
554
+
546 555
     return query.all()
547 556
 
548 557
 
@@ -550,7 +559,7 @@ def config_schema_get_all(context):
550 559
     return _get_all(context, models.OsloConfigSchema)
551 560
 
552 561
 
553
-def _config_schema_get_all_by(context, **kwargs):
562
+def config_schema_get_all_by(context, **kwargs):
554 563
     return _get_all_by(context, models.OsloConfigSchema, **kwargs)
555 564
 
556 565
 
@@ -594,7 +603,7 @@ def config_get_by_name_for_service_worker(context,
594 603
         query = query.filter_by(name=name)
595 604
     elif only_configured:
596 605
         query = query.filter(
597
-            models.OsloConfig.oslo_config_file_id is not None)
606
+            models.OsloConfig.oslo_config_file_entry_id is not None)
598 607
     return query.all()
599 608
 
600 609
 
@@ -610,6 +619,44 @@ def config_delete(context, _id):
610 619
     return _delete(context, models.OsloConfig, _id)
611 620
 
612 621
 
622
+# Config File Entry
623
+
624
+def config_file_entry_create(context, values):
625
+    return _create(context, models.OsloConfigFileEntry(), values)
626
+
627
+
628
+def config_file_entry_update(context, _id, values):
629
+    return _update(context, models.OsloConfigFileEntry, _id, values)
630
+
631
+
632
+def config_file_entry_get(context, _id):
633
+    config_file_entry = _get(context, models.OsloConfigFileEntry, _id)
634
+    if config_file_entry is None:
635
+        raise exception.ConfigNotFound(config_file_entry_id=_id)
636
+
637
+    return config_file_entry
638
+
639
+
640
+def config_file_entry_get_by_name(context, name):
641
+    config_file_entry = _get_by_name(context, models.OsloConfigFileEntry, name)
642
+    if config_file_entry is None:
643
+        raise exception.ConfigNotFound(config_file_entry_id=name)
644
+
645
+    return config_file_entry
646
+
647
+
648
+def config_file_entry_get_all(context):
649
+    return _get_all(context, models.OsloConfigFileEntry)
650
+
651
+
652
+def config_file_entry_get_all_by(context, **kwargs):
653
+    return _get_all_by(context, models.OsloConfigFileEntry, **kwargs)
654
+
655
+
656
+def config_file_entry_delete(context, _id):
657
+    return _delete(context, models.OsloConfigFileEntry, _id)
658
+
659
+
613 660
 # Config file
614 661
 def config_file_create(context, values):
615 662
     return _create(context, models.OsloConfigFile(), values)
@@ -647,6 +694,18 @@ def config_file_get_by_name_for_service_node(
647 694
     return query.all()
648 695
 
649 696
 
697
+def _config_file_id_get_for_service_component(context, service_component_id):
698
+    entries = config_file_entry_get_all_by(
699
+        context,
700
+        service_component_id=service_component_id)
701
+    files = []
702
+    for e in entries:
703
+        if e.oslo_config_file_id not in files:
704
+            files.append(e.oslo_config_file_id)
705
+
706
+    return files
707
+
708
+
650 709
 def config_file_get_all(context):
651 710
     return _get_all(context, models.OsloConfigFile)
652 711
 
@@ -889,7 +948,7 @@ def infra_perspective_get(context):
889 948
     return infra_perspective
890 949
 
891 950
 
892
-def view_360(context):
951
+def view_360(context, include_conf_file=False, include_status=False):
893 952
     view = dict()
894 953
 
895 954
     view['region'] = dict()
@@ -901,6 +960,8 @@ def view_360(context):
901 960
     view['device_driver_class'] = dict()
902 961
     view['device_endpoint'] = dict()
903 962
     view['device'] = dict()
963
+    view['config_file'] = dict()
964
+    view['status'] = dict()
904 965
 
905 966
     region_list = region_get_all(context)
906 967
     for rg in region_list:
@@ -940,15 +1001,23 @@ def view_360(context):
940 1001
                     'service_component'][srv_cmp.id] = dict()
941 1002
                 view['region'][rg.id]['service_node'][srv_nd.id][
942 1003
                     'service_component'][srv_cmp.id]['config_file'] = dict()
943
-                cfg_fl_lst = config_file_get_by_name_for_service_node(
1004
+                cfg_fl_lst = _config_file_id_get_for_service_component(
944 1005
                     context,
945
-                    service_node_id=srv_nd.id
1006
+                    service_component_id=srv_cmp.id
946 1007
                 )
947
-                for cfg_fl in cfg_fl_lst:
1008
+                for cfg_fl_id in cfg_fl_lst:
948 1009
                     # config file
1010
+                    if include_conf_file:
1011
+                        view['config_file'][cfg_fl_id] = config_file_get(
1012
+                            context,
1013
+                            cfg_fl_id
1014
+                        )
1015
+                    else:
1016
+                        view['config_file'][cfg_fl_id] = dict()
1017
+
949 1018
                     view['region'][rg.id]['service_node'][srv_nd.id][
950 1019
                         'service_component'][srv_cmp.id][
951
-                        'config_file'][cfg_fl.name] = cfg_fl.file
1020
+                        'config_file'][cfg_fl_id] = dict()
952 1021
 
953 1022
                 view['region'][rg.id]['service_node'][srv_nd.id][
954 1023
                     'service_component'][srv_cmp.id]['service'] = srv_id
@@ -1025,8 +1094,39 @@ def view_360(context):
1025 1094
                                 'service_worker'][srv_wkr.id]['device_driver'][
1026 1095
                                 dvc_drv.id]['device'] = dvc_id
1027 1096
 
1097
+    if include_status:
1098
+        view['status'] = get_status(context)
1099
+
1028 1100
     return view
1029 1101
 
1102
+
1103
+def get_status(context):
1104
+    sr = {}
1105
+    for sn in service_node_get_all(context):
1106
+        for sc in service_component_get_all_by_node_for_service(
1107
+            context,
1108
+            node_id=sn.id
1109
+        ):
1110
+            service = service_get(context, sc.service_id)
1111
+            for sw in service_worker_get_by_host_for_service_component(
1112
+                context,
1113
+                service_component_id=sc.id
1114
+            ):
1115
+                # TODO(mrkanag) Move this to db layer and query non deleted
1116
+                # if sw.deleted_at is not None:
1117
+                #     continue
1118
+
1119
+                sr[sw.pid] = (
1120
+                    dict(node=sn.name,
1121
+                         type=sc.type,
1122
+                         service=service.name,
1123
+                         component=sw.name,
1124
+                         status=utils.find_status(sw),
1125
+                         is_launcher=sw.is_launcher))
1126
+
1127
+    return sr
1128
+
1129
+
1030 1130
 if __name__ == '__main__':
1031 1131
     from namos.common import config
1032 1132
 
@@ -1053,4 +1153,4 @@ if __name__ == '__main__':
1053 1153
     # print perp_json
1054 1154
 
1055 1155
     import json
1056
-    print (json.dumps(view_360(None)))
1156
+    print (json.dumps(view_360(None, True, True)))

+ 138
- 18
namos/db/sqlalchemy/models.py View File

@@ -257,6 +257,8 @@ class ServiceComponent(BASE,
257 257
         Uuid,
258 258
         sqlalchemy.ForeignKey('service.id'),
259 259
         nullable=False)
260
+    type = sqlalchemy.Column(sqlalchemy.String(255),
261
+                             nullable=False)
260 262
 
261 263
 
262 264
 class ServiceWorker(BASE,
@@ -302,7 +304,11 @@ class OsloConfigSchema(BASE,
302 304
     # TODO(mrkanag) Check whether conf is unique across all services or only
303 305
     # sepcific to namespace, otherwise uniqueconstraint is name, group_name
304 306
     __table_args__ = (
305
-        UniqueConstraint("group_name", "name", "namespace"),
307
+        UniqueConstraint("group_name",
308
+                         "name",
309
+                         "namespace",
310
+                         "project",
311
+                         "file_name"),
306 312
     )
307 313
 
308 314
     name = sqlalchemy.Column(sqlalchemy.String(255),
@@ -327,6 +333,15 @@ class OsloConfigSchema(BASE,
327 333
         sqlalchemy.String(128),
328 334
         nullable=False
329 335
     )
336
+    # This column helps to keep schema for each service
337
+    project = sqlalchemy.Column(
338
+        sqlalchemy.String(128),
339
+        nullable=False
340
+    )
341
+    file_name = sqlalchemy.Column(
342
+        sqlalchemy.String(128),
343
+        nullable=False
344
+    )
330 345
     # TODO(mrkanag) default value is some time overriden by services, which
331 346
     # osloconfig allows, so this column should have values per given service
332 347
     default_value = sqlalchemy.Column(
@@ -346,14 +361,31 @@ class OsloConfigSchema(BASE,
346 361
     )
347 362
 
348 363
 
349
-class OsloConfig(BASE,
350
-                 NamosBase,
351
-                 SoftDelete,
352
-                 Extra):
364
+class OsloConfigBase(object):
365
+
366
+    name = sqlalchemy.Column(sqlalchemy.String(255),
367
+                             # unique=True,
368
+                             nullable=False,
369
+                             default=lambda: str(uuid.uuid4()))
370
+
371
+    value = sqlalchemy.Column(
372
+        sqlalchemy.Text
373
+    )
374
+    oslo_config_schema_id = sqlalchemy.Column(
375
+        Uuid,
376
+        sqlalchemy.ForeignKey('oslo_config_schema.id')
377
+    )
378
+
379
+
380
+class OsloConfig(
381
+    BASE,
382
+    NamosBase,
383
+    SoftDelete,
384
+    Extra):
353 385
     __tablename__ = 'oslo_config'
354 386
 
355 387
     __table_args__ = (
356
-        UniqueConstraint("oslo_config_schema_id", "service_worker_id"),
388
+        UniqueConstraint("name", "service_worker_id"),
357 389
     )
358 390
 
359 391
     name = sqlalchemy.Column(sqlalchemy.String(255),
@@ -364,19 +396,54 @@ class OsloConfig(BASE,
364 396
     value = sqlalchemy.Column(
365 397
         sqlalchemy.Text
366 398
     )
367
-    oslo_config_file_id = sqlalchemy.Column(
399
+    oslo_config_schema_id = sqlalchemy.Column(
368 400
         Uuid,
369
-        sqlalchemy.ForeignKey('oslo_config_file.id')
401
+        sqlalchemy.ForeignKey('oslo_config_schema.id')
402
+    )
403
+
404
+    service_worker_id = sqlalchemy.Column(
405
+        Uuid,
406
+        sqlalchemy.ForeignKey('service_worker.id')
407
+    )
408
+    oslo_config_file_entry_id = sqlalchemy.Column(
409
+        Uuid,
410
+        sqlalchemy.ForeignKey('oslo_config_file_entry.id')
411
+    )
412
+
413
+
414
+class OsloConfigFileEntry(
415
+    BASE,
416
+    NamosBase,
417
+    SoftDelete,
418
+    Extra):
419
+    __tablename__ = 'oslo_config_file_entry'
420
+
421
+    __table_args__ = (
422
+        UniqueConstraint("oslo_config_file_id",
423
+                         "name",
424
+                         "service_component_id", ),
425
+    )
426
+
427
+    name = sqlalchemy.Column(sqlalchemy.String(255),
428
+                             # unique=True,
429
+                             nullable=False,
430
+                             default=lambda: str(uuid.uuid4()))
431
+
432
+    value = sqlalchemy.Column(
433
+        sqlalchemy.Text
370 434
     )
371 435
     oslo_config_schema_id = sqlalchemy.Column(
372 436
         Uuid,
373
-        sqlalchemy.ForeignKey('oslo_config_schema.id'),
374
-        nullable=False
437
+        sqlalchemy.ForeignKey('oslo_config_schema.id')
375 438
     )
376
-    service_worker_id = sqlalchemy.Column(
439
+    oslo_config_file_id = sqlalchemy.Column(
377 440
         Uuid,
378
-        sqlalchemy.ForeignKey('service_worker.id'),
379
-        nullable=False
441
+        sqlalchemy.ForeignKey('oslo_config_file.id')
442
+    )
443
+
444
+    service_component_id = sqlalchemy.Column(
445
+        Uuid,
446
+        sqlalchemy.ForeignKey('service_component.id')
380 447
     )
381 448
 
382 449
 
@@ -397,14 +464,67 @@ class OsloConfigFile(BASE,
397 464
     file = sqlalchemy.Column(
398 465
         LongText
399 466
     )
400
-    # Always having last one updated the conf file
401
-    service_component_id = sqlalchemy.Column(
467
+    service_node_id = sqlalchemy.Column(
402 468
         Uuid,
403
-        sqlalchemy.ForeignKey('service_component.id'),
469
+        sqlalchemy.ForeignKey('service_node.id'),
404 470
         nullable=False
405 471
     )
406
-    service_node_id = sqlalchemy.Column(
472
+
473
+
474
+class CapabilitySchema(BASE,
475
+                       NamosBase,
476
+                       Description,
477
+                       SoftDelete,
478
+                       Extra):
479
+    __tablename__ = 'os_capability_schema'
480
+
481
+    # TODO(mrkanag) Check whether conf is unique across all services or only
482
+    # sepcific to namespace, otherwise uniqueconstraint is name, group_name
483
+    __table_args__ = (
484
+        UniqueConstraint("name",
485
+                         "category"),
486
+    )
487
+
488
+    name = sqlalchemy.Column(sqlalchemy.String(255),
489
+                             # unique=True,
490
+                             nullable=False,
491
+                             default=lambda: str(uuid.uuid4()))
492
+
493
+    type = sqlalchemy.Column(
494
+        sqlalchemy.String(128),
495
+        nullable=False
496
+    )
497
+    category = sqlalchemy.Column(
498
+        sqlalchemy.String(128),
499
+        nullable=False
500
+    )
501
+
502
+
503
+class Capability(BASE,
504
+                 NamosBase,
505
+                 SoftDelete,
506
+                 Extra):
507
+    __tablename__ = 'os_capability'
508
+
509
+    capability_schema_id = sqlalchemy.Column(
407 510
         Uuid,
408
-        sqlalchemy.ForeignKey('service_node.id'),
511
+        sqlalchemy.ForeignKey('os_capability_schema.id'),
409 512
         nullable=False
410 513
     )
514
+    value = sqlalchemy.Column(
515
+        sqlalchemy.Text
516
+    )
517
+
518
+    device_id = sqlalchemy.Column(
519
+        Uuid,
520
+        sqlalchemy.ForeignKey('device.id'),
521
+        nullable=False
522
+    )
523
+
524
+
525
+class Quota(object):
526
+    pass
527
+
528
+
529
+class Reservation(object):
530
+    pass

Loading…
Cancel
Save