Browse Source

Merge pull request #3 from purnendu15/master

Base Code for Tugboat Plugin and Addition of config files, templates
hemanthnakkina 4 months ago
parent
commit
ecaef2b549
No account linked to committer's email address
44 changed files with 7917 additions and 78 deletions
  1. 3
    0
      doc/requirements.txt
  2. 129
    0
      doc/source/conf.py
  3. 132
    0
      doc/source/getting_started.rst
  4. 34
    0
      doc/source/index.rst
  5. 0
    0
      spyglass/__init__.py
  6. 0
    0
      spyglass/config/__init__.py
  7. 38
    0
      spyglass/config/rules.yaml
  8. 10
    21
      spyglass/data_extractor/base.py
  9. 2
    2
      spyglass/data_extractor/plugins/formation.py
  10. 35
    0
      spyglass/data_extractor/plugins/tugboat/check_exceptions.py
  11. 350
    0
      spyglass/data_extractor/plugins/tugboat/tugboat.py
  12. BIN
      spyglass/examples/SiteDesignSpec_v0.1.xlsx
  13. 63
    0
      spyglass/examples/excel_spec.yaml
  14. 33
    0
      spyglass/examples/site_config.yaml
  15. 26
    0
      spyglass/examples/templates/baremetal/bootactions/promjoin.yaml.j2
  16. 51
    0
      spyglass/examples/templates/baremetal/nodes.yaml.j2
  17. 90
    0
      spyglass/examples/templates/deployment/deployment-strategy.yaml.j2
  18. 107
    0
      spyglass/examples/templates/networks/common_addresses.yaml.j2
  19. 251
    0
      spyglass/examples/templates/networks/physical/networks.yaml.j2
  20. 187
    0
      spyglass/examples/templates/pki/pki-catalogue.yaml.j2
  21. 40
    0
      spyglass/examples/templates/profile/genesis.yaml.j2
  22. 76
    0
      spyglass/examples/templates/profile/hardware/dell_r720.yaml.j2
  23. 270
    0
      spyglass/examples/templates/profile/host/cp_r720.yaml.j2
  24. 103
    0
      spyglass/examples/templates/profile/host/dp_r720.yaml.j2
  25. 35
    0
      spyglass/examples/templates/profile/region.yaml.j2
  26. 2806
    0
      spyglass/examples/templates/secrets/certificates/certificates.yaml.j2
  27. 135
    0
      spyglass/examples/templates/secrets/certificates/ingress.yaml.j2
  28. 17
    0
      spyglass/examples/templates/site-definition.yaml.j2
  29. 96
    0
      spyglass/examples/templates/software/charts/kubernetes/etcd.yaml.j2
  30. 92
    0
      spyglass/examples/templates/software/charts/kubernetes/etcd/etcd.yaml.j2
  31. 28
    0
      spyglass/examples/templates/software/charts/kubernetes/ingress/ingress.yaml.j2
  32. 16
    0
      spyglass/examples/templates/software/charts/osh-infra/osh-infra-logging/elasticsearch.yaml.j2
  33. 16
    0
      spyglass/examples/templates/software/charts/osh-infra/osh-infra-logging/fluent-logging.yaml
  34. 23
    0
      spyglass/examples/templates/software/charts/osh/openstack-compute-kit/neutron.yaml.j2
  35. 25
    0
      spyglass/examples/templates/software/charts/osh/openstack-compute-kit/nova.yaml.j2
  36. 22
    0
      spyglass/examples/templates/software/charts/osh/openstack-tenant-ceph/ceph-client.yaml.j2
  37. 55
    0
      spyglass/examples/templates/software/charts/osh/openstack-tenant-ceph/ceph-osd.yaml.j2
  38. 603
    0
      spyglass/examples/templates/software/charts/ucp/divingbell/divingbell.yaml.j2
  39. 16
    0
      spyglass/examples/templates/software/config/common-software-config.yaml.j2
  40. 1312
    0
      spyglass/examples/templates/software/config/endpoints.yaml.j2
  41. 443
    0
      spyglass/examples/templates/software/config/service_accounts.yaml.j2
  42. 117
    49
      spyglass/parser/engine.py
  43. 2
    4
      spyglass/site_processors/site_processor.py
  44. 28
    2
      spyglass/spyglass.py

+ 3
- 0
doc/requirements.txt View File

@@ -0,0 +1,3 @@
1
+# Documentation
2
+sphinx>=1.6.2
3
+sphinx_rtd_theme==0.2.4

+ 129
- 0
doc/source/conf.py View File

@@ -0,0 +1,129 @@
1
+# -*- coding: utf-8 -*-
2
+#
3
+# shipyard documentation build configuration file, created by
4
+# sphinx-quickstart on Sat Sep 16 03:40:50 2017.
5
+#
6
+# This file is execfile()d with the current directory set to its
7
+# containing dir.
8
+#
9
+# Note that not all possible configuration values are present in this
10
+# autogenerated file.
11
+#
12
+# All configuration values have a default; values that are commented out
13
+# serve to show the default.
14
+
15
+# If extensions (or modules to document with autodoc) are in another directory,
16
+# add these directories to sys.path here. If the directory is relative to the
17
+# documentation root, use os.path.abspath to make it absolute, like shown here.
18
+#
19
+import os
20
+import sys
21
+sys.path.insert(0, os.path.abspath('../../'))
22
+import sphinx_rtd_theme
23
+
24
+
25
+# -- General configuration ------------------------------------------------
26
+
27
+# If your documentation needs a minimal Sphinx version, state it here.
28
+#
29
+# needs_sphinx = '1.0'
30
+
31
+# Add any Sphinx extension module names here, as strings. They can be
32
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
33
+# ones.
34
+extensions = [
35
+    'sphinx.ext.autodoc',
36
+    'sphinx.ext.todo',
37
+    'sphinx.ext.viewcode',
38
+]
39
+
40
+# Add any paths that contain templates here, relative to this directory.
41
+# templates_path = []
42
+
43
+# The suffix(es) of source filenames.
44
+# You can specify multiple suffix as a list of string:
45
+#
46
+# source_suffix = ['.rst', '.md']
47
+source_suffix = '.rst'
48
+
49
+# The master toctree document.
50
+master_doc = 'index'
51
+
52
+# General information about the project.
53
+project = u'tugboat'
54
+copyright = u'2018 AT&T Intellectual Property.'
55
+author = u'Tugboat Authors'
56
+
57
+# The version info for the project you're documenting, acts as replacement for
58
+# |version| and |release|, also used in various other places throughout the
59
+# built documents.
60
+#
61
+# The short X.Y version.
62
+version = u'0.1.0'
63
+# The full version, including alpha/beta/rc tags.
64
+release = u'0.1.0'
65
+
66
+# The language for content autogenerated by Sphinx. Refer to documentation
67
+# for a list of supported languages.
68
+#
69
+# This is also used if you do content translation via gettext catalogs.
70
+# Usually you set "language" from the command line for these cases.
71
+language = None
72
+
73
+# List of patterns, relative to source directory, that match files and
74
+# directories to ignore when looking for source files.
75
+# This patterns also effect to html_static_path and html_extra_path
76
+exclude_patterns = []
77
+
78
+# The name of the Pygments (syntax highlighting) style to use.
79
+pygments_style = 'sphinx'
80
+
81
+# If true, `todo` and `todoList` produce output, else they produce nothing.
82
+todo_include_todos = False
83
+
84
+
85
+# -- Options for HTML output ----------------------------------------------
86
+
87
+# The theme to use for HTML and HTML Help pages.  See the documentation for
88
+# a list of builtin themes.
89
+#
90
+html_theme = "sphinx_rtd_theme"
91
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
92
+
93
+# Theme options are theme-specific and customize the look and feel of a theme
94
+# further.  For a list of options available for each theme, see the
95
+# documentation.
96
+#
97
+# html_theme_options = {}
98
+
99
+# Add any paths that contain custom static files (such as style sheets) here,
100
+# relative to this directory. They are copied after the builtin static files,
101
+# so a file named "default.css" will overwrite the builtin "default.css".
102
+html_static_path = []
103
+
104
+
105
+# -- Options for HTMLHelp output ------------------------------------------
106
+
107
+# Output file base name for HTML help builder.
108
+htmlhelp_basename = 'ucpintdoc'
109
+
110
+
111
+# -- Options for LaTeX output ---------------------------------------------
112
+
113
+latex_elements = {
114
+    # The paper size ('letterpaper' or 'a4paper').
115
+    #
116
+    # 'papersize': 'letterpaper',
117
+
118
+    # The font size ('10pt', '11pt' or '12pt').
119
+    #
120
+    # 'pointsize': '10pt',
121
+
122
+    # Additional stuff for the LaTeX preamble.
123
+    #
124
+    # 'preamble': '',
125
+
126
+    # Latex figure (float) alignment
127
+    #
128
+    # 'figure_align': 'htbp',
129
+}

+ 132
- 0
doc/source/getting_started.rst View File

@@ -0,0 +1,132 @@
1
+..
2
+      Copyright 2018 AT&T Intellectual Property.
3
+      All Rights Reserved.
4
+
5
+      Licensed under the Apache License, Version 2.0 (the "License"); you may
6
+      not use this file except in compliance with the License. You may obtain
7
+      a copy of the License at
8
+
9
+          http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+      Unless required by applicable law or agreed to in writing, software
12
+      distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+      WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+      License for the specific language governing permissions and limitations
15
+      under the License.
16
+
17
+===============
18
+Getting Started
19
+===============
20
+
21
+What is Spyglass?
22
+----------------
23
+
24
+Spyglass is a data extraction tool which can interface with
25
+different input data sources to generate site manifest YAML files.
26
+The data sources will provide all the configuration data needed
27
+for a site deployment. These site manifest YAML files generated
28
+by spyglass will be saved in a Git repository, from where Pegleg
29
+can access and aggregate them. This aggregated file can then be
30
+fed to Shipyard for site deployment / updates.
31
+
32
+Architecture
33
+------------
34
+
35
+::
36
+
37
+        +-----------+           +-------------+
38
+        |           |           |  +-------+  |
39
+        |           |   +------>|  |Generic|  |
40
+    +-----------+   |   |       |  |Object |  |
41
+    |Tugboat(Xl)| I |   |       |  +-------+  |
42
+    |Plugin     | N |   |       |     |       |
43
+    +-----------+ T |   |       |     |       |
44
+        |         E |   |       |  +------+   |
45
+   +------------+ R |   |       |  |Parser|   +------> Intermediary YAML
46
+   |Remote Data | F |---+       |  +------+   |
47
+   |SourcePlugin| A |           |     |       |
48
+   +------------+ C |           |     |(Intermediary YAML)
49
+        |         E |           |     |       |
50
+        |           |           |     |       |
51
+        |         H |           |     v       |
52
+        |         A |           |  +---------+|(templates)    +------------+
53
+        |         N |           |  |Site     |+<--------------|Repository  |
54
+        |         D |           |  |Processor||-------------->|Adapter     |
55
+        |         L |           |  +---------+|(Generated     +------------+
56
+        |         E |           |      ^      | Site Manifests)
57
+        |         R |           |  +---|-----+|
58
+        |           |           |  |  J2     ||
59
+        |           |           |  |Templates||
60
+        |           |           |  +---------+|
61
+        +-----------+           +-------------+
62
+
63
+--
64
+
65
+Basic Usage
66
+-----------
67
+
68
+Before using Spyglass you must:
69
+
70
+
71
+1. Clone the Spyglass repository:
72
+
73
+   .. code-block:: console
74
+
75
+    git clone https://github.com/att-comdev/tugboat/tree/spyglass
76
+
77
+2. Install the required packages in spyglass:
78
+
79
+   .. code-block:: console
80
+
81
+     pip3 install -r tugboat/requirements.txt
82
+
83
+
84
+CLI Options
85
+-----------
86
+
87
+Usage: spyglass [OPTIONS]
88
+
89
+Options:
90
+  -s, --site TEXT                 Specify the site for which manifests to be
91
+                                  generated
92
+  -t, --type TEXT                 Specify the plugin type formation or tugboat
93
+  -f, --formation_url TEXT        Specify the formation url
94
+  -u, --formation_user TEXT       Specify the formation user id
95
+  -p, --formation_password TEXT   Specify the formation user password
96
+  -i, --intermediary PATH         Intermediary file path  generate manifests,
97
+                                  use -m also with this option
98
+  -d, --additional_config PATH    Site specific configuraton details
99
+  -g, --generate_intermediary     Dump intermediary file from passed excel and
100
+                                  excel spec
101
+  -idir, --intermediary_dir PATH  The path where intermediary file needs to be
102
+                                  generated
103
+  -e, --edit_intermediary / -nedit, --no_edit_intermediary
104
+                                  Flag to let user edit intermediary
105
+  -m, --generate_manifests        Generate manifests from the generated
106
+                                  intermediary file
107
+  -mdir, --manifest_dir PATH      The path where manifest files needs to be
108
+                                  generated
109
+  -x, --excel PATH                Path to engineering excel file, to be passed
110
+                                  with generate_intermediary
111
+  -e, --excel_spec PATH           Path to excel spec, to be passed with
112
+                                  generate_intermediary
113
+  -l, --loglevel INTEGER          Loglevel NOTSET:0 ,DEBUG:10,     INFO:20,
114
+                                  WARNING:30, ERROR:40, CRITICAL:50  [default:
115
+                                  20]
116
+  --help                          Show this message and exit.
117
+
118
+
119
+1. Running Spyglass with  Remote Data Source Plugin
120
+
121
+spyglass -mg --type formation -f <URL> -u <user_id> -p <password> -d <site_config> -s <sitetype> --template_dir=<j2 template dir>
122
+
123
+2. Running Spyglass with Excel Plugin
124
+
125
+spyglass -mg --type tugboat -x <Excel File> -e <Excel Spec> -d <Site Config> -s <Region> --template_dir=<j2 template dir>
126
+
127
+for example:
128
+spyglass -mg -t tugboat -x SiteDesignSpec_v0.1.xlsx -e excel_spec_upstream.yaml -d site_config.yaml -s airship-seaworthy --template_dir=<j2 template dir>
129
+Where sample 'excel_spec_upstream.yaml', 'SiteDesignSpec_v0.1.xlsx'
130
+'site_config.yaml' and J2 templates can be found under 'spyglass/examples'
131
+folder
132
+

+ 34
- 0
doc/source/index.rst View File

@@ -0,0 +1,34 @@
1
+..
2
+      Copyright 2018 AT&T Intellectual Property.
3
+      All Rights Reserved.
4
+
5
+      Licensed under the Apache License, Version 2.0 (the "License"); you may
6
+      not use this file except in compliance with the License. You may obtain
7
+      a copy of the License at
8
+
9
+          http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+      Unless required by applicable law or agreed to in writing, software
12
+      distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+      WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+      License for the specific language governing permissions and limitations
15
+      under the License.
16
+
17
+=====================
18
+Spyglass Documentation
19
+=====================
20
+
21
+Overview
22
+--------
23
+Spyglass is a data extraction tool which can interface with
24
+different input data sources to generate site manifest YAML files.
25
+The data sources will provide all the configuration data needed
26
+for a site deployment. These site manifest YAML files generated
27
+by spyglass will be saved in a Git repository, from where Pegleg
28
+can access and aggregate them. This aggregated file can then be
29
+fed to Shipyard for site deployment / updates.
30
+
31
+.. toctree::
32
+   :maxdepth: 2
33
+
34
+   getting_started

+ 0
- 0
spyglass/__init__.py View File


+ 0
- 0
spyglass/config/__init__.py View File


+ 38
- 0
spyglass/config/rules.yaml View File

@@ -0,0 +1,38 @@
1
+###########################
2
+# Global Rules            #
3
+###########################
4
+#Rule1:  ip_alloc_offset
5
+#        Specifies the number of ip addresses to offset from
6
+#        the start of subnet allocation pool while allocating it to host.
7
+#        -for vlan it is set to 12 as default.
8
+#        -for oob it is 10
9
+#        -for all gateway ip addresss it is set to 1.
10
+#        -for ingress vip it is 1
11
+#        -for static end (non pxe) it is -1( means one but last ip of the pool)
12
+#        -for dhcp end (pxe only) it is -2( 3rd from the last ip of the pool)
13
+#Rule2:  host_profile_interfaces.
14
+#        Specifies the network interfaces type and
15
+#        and their names for a particular hw profile
16
+#Rule3: hardware_profile
17
+#       This specifies the profile details  bases on sitetype.
18
+#       It specifies the profile name and host type for compute,
19
+#       controller along with hw type
20
+---
21
+rule_ip_alloc_offset:
22
+  name: ip_alloc_offset
23
+  ip_alloc_offset:
24
+    default: 12
25
+    oob: 10
26
+    gateway: 1
27
+    ingress_vip: 1
28
+    static_ip_end: -2
29
+    dhcp_ip_end: -2
30
+rule_hardware_profile:
31
+  name: hardware_profile
32
+  hardware_profile:
33
+    foundry:
34
+      profile_name:
35
+        compute: dp-r720
36
+        ctrl: cp-r720
37
+      hw_type: dell_r720
38
+...

+ 10
- 21
spyglass/data_extractor/base.py View File

@@ -277,7 +277,6 @@ class BaseDataSourcePlugin(object):
277 277
         """
278 278
         LOG.info("Extract baremetal information from plugin")
279 279
         baremetal = {}
280
-        is_genesis = False
281 280
         hosts = self.get_hosts(self.region)
282 281
 
283 282
         # For each host list fill host profile and network IPs
@@ -301,30 +300,19 @@ class BaseDataSourcePlugin(object):
301 300
 
302 301
             # Fill network IP for this host
303 302
             temp_host['ip'] = {}
304
-            temp_host['ip']['oob'] = temp_host_ips[host_name].get('oob', "")
303
+            temp_host['ip']['oob'] = temp_host_ips[host_name].get(
304
+                'oob', "#CHANGE_ME")
305 305
             temp_host['ip']['calico'] = temp_host_ips[host_name].get(
306
-                'calico', "")
307
-            temp_host['ip']['oam'] = temp_host_ips[host_name].get('oam', "")
306
+                'calico', "#CHANGE_ME")
307
+            temp_host['ip']['oam'] = temp_host_ips[host_name].get(
308
+                'oam', "#CHANGE_ME")
308 309
             temp_host['ip']['storage'] = temp_host_ips[host_name].get(
309
-                'storage', "")
310
+                'storage', "#CHANGE_ME")
310 311
             temp_host['ip']['overlay'] = temp_host_ips[host_name].get(
311
-                'overlay', "")
312
+                'overlay', "#CHANGE_ME")
312 313
             temp_host['ip']['pxe'] = temp_host_ips[host_name].get(
313 314
                 'pxe', "#CHANGE_ME")
314 315
 
315
-            # Filling rack_type( compute/controller/genesis)
316
-            # "cp" host profile is controller
317
-            # "ns" host profile is compute
318
-            if (temp_host['host_profile'] == 'cp'):
319
-                # The controller node is designates as genesis"
320
-                if is_genesis is False:
321
-                    is_genesis = True
322
-                    temp_host['type'] = 'genesis'
323
-                else:
324
-                    temp_host['type'] = 'controller'
325
-            else:
326
-                temp_host['type'] = 'compute'
327
-
328 316
             baremetal[rack_name][host_name] = temp_host
329 317
         LOG.debug("Baremetal information:\n{}".format(
330 318
             pprint.pformat(baremetal)))
@@ -412,8 +400,9 @@ class BaseDataSourcePlugin(object):
412 400
         for net in networks:
413 401
             tmp_net = {}
414 402
             if net['name'] in networks_to_scan:
415
-                tmp_net['subnet'] = net['subnet']
416
-                tmp_net['vlan'] = net['vlan']
403
+                tmp_net['subnet'] = net.get('subnet', '#CHANGE_ME')
404
+                if ((net['name'] != 'ingress') and (net['name'] != 'oob')):
405
+                    tmp_net['vlan'] = net.get('vlan', '#CHANGE_ME')
417 406
 
418 407
             network_data['vlan_network_data'][net['name']] = tmp_net
419 408
 

+ 2
- 2
spyglass/data_extractor/plugins/formation.py View File

@@ -433,8 +433,8 @@ class FormationPlugin(BaseDataSourcePlugin):
433 433
             name_pattern = "(?i)({})".format(name)
434 434
             if re.search(name_pattern, vlan_name):
435 435
                 return network_names[name]
436
-
437
-        return ("")
436
+        # Return empty string is vlan_name is not matched with network_names
437
+        return ""
438 438
 
439 439
     def get_dns_servers(self, region):
440 440
         try:

+ 35
- 0
spyglass/data_extractor/plugins/tugboat/check_exceptions.py View File

@@ -0,0 +1,35 @@
1
+# Copyright 2018 AT&T Intellectual Property.  All other rights reserved.
2
+#
3
+# Licensed under the Apache License, Version 2.0 (the "License");
4
+# you may not use this file except in compliance with the License.
5
+# You may obtain a copy of the License at
6
+#
7
+# http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+# Unless required by applicable law or agreed to in writing, software
10
+# distributed under the License is distributed on an "AS IS" BASIS,
11
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+# See the License for the specific language governing permissions and
13
+# limitations under the License.
14
+
15
+
16
+class BaseError(Exception):
17
+    pass
18
+
19
+
20
+class NotEnoughIp(BaseError):
21
+    def __init__(self, cidr, total_nodes):
22
+        self.cidr = cidr
23
+        self.total_nodes = total_nodes
24
+
25
+    def display_error(self):
26
+        print('{} can not handle {} nodes'.format(self.cidr, self.total_nodes))
27
+
28
+
29
+class NoSpecMatched(BaseError):
30
+    def __init__(self, excel_specs):
31
+        self.specs = excel_specs
32
+
33
+    def display_error(self):
34
+        print('No spec matched. Following are the available specs:\n'.format(
35
+            self.specs))

+ 350
- 0
spyglass/data_extractor/plugins/tugboat/tugboat.py View File

@@ -0,0 +1,350 @@
1
+# Copyright 2018 AT&T Intellectual Property.  All other rights reserved.
2
+#
3
+# Licensed under the Apache License, Version 2.0 (the 'License');
4
+# you may not use this file except in compliance with the License.
5
+# You may obtain a copy of the License at
6
+#
7
+# http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+# Unless required by applicable law or agreed to in writing, software
10
+# distributed under the License is distributed on an 'AS IS' BASIS,
11
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+# See the License for the specific language governing permissions and
13
+# limitations under the License.
14
+
15
+import itertools
16
+import logging
17
+import pprint
18
+import re
19
+from spyglass.data_extractor.base import BaseDataSourcePlugin
20
+from spyglass.data_extractor.plugins.tugboat.excel_parser import ExcelParser
21
+
22
+LOG = logging.getLogger(__name__)
23
+
24
+
25
+class TugboatPlugin(BaseDataSourcePlugin):
26
+    def __init__(self, region):
27
+        LOG.info("Tugboat Initializing")
28
+        self.source_type = 'excel'
29
+        self.source_name = 'tugboat'
30
+
31
+        # Configuration parameters
32
+        self.excel_path = None
33
+        self.excel_spec = None
34
+
35
+        # Site related data
36
+        self.region = region
37
+
38
+        # Raw data from excel
39
+        self.parsed_xl_data = None
40
+
41
+        LOG.info("Initiated data extractor plugin:{}".format(self.source_name))
42
+
43
+    def set_config_opts(self, conf):
44
+        """
45
+        Placeholder to set confgiuration options
46
+        specific to each plugin.
47
+
48
+        :param dict conf: Configuration options as dict
49
+
50
+        Example: conf = { 'excel_spec': 'spec1.yaml',
51
+                          'excel_path': 'excel.xls' }
52
+
53
+        Each plugin will have their own config opts.
54
+        """
55
+        self.excel_path = conf['excel_path']
56
+        self.excel_spec = conf['excel_spec']
57
+
58
+        # Extract raw data from excel sheets
59
+        self._get_excel_obj()
60
+        self._extract_raw_data_from_excel()
61
+        return
62
+
63
+    def get_plugin_conf(self, kwargs):
64
+        """ Validates the plugin param from CLI and return if correct
65
+
66
+
67
+        Ideally the CLICK module shall report an error if excel file
68
+        and excel specs are not specified. The below code has been
69
+        written as an additional safeguard.
70
+        """
71
+        try:
72
+            assert (len(
73
+                kwargs['excel'])), "Engineering Spec file not specified"
74
+            excel_file_info = kwargs['excel']
75
+            assert (kwargs['excel_spec']
76
+                    ) is not None, "Excel Spec file not specified"
77
+            excel_spec_info = kwargs['excel_spec']
78
+        except AssertionError as e:
79
+            LOG.error("{}:Spyglass exited!".format(e))
80
+            exit()
81
+        plugin_conf = {
82
+            'excel_path': excel_file_info,
83
+            'excel_spec': excel_spec_info
84
+        }
85
+        return plugin_conf
86
+
87
+    def get_hosts(self, region, rack=None):
88
+        """Return list of hosts in the region
89
+        :param string region: Region name
90
+        :param string rack: Rack name
91
+        :returns: list of hosts information
92
+        :rtype: list of dict
93
+        Example: [
94
+                     {
95
+                         'name': 'host01',
96
+                         'type': 'controller',
97
+                         'host_profile': 'hp_01'
98
+                     },
99
+                     {
100
+                         'name': 'host02',
101
+                         'type': 'compute',
102
+                         'host_profile': 'hp_02'}
103
+                 ]
104
+        """
105
+        LOG.info("Get Host Information")
106
+        ipmi_data = self.parsed_xl_data['ipmi_data'][0]
107
+        rackwise_hosts = self._get_rackwise_hosts()
108
+        host_list = []
109
+        for rack in rackwise_hosts.keys():
110
+            for host in rackwise_hosts[rack]:
111
+                host_list.append({
112
+                    'rack_name':
113
+                    rack,
114
+                    'name':
115
+                    host,
116
+                    'host_profile':
117
+                    ipmi_data[host]['host_profile']
118
+                })
119
+        return host_list
120
+
121
+    def get_networks(self, region):
122
+        """ Extracts vlan network info from raw network data from excel"""
123
+        vlan_list = []
124
+        # Network data extracted from xl is formatted to have a predictable
125
+        # data type. For e.g VlAN 45 extracted from xl is formatted as 45
126
+        vlan_pattern = r'\d+'
127
+        private_net = self.parsed_xl_data['network_data']['private']
128
+        public_net = self.parsed_xl_data['network_data']['public']
129
+        # Extract network information from private and public network data
130
+        for net_type, net_val in itertools.chain(private_net.items(),
131
+                                                 public_net.items()):
132
+            tmp_vlan = {}
133
+            # Ingress is special network that has no vlan, only a subnet string
134
+            # So treatment for ingress is different
135
+            if net_type is not 'ingress':
136
+                # standardize the network name as net_type may ne different.
137
+                # For e.g insteas of pxe it may be PXE or instead of calico
138
+                # it may be ksn. Valid network names are pxe, calico, oob, oam,
139
+                # overlay, storage, ingress
140
+                tmp_vlan['name'] = self._get_network_name_from_vlan_name(
141
+                    net_type)
142
+
143
+                # extract vlan tag. It was extracted from xl file as 'VlAN 45'
144
+                # The code below extracts the numeric data fron net_val['vlan']
145
+                if net_val.get('vlan', "") is not "":
146
+                    value = re.findall(vlan_pattern, net_val['vlan'])
147
+                    tmp_vlan['vlan'] = value[0]
148
+                else:
149
+                    tmp_vlan['vlan'] = "#CHANGE_ME"
150
+
151
+                tmp_vlan['subnet'] = net_val.get('subnet', "#CHANGE_ME")
152
+                tmp_vlan['gateway'] = net_val.get('gateway', "#CHANGE_ME")
153
+            else:
154
+                tmp_vlan['name'] = 'ingress'
155
+                tmp_vlan['subnet'] = net_val
156
+            vlan_list.append(tmp_vlan)
157
+        LOG.debug("vlan list extracted from tugboat:\n{}".format(
158
+            pprint.pformat(vlan_list)))
159
+        return vlan_list
160
+
161
+    def get_ips(self, region, host=None):
162
+        """Return list of IPs on the host
163
+        :param string region: Region name
164
+        :param string host: Host name
165
+        :returns: Dict of IPs per network on the host
166
+        :rtype: dict
167
+        Example: {'oob': {'ipv4': '192.168.1.10'},
168
+                  'pxe': {'ipv4': '192.168.2.10'}}
169
+        The network name from get_networks is expected to be the keys of this
170
+        dict. In case some networks are missed, they are expected to be either
171
+        DHCP or internally generated n the next steps by the design rules.
172
+        """
173
+
174
+        ip_ = {}
175
+        ipmi_data = self.parsed_xl_data['ipmi_data'][0]
176
+        ip_[host] = {
177
+            'oob': ipmi_data[host].get('ipmi_address', '#CHANGE_ME'),
178
+            'oam': ipmi_data[host].get('oam', '#CHANGE_ME'),
179
+            'calico': ipmi_data[host].get('calico', '#CHANGE_ME'),
180
+            'overlay': ipmi_data[host].get('overlay', '#CHANGE_ME'),
181
+            'pxe': ipmi_data[host].get('pxe', '#CHANGE_ME'),
182
+            'storage': ipmi_data[host].get('storage', '#CHANGE_ME')
183
+        }
184
+        return ip_
185
+
186
+    def get_ldap_information(self, region):
187
+        """ Extract ldap information from excel"""
188
+
189
+        ldap_raw_data = self.parsed_xl_data['site_info']['ldap']
190
+        ldap_info = {}
191
+        # raw url is 'url: ldap://example.com' so we are converting to
192
+        # 'ldap://example.com'
193
+        url = ldap_raw_data.get('url', '#CHANGE_ME')
194
+        try:
195
+            ldap_info['url'] = url.split(' ')[1]
196
+            ldap_info['domain'] = url.split('.')[1]
197
+        except IndexError as e:
198
+            LOG.error("url.split:{}".format(e))
199
+        ldap_info['common_name'] = ldap_raw_data.get('common_name',
200
+                                                     '#CHANGE_ME')
201
+        ldap_info['subdomain'] = ldap_raw_data.get('subdomain', '#CHANGE_ME')
202
+
203
+        return ldap_info
204
+
205
+    def get_ntp_servers(self, region):
206
+        """ Returns a comma separated list of ntp ip addresses"""
207
+
208
+        ntp_server_list = self._get_formatted_server_list(
209
+            self.parsed_xl_data['site_info']['ntp'])
210
+        return ntp_server_list
211
+
212
+    def get_dns_servers(self, region):
213
+        """ Returns a comma separated list of dns ip addresses"""
214
+        dns_server_list = self._get_formatted_server_list(
215
+            self.parsed_xl_data['site_info']['dns'])
216
+        return dns_server_list
217
+
218
+    def get_domain_name(self, region):
219
+        """ Returns domain name extracted from excel file"""
220
+
221
+        return self.parsed_xl_data['site_info']['domain']
222
+
223
+    def get_location_information(self, region):
224
+        """
225
+        Prepare location data from information extracted
226
+        by ExcelParser(i.e raw data)
227
+        """
228
+        location_data = self.parsed_xl_data['site_info']['location']
229
+
230
+        corridor_pattern = r'\d+'
231
+        corridor_number = re.findall(corridor_pattern,
232
+                                     location_data['corridor'])[0]
233
+        name = location_data.get('name', '#CHANGE_ME')
234
+        state = location_data.get('state', '#CHANGE_ME')
235
+        country = location_data.get('country', '#CHANGE_ME')
236
+        physical_location_id = location_data.get('physical_location', '')
237
+
238
+        return {
239
+            'name': name,
240
+            'physical_location_id': physical_location_id,
241
+            'state': state,
242
+            'country': country,
243
+            'corridor': 'c{}'.format(corridor_number),
244
+        }
245
+
246
+    def get_racks(self, region):
247
+        # This function is not required since the excel plugin
248
+        # already provide rack information.
249
+        pass
250
+
251
+    def _get_excel_obj(self):
252
+        """ Creation of an ExcelParser object to store site information.
253
+
254
+        The information is obtained based on a excel spec yaml file.
255
+        This spec contains row, column and sheet information of
256
+        the excel file from where site specific data can be extracted.
257
+        """
258
+        self.excel_obj = ExcelParser(self.excel_path, self.excel_spec)
259
+
260
+    def _extract_raw_data_from_excel(self):
261
+        """ Extracts raw information from excel file based on excel spec"""
262
+        self.parsed_xl_data = self.excel_obj.get_data()
263
+
264
+    def _get_network_name_from_vlan_name(self, vlan_name):
265
+        """ network names are ksn, oam, oob, overlay, storage, pxe
266
+
267
+
268
+        This is a utility function to determine the vlan acceptable
269
+        vlan from the name extracted from excel file
270
+
271
+        The following mapping rules apply:
272
+            vlan_name contains "ksn or calico"  the network name is "calico"
273
+            vlan_name contains "storage" the network name is "storage"
274
+            vlan_name contains "server"  the network name is "oam"
275
+            vlan_name contains "ovs"  the network name is "overlay"
276
+            vlan_name contains "oob" the network name is "oob"
277
+            vlan_name contains "pxe" the network name is "pxe"
278
+        """
279
+        network_names = [
280
+            'ksn|calico', 'storage', 'oam|server', 'ovs|overlay', 'oob', 'pxe'
281
+        ]
282
+        for name in network_names:
283
+            # Make a pattern that would ignore case.
284
+            # if name is 'ksn' pattern name is '(?i)(ksn)'
285
+            name_pattern = "(?i)({})".format(name)
286
+            if re.search(name_pattern, vlan_name):
287
+                if name is 'ksn|calico':
288
+                    return 'calico'
289
+                if name is 'storage':
290
+                    return 'storage'
291
+                if name is 'oam|server':
292
+                    return 'oam'
293
+                if name is 'ovs|overlay':
294
+                    return 'overlay'
295
+                if name is 'oob':
296
+                    return 'oob'
297
+                if name is 'pxe':
298
+                    return 'pxe'
299
+        # if nothing matches
300
+        LOG.error(
301
+            "Unable to recognize VLAN name extracted from Plugin data source")
302
+        return ("")
303
+
304
+    def _get_formatted_server_list(self, server_list):
305
+        """ Format dns and ntp server list as comma separated string """
306
+
307
+        # dns/ntp server info from excel is of the format
308
+        # 'xxx.xxx.xxx.xxx, (aaa.bbb.ccc.com)'
309
+        # The function returns a list of comma separated dns ip addresses
310
+        servers = []
311
+        for data in server_list:
312
+            if '(' not in data:
313
+                servers.append(data)
314
+        formatted_server_list = ','.join(servers)
315
+        return formatted_server_list
316
+
317
+    def _get_rack(self, host):
318
+        """
319
+        Get rack id  from the rack string extracted
320
+        from xl
321
+        """
322
+        rack_pattern = r'\w.*(r\d+)\w.*'
323
+        rack = re.findall(rack_pattern, host)[0]
324
+        if not self.region:
325
+            self.region = host.split(rack)[0]
326
+        return rack
327
+
328
+    def _get_rackwise_hosts(self):
329
+        """ Mapping hosts with rack ids """
330
+        rackwise_hosts = {}
331
+        hostnames = self.parsed_xl_data['ipmi_data'][1]
332
+        racks = self._get_rack_data()
333
+        for rack in racks:
334
+            if rack not in rackwise_hosts:
335
+                rackwise_hosts[racks[rack]] = []
336
+            for host in hostnames:
337
+                if rack in host:
338
+                    rackwise_hosts[racks[rack]].append(host)
339
+        LOG.debug("rackwise hosts:\n%s", pprint.pformat(rackwise_hosts))
340
+        return rackwise_hosts
341
+
342
+    def _get_rack_data(self):
343
+        """ Format rack name """
344
+        LOG.info("Getting rack data")
345
+        racks = {}
346
+        hostnames = self.parsed_xl_data['ipmi_data'][1]
347
+        for host in hostnames:
348
+            rack = self._get_rack(host)
349
+            racks[rack] = rack.replace('r', 'rack')
350
+        return racks

BIN
spyglass/examples/SiteDesignSpec_v0.1.xlsx View File


+ 63
- 0
spyglass/examples/excel_spec.yaml View File

@@ -0,0 +1,63 @@
1
+# Copyright 2018 The Openstack-Helm Authors.
2
+# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
3
+#
4
+# Licensed under the Apache License, Version 2.0 (the "License");
5
+# you may not use this file except in compliance with the License.
6
+# You may obtain a copy of the License at
7
+#
8
+#     http://www.apache.org/licenses/LICENSE-2.0
9
+#
10
+# Unless required by applicable law or agreed to in writing, software
11
+# distributed under the License is distributed on an "AS IS" BASIS,
12
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+# See the License for the specific language governing permissions and
14
+# limitations under the License.
15
+
16
+# Important: Please modify the dictionary with appropriate
17
+# design spec file.
18
+---
19
+specs:
20
+    # Design Spec file name: SiteDesignSpec_v0.1.xlsx
21
+    xl_spec:
22
+        ipmi_sheet_name: 'Site-Information'
23
+        start_row: 4
24
+        end_row: 15
25
+        hostname_col: 2
26
+        ipmi_address_col: 3
27
+        host_profile_col: 5
28
+        ipmi_gateway_col: 4
29
+        private_ip_sheet: 'Site-Information'
30
+        net_type_col: 1
31
+        vlan_col: 2
32
+        vlan_start_row: 19 
33
+        vlan_end_row: 30
34
+        net_start_row: 33
35
+        net_end_row: 40
36
+        net_col: 2
37
+        net_vlan_col: 1
38
+        public_ip_sheet: 'Site-Information'
39
+        oam_vlan_col: 1
40
+        oam_ip_row: 43
41
+        oam_ip_col: 2
42
+        oob_net_row: 48
43
+        oob_net_start_col: 2
44
+        oob_net_end_col: 5
45
+        ingress_ip_row: 45
46
+        dns_ntp_ldap_sheet: 'Site-Information'
47
+        login_domain_row: 52
48
+        ldap_col: 2
49
+        global_group: 53
50
+        ldap_search_url_row: 54
51
+        ntp_row: 55
52
+        ntp_col: 2
53
+        dns_row: 56
54
+        dns_col: 2
55
+        domain_row: 51
56
+        domain_col: 2
57
+        location_sheet: 'Site-Information'
58
+        column: 2
59
+        corridor_row: 59 
60
+        site_name_row: 58
61
+        state_name_row: 60
62
+        country_name_row: 61
63
+        clli_name_row: 62

+ 33
- 0
spyglass/examples/site_config.yaml View File

@@ -0,0 +1,33 @@
1
+##################################
2
+# Site Specific Tugboat Settings #
3
+##################################
4
+---
5
+site_info:
6
+  ldap:
7
+    common_name: test
8
+    url: ldap://ldap.example.com
9
+    subdomain: test
10
+  ntp:
11
+    servers: 10.10.10.10,20.20.20.20,30.30.30.30
12
+  sitetype: foundry
13
+  domain: atlantafoundry.com
14
+  dns:
15
+    servers: 8.8.8.8,8.8.4.4,208.67.222.222
16
+network:
17
+  vlan_network_data:
18
+    ingress:
19
+        subnet:
20
+        - 132.68.226.72/29
21
+  bgp :
22
+    peers:
23
+    - '172.29.0.2'
24
+    - '172.29.0.3'
25
+    asnumber: 64671
26
+    peer_asnumber: 64688
27
+storage:
28
+  ceph:
29
+    controller:
30
+      osd_count: 6
31
+...
32
+
33
+

+ 26
- 0
spyglass/examples/templates/baremetal/bootactions/promjoin.yaml.j2 View File

@@ -0,0 +1,26 @@
1
+---
2
+schema: 'drydock/BootAction/v1'
3
+metadata:
4
+  schema: 'metadata/Document/v1'
5
+  name: promjoin
6
+  storagePolicy: 'cleartext'
7
+  layeringDefinition:
8
+    abstract: false
9
+    layer: site
10
+  labels:
11
+    application: 'drydock'
12
+data:
13
+  signaling: false
14
+  assets:
15
+    - path: /opt/promjoin.sh
16
+      type: file
17
+      permissions: '555'
18
+{% raw %}
19
+      location: promenade+http://promenade-api.ucp.svc.cluster.local/api/v1.0/join-scripts?design_ref={{ action.design_ref | urlencode }}&hostname={{ node.hostname }}&ip={{ node.network.calico.ip }}{% endif %}{% for k, v in node.labels.items() %}&labels.dynamic={{ k }}={{ v }}{% endfor %}
20
+
21
+{% endraw %}
22
+      location_pipeline:
23
+        - template
24
+      data_pipeline:
25
+        - utf8_decode
26
+...

+ 51
- 0
spyglass/examples/templates/baremetal/nodes.yaml.j2 View File

@@ -0,0 +1,51 @@
1
+{% set control_count = [1] %}
2
+{% for rack in data['baremetal'].keys() %}
3
+{% for host in data['baremetal'][rack].keys()%}
4
+{% if data['baremetal'][rack][host]['type'] != 'genesis' %}
5
+---
6
+schema: 'drydock/BaremetalNode/v1'
7
+metadata:
8
+  schema: 'metadata/Document/v1'
9
+  name: {{ host }}
10
+  layeringDefinition:
11
+    abstract: false
12
+    layer: site
13
+  storagePolicy: cleartext
14
+data:
15
+  oob:
16
+    account: 'root'
17
+{% if data['baremetal'][rack][host]['host_profile'] == 'cp' %}
18
+{% if control_count.append(control_count.pop()+1) %} {% endif %}
19
+{% if control_count[0] < 4 %}
20
+  host_profile: nc-{{data['baremetal'][rack][host]['host_profile']}}-primary
21
+{% else %}
22
+  host_profile: nc-{{data['baremetal'][rack][host]['host_profile']}}-secondary
23
+{% endif %}
24
+{% else %}
25
+  host_profile: nc-{{data['baremetal'][rack][host]['host_profile']}}
26
+{% endif %}
27
+  addressing:
28
+    - network: oob
29
+      address: {{ data['baremetal'][rack][host]['ip']['oob'] }}
30
+    - network: oam
31
+      address: {{ data['baremetal'][rack][host]['ip']['oam'] }}
32
+    - network: pxe
33
+      address: {{ data['baremetal'][rack][host]['ip']['pxe'] }}
34
+    - network: storage
35
+      address: {{ data['baremetal'][rack][host]['ip']['storage'] }}
36
+    - network: calico
37
+      address: {{ data['baremetal'][rack][host]['ip']['calico'] }}
38
+    - network: overlay
39
+      address: {{ data['baremetal'][rack][host]['ip']['overlay'] }}
40
+  metadata:
41
+    rack: RACK{{rack[-2:] }}
42
+    tags:
43
+{% if data['baremetal'][rack][host]['type'] == 'compute' %}
44
+        - 'workers'
45
+{% else %}
46
+        - 'masters'
47
+{% endif %}
48
+...
49
+{% endif %}
50
+{%endfor%}
51
+{%endfor%}

+ 90
- 0
spyglass/examples/templates/deployment/deployment-strategy.yaml.j2 View File

@@ -0,0 +1,90 @@
1
+---
2
+# The purpose of this file is to provide Shipyard a strategy to aid in the site's
3
+# deployment. This WILL require modification for each particular site. A successful
4
+# strategy for large labs that has been used in the past has been to split the Control
5
+# Plane hosts up from the computes, as well as the computes by rack. The below strategy
6
+# differs slightly, as the size of the lab is smaller. As such, the Control Plane hosts
7
+# deploy first, followed by half of the computes, followed by the second half of the
8
+# computes. Shipyard deployment strategies can be very useful in getting around certain
9
+# failures, like misbehaving nodes that may hold up the deployment. See more at:
10
+# https://github.com/openstack/airship-shipyard/blob/master/doc/source/site-definition-documents.rst#deployment-strategy
11
+schema: shipyard/DeploymentStrategy/v1
12
+metadata:
13
+  schema: metadata/Document/v1
14
+  replacement: true
15
+  name: deployment-strategy
16
+  layeringDefinition:
17
+    abstract: false
18
+    layer: site
19
+    parentSelector:
20
+      name: deployment-strategy-global
21
+    actions:
22
+      - method: replace
23
+        path: .
24
+  storagePolicy: cleartext
25
+  replacement: true
26
+data:
27
+  groups:
28
+    - name: masters
29
+      critical: true
30
+      depends_on: []
31
+      selectors:
32
+        - node_names: []
33
+          node_labels: []
34
+          node_tags:
35
+            - masters
36
+          rack_names: []
37
+      success_criteria:
38
+        percent_successful_nodes: 100
39
+    # NEWSITE-CHANGEME: The number of "worker groups" should equal the number of site racks
40
+    - name: worker_group_0
41
+      critical: false
42
+      depends_on:
43
+        - masters
44
+      selectors:
45
+        # NEWSITE-CHANGEME: The following should be a list of the computes in the site's first rack
46
+        - node_names:
47
+{% for rack in data['baremetal'].keys() %}
48
+{% for host in data['baremetal'][rack].keys()%}
49
+{% if rack == 'rack03' or rack == 'rack04' %}
50
+          - {{ host }}
51
+{% endif %}
52
+{% endfor %}
53
+{% endfor %}
54
+          node_labels: []
55
+          node_tags: []
56
+          rack_names: []
57
+    - name: worker_group_1
58
+      critical: false
59
+      depends_on:
60
+        - masters
61
+      selectors:
62
+        # NEWSITE-CHANGEME: The following should be a list of the computes in the site's second rack
63
+        - node_names:
64
+{% for rack in data['baremetal'].keys() %}
65
+{% for host in data['baremetal'][rack].keys()%}
66
+{% if rack == 'rack05' or rack == 'rack06' %}
67
+          - {{ host }}
68
+{% endif %}
69
+{% endfor %}
70
+{% endfor %}
71
+          node_labels: []
72
+          node_tags: []
73
+          rack_names: []
74
+    - name: workers
75
+      critical: true
76
+      # NEWSITE-CHANGEME: Populate with each worker group (should equal the number of site racks).
77
+      # This group ensures a percent of success is achieved with the compute deployments.
78
+      depends_on:
79
+        - worker_group_0
80
+        - worker_group_1
81
+      selectors:
82
+        - node_names: []
83
+          node_labels: []
84
+          node_tags:
85
+            - workers
86
+          rack_names: []
87
+      success_criteria:
88
+        percent_successful_nodes: 60
89
+...
90
+

+ 107
- 0
spyglass/examples/templates/networks/common_addresses.yaml.j2 View File

@@ -0,0 +1,107 @@
1
+---
2
+schema: pegleg/CommonAddresses/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: common-addresses
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+  storagePolicy: cleartext
10
+data:
11
+  calico:
12
+    ip_autodetection_method: interface=bond1.{{ data['network']['vlan_network_data']['calico']['vlan']}}
13
+    etcd:
14
+      service_ip: 10.96.232.136
15
+    ip_rule:
16
+      gateway: {{ data['network']['vlan_network_data']['calico']['gateway']}}
17
+      overlap_cidr: 10.96.0.0/15
18
+    bgp:
19
+      ipv4:
20
+        public_service_cidr: {{ data['network']['vlan_network_data']['ingress']['subnet'][0] }}
21
+        ingress_vip: {{ data['network']['bgp']['ingress_vip'] }}
22
+        peers:
23
+{% for peer in data['network']['bgp']['peers'] %}
24
+          - {{ peer }}
25
+{% endfor %}
26
+  dns:
27
+    cluster_domain: cluster.local
28
+    service_ip: 10.96.0.10
29
+    upstream_servers:
30
+{% for server in (data['site_info']['dns']['servers']).split(',') %}
31
+      - {{ server }}
32
+{% endfor %}
33
+    upstream_servers_joined: {{ data['site_info']['dns']['servers']}}
34
+    ingress_domain: {{ data['site_info']['domain']|lower }}
35
+
36
+  genesis:
37
+    hostname: {{ (data|get_role_wise_nodes)['genesis']['name'] }}
38
+{% for rack in data['baremetal'] %}
39
+{% for host  in data['baremetal'][rack] %}
40
+{% if data['baremetal'][rack][host]['type'] == 'genesis' %}
41
+    ip: {{ data['baremetal'][rack][host]['ip']['calico'] }}
42
+{% endif %}
43
+{% endfor %}
44
+{% endfor %}
45
+  bootstrap:
46
+    ip: {{ (data|get_role_wise_nodes)['genesis']['pxe'] }}
47
+
48
+  kubernetes:
49
+    api_service_ip: 10.96.0.1
50
+    etcd_service_ip: 10.96.0.2
51
+    pod_cidr: 10.97.0.0/16
52
+    service_cidr: 10.96.0.0/16
53
+    # misc k8s port settings
54
+    apiserver_port: 6443
55
+    haproxy_port: 6553
56
+    service_node_port_range: 30000-32767
57
+
58
+  # etcd port settings
59
+  etcd:
60
+    container_port: 2379
61
+    haproxy_port: 2378
62
+
63
+  masters:
64
+{% for host in (data|get_role_wise_nodes)['masters'] %}
65
+    - hostname: {{ host }}
66
+{% endfor %}
67
+  # NEWSITE-CHANGEME: Environment proxy information.
68
+  # NOTE: Reference Airship sites do not deploy behind a proxy, so this proxy section
69
+  # should be commented out.
70
+  # However if you are in a lab that requires proxy, ensure that these proxy
71
+  # settings are correct and reachable in your environment; otherwise update
72
+  # them with the correct values for your environment.
73
+  proxy:
74
+    http: ""
75
+    https: ""
76
+    no_proxy: []
77
+
78
+  node_ports:
79
+    drydock_api: 30000
80
+    maas_api: 30001
81
+    maas_proxy: 31800  # hardcoded in MAAS
82
+    shipyard_api: 30003
83
+    airflow_web: 30004
84
+  ntp:
85
+    servers_joined: {{ data['site_info']['ntp']['servers'] }}
86
+
87
+  ldap:
88
+    base_url: {{ (data['site_info']['ldap']['url']|string).split('//')[1] }}
89
+    url: {{ data['site_info']['ldap']['url'] }}
90
+    auth_path: DC=test,DC=test,DC=com?sAMAccountName?sub?memberof=CN={{ data['site_info']['ldap']['common_name'] }},OU=Application,OU=Groups,DC=test,DC=test,DC=com
91
+    common_name: {{ data['site_info']['ldap']['common_name'] }}
92
+    subdomain: {{ data['site_info']['ldap']['subdomain'] }}
93
+    domain: {{ (data['site_info']['ldap']['url']|string).split('.')[1] }}
94
+
95
+  storage:
96
+    ceph:
97
+      public_cidr: {{ data['network']['vlan_network_data']['storage']['subnet'] }}
98
+      cluster_cidr: {{ data['network']['vlan_network_data']['storage']['subnet'] }}
99
+
100
+  neutron:
101
+    tunnel_device: 'bond1.{{ data['network']['vlan_network_data']['overlay']['vlan'] }}'
102
+    external_iface: 'bond1'
103
+
104
+  openvswitch:
105
+    external_iface: 'bond1'
106
+...
107
+

+ 251
- 0
spyglass/examples/templates/networks/physical/networks.yaml.j2 View File

@@ -0,0 +1,251 @@
1
+---
2
+schema: 'drydock/NetworkLink/v1'
3
+metadata:
4
+  schema: 'metadata/Document/v1'
5
+  name: oob
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+  storagePolicy: cleartext
10
+data:
11
+  # MaaS doesnt own this network like it does the others, so the noconfig label
12
+  # is specified.
13
+  labels:
14
+    noconfig: enabled
15
+  bonding:
16
+    mode: disabled
17
+  mtu: 1500
18
+  linkspeed: auto
19
+  trunking:
20
+    mode: disabled
21
+    default_network: oob
22
+  allowed_networks:
23
+    - oob
24
+...
25
+---
26
+schema: 'drydock/Network/v1'
27
+metadata:
28
+  schema: 'metadata/Document/v1'
29
+  name: oob
30
+  layeringDefinition:
31
+    abstract: false
32
+    layer: site
33
+  storagePolicy: cleartext
34
+data:
35
+  cidr: {{ data['network']['vlan_network_data']['oob']['subnet'] }}
36
+  routes:
37
+    - subnet: '0.0.0.0/0'
38
+      gateway: {{ data['network']['vlan_network_data']['oob']['gateway'] }}
39
+      metric: 100
40
+  ranges:
41
+    - type: static
42
+      start: {{ data['network']['vlan_network_data']['oob']['static_start'] }}
43
+      end: {{ data['network']['vlan_network_data']['oob']['static_end'] }}
44
+...
45
+
46
+---
47
+schema: 'drydock/NetworkLink/v1'
48
+metadata:
49
+  schema: 'metadata/Document/v1'
50
+  name: pxe
51
+  layeringDefinition:
52
+    abstract: false
53
+    layer: site
54
+  storagePolicy: cleartext
55
+data:
56
+  bonding:
57
+    mode: disabled
58
+  mtu: 1500
59
+  linkspeed: auto
60
+  trunking:
61
+    mode: disabled
62
+    default_network: pxe
63
+  allowed_networks:
64
+    - pxe
65
+...
66
+
67
+---
68
+schema: 'drydock/Network/v1'
69
+metadata:
70
+  schema: 'metadata/Document/v1'
71
+  name: pxe
72
+  layeringDefinition:
73
+    abstract: false
74
+    layer: site
75
+    parentSelector:
76
+      network_role: pxe
77
+      topology: cruiser
78
+    actions:
79
+      - method: merge
80
+        path: .
81
+  storagePolicy: cleartext
82
+data:
83
+  cidr: {{ data['network']['vlan_network_data']['pxe']['subnet'] }}
84
+  routes:
85
+{% for other_subnet in data['network']['vlan_network_data']['pxe']['routes'] %}
86
+    - subnet: {{ other_subnet }}
87
+      gateway: {{ data['network']['vlan_network_data']['pxe']['gateway'] }}
88
+      metric: 100
89
+{% endfor %}
90
+  ranges:
91
+    - type: reserved
92
+      start: {{ data['network']['vlan_network_data']['pxe']['reserved_start'] }}
93
+      end: {{ data['network']['vlan_network_data']['pxe']['reserved_end'] }}
94
+    - type: static
95
+      start: {{ data['network']['vlan_network_data']['pxe']['static_start'] }}
96
+      end: {{ data['network']['vlan_network_data']['pxe']['static_end'] }}
97
+    - type: dhcp
98
+      start: {{ data['network']['vlan_network_data']['pxe']['dhcp_start'] }}
99
+      end: {{ data['network']['vlan_network_data']['pxe']['dhcp_end'] }}
100
+...
101
+
102
+---
103
+schema: 'drydock/NetworkLink/v1'
104
+metadata:
105
+  schema: 'metadata/Document/v1'
106
+  name: data
107
+  layeringDefinition:
108
+    abstract: false
109
+    layer: site
110
+  storagePolicy: cleartext
111
+data:
112
+  bonding:
113
+    mode: 802.3ad
114
+    hash: layer3+4
115
+    peer_rate: fast
116
+    mon_rate: 100
117
+    up_delay: 1000
118
+    down_delay: 3000
119
+  # NEWSITE-CHANGEME: Ensure the network switches in the environment are
120
+  # configured for this MTU or greater. Even if switches are configured for or
121
+  # can support a slightly higher MTU, there is no need (and negliable benefit)
122
+  # to squeeze every last byte into the MTU (e.g., 9216 vs 9100). Leave MTU at
123
+  # 9100 for maximum compatibility.
124
+  mtu: 9100
125
+  linkspeed: auto
126
+  trunking:
127
+    mode: 802.1q
128
+  allowed_networks:
129
+    - oam
130
+    - storage
131
+    - overlay
132
+    - calico
133
+...
134
+
135
+---
136
+schema: 'drydock/Network/v1'
137
+metadata:
138
+  schema: 'metadata/Document/v1'
139
+  name: oam
140
+  layeringDefinition:
141
+    abstract: false
142
+    layer: 'site'
143
+    parentSelector:
144
+      network_role: oam
145
+      topology: cruiser
146
+    actions:
147
+      - method: merge
148
+        path: .
149
+  storagePolicy: cleartext
150
+data:
151
+  cidr: {{ data['network']['vlan_network_data']['oam']['subnet'] }}
152
+{% set flag = [0] %}
153
+{% for route in data['network']['vlan_network_data']['oam']['routes'] %}
154
+{% if flag[0] == 0 %}
155
+  routes:
156
+{% endif %}
157
+{% if flag.append(flag.pop() + 1) %} {% endif %}
158
+    - subnet: {{ route }}
159
+      gateway: {{ data['network']['vlan_network_data']['oam']['gateway'] }}
160
+      metric: 100
161
+{% endfor %}
162
+{% if flag[0] == 0 %}
163
+  routes:[]
164
+{% endif %}
165
+  ranges:
166
+    - type: reserved
167
+      start: {{ data['network']['vlan_network_data']['oam']['reserved_start'] }}
168
+      end: {{ data['network']['vlan_network_data']['oam']['reserved_end'] }}
169
+    - type: static
170
+      start: {{ data['network']['vlan_network_data']['oam']['static_start'] }}
171
+      end: {{ data['network']['vlan_network_data']['oam']['static_end'] }}
172
+...
173
+
174
+---
175
+schema: 'drydock/Network/v1'
176
+metadata:
177
+  schema: 'metadata/Document/v1'
178
+  name: storage
179
+  layeringDefinition:
180
+    abstract: false
181
+    layer: site
182
+    parentSelector:
183
+      network_role: storage
184
+      topology: cruiser
185
+    actions:
186
+      - method: merge
187
+        path: .
188
+  storagePolicy: cleartext
189
+data:
190
+  cidr: {{ data['network']['vlan_network_data']['storage']['subnet'] }}
191
+  ranges:
192
+    - type: reserved
193
+      start: {{ data['network']['vlan_network_data']['storage']['reserved_start'] }}
194
+      end: {{ data['network']['vlan_network_data']['storage']['reserved_end'] }}
195
+    - type: static
196
+      start: {{ data['network']['vlan_network_data']['storage']['static_start'] }}
197
+      end: {{ data['network']['vlan_network_data']['storage']['static_end'] }}
198
+...
199
+
200
+---
201
+schema: 'drydock/Network/v1'
202
+metadata:
203
+  schema: 'metadata/Document/v1'
204
+  name: overlay
205
+  layeringDefinition:
206
+    abstract: false
207
+    layer: site
208
+    parentSelector:
209
+      network_role: os-overlay
210
+      topology: cruiser
211
+    actions:
212
+      - method: merge
213
+        path: .
214
+  storagePolicy: cleartext
215
+data:
216
+  cidr: {{ data['network']['vlan_network_data']['overlay']['subnet'] }}
217
+  ranges:
218
+    - type: reserved
219
+      start: {{ data['network']['vlan_network_data']['overlay']['reserved_start'] }}
220
+      end: {{ data['network']['vlan_network_data']['overlay']['reserved_end'] }}
221
+    - type: static
222
+      start: {{ data['network']['vlan_network_data']['overlay']['static_start'] }}
223
+      end: {{ data['network']['vlan_network_data']['overlay']['static_end'] }}
224
+...
225
+
226
+---
227
+schema: 'drydock/Network/v1'
228
+metadata:
229
+  schema: 'metadata/Document/v1'
230
+  name: calico
231
+  layeringDefinition:
232
+    abstract: false
233
+    layer: site
234
+    parentSelector:
235
+      network_role: calico
236
+      topology: cruiser
237
+    actions:
238
+      - method: merge
239
+        path: .
240
+  storagePolicy: cleartext
241
+data:
242
+  cidr: {{ data['network']['vlan_network_data']['calico']['subnet'] }}
243
+  ranges:
244
+    - type: reserved
245
+      start: {{ data['network']['vlan_network_data']['calico']['reserved_start'] }}
246
+      end: {{ data['network']['vlan_network_data']['calico']['reserved_end'] }}
247
+    - type: static
248
+      start: {{ data['network']['vlan_network_data']['calico']['static_start'] }}
249
+      end: {{ data['network']['vlan_network_data']['calico']['static_end'] }}
250
+...
251
+

+ 187
- 0
spyglass/examples/templates/pki/pki-catalogue.yaml.j2 View File

@@ -0,0 +1,187 @@
1
+---
2
+schema: promenade/PKICatalog/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: cluster-certificates
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+  storagePolicy: cleartext
10
+data:
11
+  certificate_authorities:
12
+    kubernetes:
13
+      description: CA for Kubernetes components
14
+      certificates:
15
+        - document_name: apiserver
16
+          description: Service certificate for Kubernetes apiserver
17
+          common_name: apiserver
18
+          hosts:
19
+            - localhost
20
+            - 127.0.0.1
21
+            - 10.96.0.1
22
+          kubernetes_service_names:
23
+            - kubernetes.default.svc.cluster.local
24
+{% for racks in data['baremetal'].keys()%}
25
+{% for host in data['baremetal'][racks].keys()%}
26
+{% if data['baremetal'][racks][host]['type'] == 'genesis' %}
27
+
28
+        - document_name: kubelet-genesis
29
+          common_name: system:node:{{ host }}
30
+          hosts:
31
+            - {{ host }}
32
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
33
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
34
+          groups:
35
+            - system:nodes
36
+{% endif %}
37
+{%endfor%}
38
+{%endfor%}
39
+{% for racks in data['baremetal'].keys()%}
40
+{% for host in data['baremetal'][racks].keys()%}
41
+        - document_name: kubelet-{{ host }}
42
+          common_name: system:node:{{ host }}
43
+          hosts:
44
+            - {{ host }}
45
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
46
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
47
+          groups:
48
+            - system:nodes
49
+{%endfor%}
50
+{%endfor%}
51
+        - document_name: scheduler
52
+          description: Service certificate for Kubernetes scheduler
53
+          common_name: system:kube-scheduler
54
+        - document_name: controller-manager
55
+          description: certificate for controller-manager
56
+          common_name: system:kube-controller-manager
57
+        - document_name: admin
58
+          common_name: admin
59
+          groups:
60
+            - system:masters
61
+        - document_name: armada
62
+          common_name: armada
63
+          groups:
64
+            - system:masters
65
+    kubernetes-etcd:
66
+      description: Certificates for Kubernetes's etcd servers
67
+      certificates:
68
+        - document_name: apiserver-etcd
69
+          description: etcd client certificate for use by Kubernetes apiserver
70
+          common_name: apiserver
71
+          # NOTE(mark-burnett): hosts not required for client certificates
72
+        - document_name: kubernetes-etcd-anchor
73
+          description: anchor
74
+          common_name: anchor
75
+{% for racks in data['baremetal'].keys()%}
76
+{% for host in data['baremetal'][racks].keys()%}
77
+{% if data['baremetal'][racks][host]['type'] == 'genesis' %}
78
+        - document_name: kubernetes-etcd-genesis
79
+          common_name: kubernetes-etcd-genesis
80
+          hosts:
81
+            - {{ host }}
82
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
83
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
84
+            - 127.0.0.1
85
+            - localhost
86
+            - kubernetes-etcd.kube-system.svc.cluster.local
87
+            - 10.96.0.2
88
+{% endif %}
89
+{%endfor%}
90
+{%endfor%}
91
+{% for racks in data['baremetal'].keys()%}
92
+{% for host in data['baremetal'][racks].keys()%}
93
+{% if data['baremetal'][racks][host]['type'] == 'controller' or data['baremetal'][racks][host]['type'] == 'genesis'%}
94
+        - document_name: kubernetes-etcd-{{ host }}
95
+          common_name: kubernetes-etcd-{{ host }}
96
+          hosts:
97
+            - {{ host }}
98
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
99
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
100
+            - 127.0.0.1
101
+            - localhost
102
+            - kubernetes-etcd.kube-system.svc.cluster.local
103
+            - 10.96.0.2
104
+{% endif %}
105
+{%endfor%}
106
+{%endfor%}
107
+{% for racks in data['baremetal'].keys()%}
108
+{% for host in data['baremetal'][racks].keys()%}
109
+{% if data['baremetal'][racks][host]['type'] == 'genesis' %}
110
+    kubernetes-etcd-peer:
111
+      certificates:
112
+        - document_name: kubernetes-etcd-genesis-peer
113
+          common_name: kubernetes-etcd-genesis-peer
114
+          hosts:
115
+            - {{ host }}
116
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
117
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
118
+            - 127.0.0.1
119
+            - localhost
120
+            - kubernetes-etcd.kube-system.svc.cluster.local
121
+            - 10.96.0.2
122
+{% endif %}
123
+{%endfor%}
124
+{%endfor%}
125
+{% for racks in data['baremetal'].keys()%}
126
+{% for host in data['baremetal'][racks].keys()%}
127
+{% if data['baremetal'][racks][host]['type'] == 'controller' or data['baremetal'][racks][host]['type'] == 'genesis' %}
128
+        - document_name: kubernetes-etcd-{{ host }}-peer
129
+          common_name: kubernetes-etcd-{{ host }}-peer
130
+          hosts:
131
+            - {{ host }}
132
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
133
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
134
+            - 127.0.0.1
135
+            - localhost
136
+            - kubernetes-etcd.kube-system.svc.cluster.local
137
+            - 10.96.0.2
138
+{% endif %}
139
+{%endfor%}
140
+{%endfor%}
141
+    ksn-etcd:
142
+      description: Certificates for Calico etcd client traffic
143
+      certificates:
144
+        - document_name: ksn-etcd-anchor
145
+          description: anchor
146
+          common_name: anchor
147
+{% for racks in data['baremetal'].keys()%}
148
+{% for host in data['baremetal'][racks].keys()%}
149
+{% if data['baremetal'][racks][host]['type'] == 'controller' or data['baremetal'][racks][host]['type'] == 'genesis' %}
150
+        - document_name: ksn-etcd-{{ host }}
151
+          common_name: ksn-etcd-{{ host }}
152
+          hosts:
153
+            - {{ host }}
154
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
155
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
156
+            - 127.0.0.1
157
+            - localhost
158
+            - 10.96.232.136
159
+{% endif %}
160
+{%endfor%}
161
+{%endfor%}
162
+        - document_name: ksn-node
163
+          common_name: calcico-node
164
+    ksn-etcd-peer:
165
+      description: Certificates for Calico etcd clients
166
+      certificates:
167
+{% for racks in data['baremetal'].keys()%}
168
+{% for host in data['baremetal'][racks].keys()%}
169
+{% if data['baremetal'][racks][host]['type'] == 'controller' or data['baremetal'][racks][host]['type'] == 'genesis' %}
170
+        - document_name: ksn-etcd-{{ host }}-peer
171
+          common_name: ksn-etcd-{{ host }}-peer
172
+          hosts:
173
+            - {{ host }}
174
+            - {{ data['baremetal'][racks][host]['ip']['oam'] }}
175
+            - {{ data['baremetal'][racks][host]['ip']['ksn']}}
176
+            - 127.0.0.1
177
+            - localhost
178
+            - 10.96.232.136
179
+{% endif %}
180
+{%endfor%}
181
+{%endfor%}
182
+        - document_name: ksn-node-peer
183
+          common_name: calico-node-peer
184
+  keypairs:
185
+    - name: service-account
186
+      description: Service account signing key for use by Kubernetes controller-manager.
187
+...

+ 40
- 0
spyglass/examples/templates/profile/genesis.yaml.j2 View File

@@ -0,0 +1,40 @@
1
+---
2
+schema: promenade/Genesis/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: genesis-site
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+    parentSelector:
10
+      name: genesis-global
11
+    actions:
12
+      - method: merge
13
+        path: .
14
+  storagePolicy: cleartext
15
+data:
16
+  labels:
17
+    dynamic:
18
+      - beta.kubernetes.io/fluentd-ds-ready=true
19
+      - calico-etcd=enabled
20
+      - ceph-mds=enabled
21
+      - ceph-mon=enabled
22
+      - ceph-osd=enabled
23
+      - ceph-rgw=enabled
24
+      - ceph-mgr=enabled
25
+      - ceph-bootstrap=enabled
26
+      - kube-dns=enabled
27
+      - kube-ingress=enabled
28
+      - kubernetes-apiserver=enabled
29
+      - kubernetes-controller-manager=enabled
30
+      - kubernetes-etcd=enabled
31
+      - kubernetes-scheduler=enabled
32
+      - promenade-genesis=enabled
33
+      - ucp-control-plane=enabled
34
+      - maas-control-plane=enabled
35
+      - ceph-osd-bootstrap=enabled
36
+      - openstack-control-plane=enabled
37
+      - openvswitch=enabled
38
+      - openstack-l3-agent=enabled
39
+      - node-exporter=enabled
40
+...

+ 76
- 0
spyglass/examples/templates/profile/hardware/dell_r720.yaml.j2 View File

@@ -0,0 +1,76 @@
1
+---
2
+schema: 'drydock/HardwareProfile/v1'
3
+metadata:
4
+  schema: 'metadata/Document/v1'
5
+  name: dell_r720
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+  storagePolicy: cleartext
10
+data:
11
+  # Vendor of the server chassis
12
+  vendor: DELL
13
+  # Generation of the chassis model
14
+  generation: '8'
15
+  # Version of the chassis model within its generation - not version of the hardware definition
16
+  hw_version: '3'
17
+  # The certified version of the chassis BIOS
18
+  bios_version: '2.2.3'
19
+  # Mode of the default boot of hardware - bios, uefi
20
+  boot_mode: bios
21
+  # Protocol of boot of the hardware - pxe, usb, hdd
22
+  bootstrap_protocol: pxe
23
+  # Which interface to use for network booting within the OOB manager, not OS device
24
+  pxe_interface: 0
25
+  # Map hardware addresses to aliases/roles to allow a mix of hardware configs
26
+  # in a site to result in a consistent configuration
27
+  device_aliases:
28
+    ## network
29
+    # eno1
30
+    pxe_nic01:
31
+      address: '0000:01:00.0'
32
+      # type could identify expected hardware - used for hardware manifest validation
33
+      dev_type: 'I350 Gigabit Network Connection'
34
+      bus_type: 'pci'
35
+    # enp67s0f0
36
+    data_nic01:
37
+      address: '0000:43:00.0'
38
+      dev_type: 'Ethernet 10G 2P X520 Adapter'
39
+      bus_type: 'pci'
40
+    # enp67s0f1
41
+    data_nic02:
42
+      address: '0000:43:00.1'
43
+      dev_type: 'Ethernet 10G 2P X520 Adapter'
44
+      bus_type: 'pci'
45
+    # enp68s0f0
46
+    data_nic03:
47
+      address: '0000:44:00.0'
48
+      dev_type: 'Ethernet 10G 2P X520 Adapter'
49
+      bus_type: 'pci'
50
+    # enp68s0f1
51
+    data_nic04:
52
+      address: '0000:44:00.1'
53
+      dev_type: 'Ethernet 10G 2P X520 Adapter'
54
+      bus_type: 'pci'
55
+    ## storage
56
+    # /dev/sda
57
+    bootdisk:
58
+      address: '0:2.0.0'
59
+      dev_type: 'PERC H710P'
60
+      bus_type: 'scsi'
61
+    # /dev/sdb
62
+    cephjournal1:
63
+      address: '0:2.1.0'
64
+      dev_type: 'PERC H710P'
65
+      bus_type: 'scsi'
66
+    # /dev/sdc
67
+    cephjournal2:
68
+      address: '0:2.2.0'
69
+      dev_type: 'PERC H710P'
70
+      bus_type: 'scsi'
71
+    # /dev/sdc
72
+    ephemeral:
73
+      address: '0:2.3.0'
74
+      dev_type: 'PERC H710P'
75
+      bus_type: 'scsi'
76
+...

+ 270
- 0
spyglass/examples/templates/profile/host/cp_r720.yaml.j2 View File

@@ -0,0 +1,270 @@
1
+---
2
+# The primary control plane host profile for Airship for DELL R720s, and
3
+# should not need to be altered if you are using matching HW. The active
4
+# participants in the Ceph cluster run on this profile. Other control plane
5
+# services are not affected by primary vs secondary designation.
6
+schema: drydock/HostProfile/v1
7
+metadata:
8
+  schema: metadata/Document/v1
9
+  name: cp_r720-primary
10
+  storagePolicy: cleartext
11
+  layeringDefinition:
12
+    abstract: false
13
+    layer: site
14
+    parentSelector:
15
+      hosttype: cp-global
16
+    actions:
17
+      - method: replace
18
+        path: .interfaces
19
+      - method: replace
20
+        path: .storage
21
+      - method: merge
22
+        path: .
23
+data:
24
+  hardware_profile: dell_r720
25
+
26
+  primary_network: oam
27
+  interfaces:
28
+    pxe:
29
+      device_link: pxe
30
+      slaves:
31
+        - pxe_nic01
32
+      networks:
33
+        - pxe
34
+    bond0:
35
+      device_link: data
36
+      slaves:
37
+        - data_nic01
38
+        - data_nic02
39
+        - data_nic03
40
+        - data_nic04
41
+      networks:
42
+        - oam
43
+        - storage
44
+        - overlay
45
+        - calico
46
+
47
+  storage:
48
+    physical_devices:
49
+      bootdisk:
50
+        labels:
51
+          bootdrive: 'true'
52
+        partitions:
53
+          - name: 'root'
54
+            size: '30g'
55
+            bootable: true
56
+            filesystem:
57
+              mountpoint: '/'
58
+              fstype: 'ext4'
59
+              mount_options: 'defaults'
60
+          - name: 'boot'
61
+            size: '1g'
62
+            filesystem:
63
+              mountpoint: '/boot'
64
+              fstype: 'ext4'
65
+              mount_options: 'defaults'
66
+          - name: 'var_log'
67
+            size: '100g'
68
+            filesystem:
69
+              mountpoint: '/var/log'
70
+              fstype: 'ext4'
71
+              mount_options: 'defaults'
72
+          - name: 'var'
73
+            size: '>100g'
74
+            filesystem:
75
+              mountpoint: '/var'
76
+              fstype: 'ext4'
77
+              mount_options: 'defaults'
78
+
79
+      cephjournal1:
80
+        partitions:
81
+          - name: 'ceph-j1'
82
+            size: '10g'
83
+          - name: 'ceph-j2'
84
+            size: '10g'
85
+          - name: 'ceph-j3'
86
+            size: '10g'
87
+          - name: 'ceph-j4'
88
+            size: '10g'
89
+      cephjournal2:
90
+        partitions:
91
+          - name: 'ceph-j5'
92
+            size: '10g'
93
+          - name: 'ceph-j6'
94
+            size: '10g'
95
+          - name: 'ceph-j7'
96
+            size: '10g'
97
+          - name: 'ceph-j8'
98
+            size: '10g'
99
+
100
+  platform:
101
+    kernel: 'hwe-16.04'
102
+    kernel_params:
103
+      console: 'ttyS1,115200n8'
104
+
105
+  metadata:
106
+    owner_data:
107
+      openstack-l3-agent: enabled
108
+...
109
+---
110
+schema: drydock/HostProfile/v1
111
+metadata:
112
+  schema: metadata/Document/v1
113
+  name: cp_r740-secondary
114
+  storagePolicy: cleartext
115
+  layeringDefinition:
116
+    abstract: false
117
+    layer: site
118
+    parentSelector:
119
+      hosttype: cp-global
120
+    actions:
121
+      - method: replace
122
+        path: .interfaces
123
+      - method: replace
124
+        path: .storage
125
+      - method: replace
126
+        path: .metadata.owner_data
127
+      - method: merge
128
+        path: .
129
+data:
130
+  hardware_profile: dell_r720
131
+
132
+  primary_network: oam
133
+  interfaces:
134
+    pxe:
135
+      device_link: pxe
136
+      slaves:
137
+        - pxe_nic01
138
+      networks:
139
+        - pxe
140
+    bond0:
141
+      device_link: data
142
+      slaves:
143
+        - data_nic01
144
+        - data_nic02
145
+        - data_nic03
146
+        - data_nic04
147
+      networks:
148
+        - oam
149
+        - storage
150
+        - overlay
151
+        - calico
152
+
153
+  storage:
154
+    physical_devices:
155
+      bootdisk:
156
+        labels:
157
+          bootdrive: 'true'
158
+        partitions:
159
+          - name: 'root'
160
+            size: '30g'
161
+            bootable: true
162
+            filesystem:
163
+              mountpoint: '/'
164
+              fstype: 'ext4'
165
+              mount_options: 'defaults'
166
+          - name: 'boot'
167
+            size: '1g'
168
+            filesystem:
169
+              mountpoint: '/boot'
170
+              fstype: 'ext4'
171
+              mount_options: 'defaults'
172
+          - name: 'var_log'
173
+            size: '100g'
174
+            filesystem:
175
+              mountpoint: '/var/log'
176
+              fstype: 'ext4'
177
+              mount_options: 'defaults'
178
+          - name: 'var'
179
+            size: '>100g'
180
+            filesystem:
181
+              mountpoint: '/var'
182
+              fstype: 'ext4'
183
+              mount_options: 'defaults'
184
+
185
+      cephjournal1:
186
+        partitions:
187
+          - name: 'ceph-j1'
188
+            size: '10g'
189
+          - name: 'ceph-j2'
190
+            size: '10g'
191
+          - name: 'ceph-j3'
192
+            size: '10g'
193
+          - name: 'ceph-j4'
194
+            size: '10g'
195
+      cephjournal2:
196
+        partitions:
197
+          - name: 'ceph-j5'
198
+            size: '10g'
199
+          - name: 'ceph-j6'
200
+            size: '10g'
201
+          - name: 'ceph-j7'
202
+            size: '10g'
203
+          - name: 'ceph-j8'
204
+            size: '10g'
205
+
206
+  platform:
207
+    kernel: 'hwe-16.04'
208
+    kernel_params:
209
+      console: 'ttyS1,115200n8'
210
+
211
+  metadata:
212
+    owner_data:
213
+      control-plane: enabled
214
+      ucp-control-plane: enabled
215
+      openstack-control-plane: enabled
216
+      openstack-heat: enabled
217
+      openstack-keystone: enabled
218
+      openstack-rabbitmq: enabled
219
+      openstack-dns-helper: enabled
220
+      openstack-mariadb: enabled
221
+      openstack-nova-control: enabled
222
+      # openstack-etcd: enabled
223
+      openstack-mistral: enabled
224
+      openstack-memcached: enabled
225
+      openstack-glance: enabled
226
+      openstack-horizon: enabled
227
+      openstack-cinder-control: enabled
228
+      openstack-cinder-volume: control
229
+      openstack-neutron: enabled
230
+      openvswitch: enabled
231
+      ucp-barbican: enabled
232
+      # ceph-mon: enabled
233
+      ceph-mgr: enabled
234
+      ceph-osd: enabled
235
+      ceph-mds: enabled
236
+      ceph-rgw: enabled
237
+      ucp-maas: enabled
238
+      kube-dns: enabled
239
+      tenant-ceph-control-plane: enabled
240
+      # tenant-ceph-mon: enabled
241
+      tenant-ceph-rgw: enabled
242
+      tenant-ceph-mgr: enabled
243
+      kubernetes-apiserver: enabled
244
+      kubernetes-controller-manager: enabled
245
+      # kubernetes-etcd: enabled
246
+      kubernetes-scheduler: enabled
247
+      tiller-helm: enabled
248
+      # kube-etcd: enabled
249
+      calico-policy: enabled
250
+      calico-node: enabled
251
+      # calico-etcd: enabled
252
+      ucp-armada: enabled
253
+      ucp-drydock: enabled
254
+      ucp-deckhand: enabled
255
+      ucp-shipyard: enabled
256
+      IAM: enabled
257
+      ucp-promenade: enabled
258
+      prometheus-server: enabled
259
+      prometheus-client: enabled
260
+      fluentd: enabled
261
+      influxdb: enabled
262
+      kibana: enabled
263
+      elasticsearch-client: enabled
264
+      elasticsearch-master: enabled
265
+      elasticsearch-data: enabled
266
+      postgresql: enabled
267
+      kube-ingress: enabled
268
+      beta.kubernetes.io/fluentd-ds-ready: 'true'
269
+      node-exporter: enabled
270
+...

+ 103
- 0
spyglass/examples/templates/profile/host/dp_r720.yaml.j2 View File

@@ -0,0 +1,103 @@
1
+---
2
+# The data plane host profile for Airship for DELL R720s, and should
3
+# not need to be altered if you are using matching HW. The host profile is setup
4
+# for cpu isolation (for nova pinning), hugepages, and sr-iov.
5
+schema: drydock/HostProfile/v1
6
+metadata:
7
+  schema: metadata/Document/v1
8
+  name: dp_r720
9
+  storagePolicy: cleartext
10
+  layeringDefinition:
11
+    abstract: false
12
+    layer: site
13
+    parentSelector:
14
+      hosttype: dp-global
15
+    actions:
16
+      - method: replace
17
+        path: .interfaces
18
+      - method: replace
19
+        path: .storage
20
+      - method: merge
21
+        path: .
22
+data:
23
+  hardware_profile: dell_r720
24
+
25
+  primary_network: oam
26
+  interfaces:
27
+    pxe:
28
+      device_link: pxe
29
+      slaves:
30
+        - pxe_nic01
31
+      networks:
32
+        - pxe
33
+    bond0:
34
+      device_link: data
35
+      slaves:
36
+        - data_nic01
37
+        - data_nic02
38
+        - data_nic03
39
+        - data_nic04
40
+      networks:
41
+        - oam
42
+        - storage
43
+        - overlay
44
+        - calico
45
+
46
+  storage:
47
+    physical_devices:
48
+      bootdisk:
49
+        labels:
50
+          bootdrive: 'true'
51
+        partitions:
52
+          - name: 'root'
53
+            size: '30g'
54
+            bootable: true
55
+            filesystem:
56
+              mountpoint: '/'
57
+              fstype: 'ext4'
58
+              mount_options: 'defaults'
59
+          - name: 'boot'
60
+            size: '1g'
61
+            filesystem:
62
+              mountpoint: '/boot'
63
+              fstype: 'ext4'
64
+              mount_options: 'defaults'
65
+          - name: 'var_log'
66
+            size: '100g'
67
+            filesystem:
68
+              mountpoint: '/var/log'
69
+              fstype: 'ext4'
70
+              mount_options: 'defaults'
71
+          - name: 'var'
72
+            size: '>100g'
73
+            filesystem:
74
+              mountpoint: '/var'
75
+              fstype: 'ext4'
76
+              mount_options: 'defaults'
77
+
78
+      cephjournal1:
79
+        partitions:
80
+          - name: 'ceph-j1'
81
+            size: '10g'
82
+          - name: 'ceph-j2'
83
+            size: '10g'
84
+      cephjournal2:
85
+        partitions:
86
+          - name: 'ceph-j3'
87
+            size: '10g'
88
+          - name: 'ceph-j4'
89
+            size: '10g'
90
+
91
+      ephemeral:
92
+        partitions:
93
+          - name: 'nova'
94
+            size: '99%'
95
+            filesystem:
96
+              mountpoint: '/var/lib/nova'
97
+              fstype: 'ext4'
98
+              mount_options: 'defaults'
99
+  platform:
100
+    kernel: 'hwe-16.04'
101
+    kernel_params:
102
+      console: 'ttyS1,115200n8'
103
+...

+ 35
- 0
spyglass/examples/templates/profile/region.yaml.j2 View File

@@ -0,0 +1,35 @@
1
+---
2
+schema: 'drydock/Region/v1'
3
+metadata:
4
+  schema: 'metadata/Document/v1'
5
+  name: {{ data['region_name'] }}
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+  storagePolicy: cleartext
10
+  substitutions:
11
+    - dest:
12
+        path: .authorized_keys[0]
13
+      src:
14
+        schema: deckhand/PublicKey/v1
15
+        name: jenkins_ssh_public_key
16
+        path: .
17
+    - dest:
18
+        path: .authorized_keys[1]
19
+      src:
20
+        schema: deckhand/PublicKey/v1
21
+        name: {{ data['region_name'] }}_ssh_public_key
22
+        path: .
23
+    - dest:
24
+        path: .repositories.main_archive
25
+      src:
26
+        schema: pegleg/SoftwareVersions/v1
27
+        name: software-versions
28
+        path: .packages.repositories.main_archive
29
+data:
30
+  tag_definitions: []
31
+  authorized_keys: []
32
+  repositories:
33
+      remove_unlisted: true
34
+...
35
+

+ 2806
- 0
spyglass/examples/templates/secrets/certificates/certificates.yaml.j2
File diff suppressed because it is too large
View File


+ 135
- 0
spyglass/examples/templates/secrets/certificates/ingress.yaml.j2 View File

@@ -0,0 +1,135 @@
1
+---
2
+# Example manifest for ingress cert.
3
+# Shall be replaced with proper/valid set.
4
+# Self-signed certs are not supported.
5
+metadata:
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+  name: ingress-crt
10
+  schema: metadata/Document/v1
11
+  labels:
12
+    name: ingress-crt-site
13
+  storagePolicy: cleartext
14
+schema: deckhand/Certificate/v1
15
+data: |
16
+  -----BEGIN CERTIFICATE-----
17
+  MIIFKzCCA5OgAwIBAgIMW2h6FCcFdKeaw3vnMA0GCSqGSIb3DQEBCwUAMBIxEDAO
18
+  BgNVBAMTB0FpcnNoaXAwHhcNMTgwODA2MTY0MDUyWhcNMTkwODA2MTY0MDUyWjBJ
19
+  MTUwMwYDVQQDEyxpbmdyZXNzLmFpcnNoaXAtc2Vhd29ydGh5LmF0bGFudGFmb3Vu
20
+  ZHJ5LmNvbTEQMA4GA1UEChMHQWlyc2hpcDCCAaIwDQYJKoZIhvcNAQEBBQADggGP
21
+  ADCCAYoCggGBALvNHm/G/ylh6aPcvrhOcb4qz1BjcNtnxH8bzZng/rMeX3W2AzjC
22
+  r2JloJcDvOLBp/TkLOZPImnFW2/GCwktxPgXZuBTPzFV50g77KsPFw0fn3Si7+bs
23
+  F22tLhdOGk6MQj/WW4pKGHqdw1/VbPwOHBT+I4/scR1L2SZxYtSFIKGenHJH+PMV
24
+  bCdwnNOR80F8KRzK5iZs/r6S/QqVheieARSWWnk2+TtkM1BloGOhLSd+ZkWh9VO1
25
+  eOnZowkaDAJwD/G6zoSr5n+beaXzDnEcoVXFSwd4FLoV+om77o92XmZ4rVw0vTMO
26
+  k6jVwmkdT+dM2K2hLUG/TXWoV2/Qms70gzDOs85RtAkTPe4Ohtdpr51Q0hd35TKG
27
+  YLKzX/OPblD68iYJYSBvMPpAVTbFYVPW1AQx8wWfannYbMoeL8XTEOKfkqm90YP9
28
+  EhIdtmw4D7GZxlzG5FXXutmT9sqLfqlRu/RynAhBP8NQvw74WumhOe8r7GhCwgzC
29
+  gaPLGjeekoS6LQIDAQABo4IBSDCCAUQwDAYDVR0TAQH/BAIwADCBzQYDVR0RBIHF
30
+  MIHCgixpbmdyZXNzLmFpcnNoaXAtc2Vhd29ydGh5LmF0bGFudGFmb3VuZHJ5LmNv
31
+  bYIta2V5c3RvbmUuYWlyc2hpcC1zZWF3b3J0aHkuYXRsYW50YWZvdW5kcnkuY29t
32
+  gilub3ZhLmFpcnNoaXAtc2Vhd29ydGh5LmF0bGFudGFmb3VuZHJ5LmNvbYIsaG9y
33
+  aXpvbi5haXJzaGlwLXNlYXdvcnRoeS5hdGxhbnRhZm91bmRyeS5jb22HBAoXFQuH
34
+  BAoXFgswEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/BAUDAwegADAdBgNV
35
+  HQ4EFgQUfTAjNgn/1U1Uh1MJDYT2m4dzhsYwHwYDVR0jBBgwFoAUJFuXPZo6RzfE
36
+  BlJjnnk5jhcP4wIwDQYJKoZIhvcNAQELBQADggGBAE2ISWmrxqrledJI3aLaS9Yw
37
+  WsZc8O8CnIyLoxrE85vUubFjuI9ixC/6dJxl2iB1n0H8JgmFREox32Q4+kDJI8V/
38
+  X9x0PFpRzL7QEPrLZhW94Yis3sOphLW0rf0t06ZepdHHeodYJu1pVMDmLq6bKXdX
39
+  vo+/WwKnZBXC1qPbXJByv/CN9MtViXOnBGORFRTJPb6U8379LNWclJ/LW12yTwNk
40
+  JGIbZU61Vxu+2nLIabmmRoODH2jomgMOMMzLgjT3Hvw3whe8GrUoxDiPYQVTDGNm
41
+  ly6m+5B1Nx06fkZazonozeaOhSQ7RblUSbo+w8TJmLRzD9ft7p4vpjBGxRADMcuF
42
+  DOjATgdZeisBUHTGEO0P6wJOBQuCFMX9AVl+u8ZpcuRaRaN+pBE6/BqcHBB6qV/N
43
+  w2DdNtP8BrJ3kJVNEDIo5oTbH5SToxgA4hWBV42M1rB+5vIMDKN3rwVDdNKWYhYc
44
+  VZpU3V9V6JzSW1O2w4Wu9PdbWJD9oSvC0qJgnjOXzg==
45
+  -----END CERTIFICATE-----
46
+...
47
+---
48
+metadata:
49
+  layeringDefinition:
50
+    abstract: false
51
+    layer: site
52
+  name: ingress-ca
53
+  schema: metadata/Document/v1
54
+  labels:
55
+    name: ingress-ca-site
56
+  storagePolicy: cleartext
57
+schema: deckhand/CertificateAuthority/v1
58
+data: |
59
+  -----BEGIN CERTIFICATE-----
60
+  MIID7TCCAlWgAwIBAgIMW2h3tgSwie0Ypx8eMA0GCSqGSIb3DQEBCwUAMBIxEDAO
61
+  BgNVBAMTB0FpcnNoaXAwHhcNMTgwODA2MTYzMDQ2WhcNMTkwODA2MTYzMDQ2WjAS
62
+  MRAwDgYDVQQDEwdBaXJzaGlwMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKC
63
+  AYEAny0Nqu9U2tXdCCTNzD2T62htMmBLg3CmzWajfbfFl7ALqzo3HgbbY3PxTHDE
64
+  OJ/lwdm0HkEaGfEDXhJd06WZsa8+fKGqhKXvZXwXx5mJ8LCGxz6xiaxwo9lnKe6V
65
+  o3YX7bJ5YIVxQ2jhvZo+dY8Z/buloi2Tp2HbqTejKULH9+qdiQTDXAnyR0NLqzJ0
66
+  YQ4v4yU3zix3nBi8z29lQekGO9quNEka3nw2n0Gxmq5z1bNALGCF5F759mVkB0uT
67
+  fPGF+zm9eqlqAgduYg7R+JYUumVHvIoRY454GtAdZHTJHJZP0gQSGJsLff8ROFpI
68
+  GVYsOZhJXU9Ihc5VBC5PMErbmCn0YkuxAWNOYBstZ8l+uY6YiPoFV5Ulc/8M0If+
69
+  T6jbqzWoFC+4ysgY95RKOw53S4o/T6AFwiIKIw0xp3UfHCf6kr5Y0+XdDn5CXpJB
70
+  d1KK3PoUWzPSsxcUMXvgKWT4x1vsCId21dn1SmVSOEBhM08VZfjd5bvL9Xjt/E0j
71
+  mUqDAgMBAAGjQzBBMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcEADAd
72
+  BgNVHQ4EFgQUJFuXPZo6RzfEBlJjnnk5jhcP4wIwDQYJKoZIhvcNAQELBQADggGB
73
+  AJaoEtnDoWUUs4nSSqIGcoCfpIO0oqVp8DvkBOcxz5Rz8vMVJSC24/UnuCD2Wknx
74
+  2V/E3edXIeRo7duhPtNCT7c8OKY/pJsZQTgOczn4rphoD1pmAIPZmpG6ssPadPiM
75
+  EP8xWJHZt8NXG7D5kJX2COvBvgNeWXL6MF7Tv8+t5xzt59Vitdb/7lm9Z6jjpvN+
76
+  zoG0pKx3XYESsnLAVAf00F+kWwds/3x3gQywUAQUDER0jliYUE5id+sojp357Cl9
77
+  XtY+8zSnTduuP8CfMhwv5p6j9xbqacfT7AzpQ6cy4xcQ7MA6JBQcxbaq4NtvIf6+
78
+  d/5N9d8LGnfXdCd9iwNy9Qk23Ea0SNhnk9F/NqGBPakU4TbHh4iTYMC/+hDGInpO
79
+  TIRelTidNBFNaIBg3Z0vsh0lDwbt/xhpXip+ZVBqKMTtktEceiVGru9cYUQA2tKI
80
+  XNoc5s0uQGMpdFzgED4lXZf+n7yGVMKohvi7Yn96HqujGIrVH6qThsI6m7pUSz40
81
+  +g==
82
+  -----END CERTIFICATE-----
83
+...
84
+---
85
+metadata:
86
+  layeringDefinition:
87
+    abstract: false
88
+    layer: site
89
+  name: ingress-key
90
+  schema: metadata/Document/v1
91
+  labels:
92
+    name: ingress-key-site
93
+  storagePolicy: cleartext
94
+schema: deckhand/CertificateKey/v1
95
+data: |
96
+  -----BEGIN RSA PRIVATE KEY-----
97
+  MIIG4wIBAAKCAYEAu80eb8b/KWHpo9y+uE5xvirPUGNw22fEfxvNmeD+sx5fdbYD
98
+  OMKvYmWglwO84sGn9OQs5k8iacVbb8YLCS3E+Bdm4FM/MVXnSDvsqw8XDR+fdKLv
99
+  5uwXba0uF04aToxCP9ZbikoYep3DX9Vs/A4cFP4jj+xxHUvZJnFi1IUgoZ6cckf4
100
+  8xVsJ3Cc05HzQXwpHMrmJmz+vpL9CpWF6J4BFJZaeTb5O2QzUGWgY6EtJ35mRaH1
101
+  U7V46dmjCRoMAnAP8brOhKvmf5t5pfMOcRyhVcVLB3gUuhX6ibvuj3ZeZnitXDS9
102
+  Mw6TqNXCaR1P50zYraEtQb9NdahXb9CazvSDMM6zzlG0CRM97g6G12mvnVDSF3fl
103
+  MoZgsrNf849uUPryJglhIG8w+kBVNsVhU9bUBDHzBZ9qedhsyh4vxdMQ4p+Sqb3R
104
+  g/0SEh22bDgPsZnGXMbkVde62ZP2yot+qVG79HKcCEE/w1C/Dvha6aE57yvsaELC
105
+  DMKBo8saN56ShLotAgMBAAECggGAYzZDhA1+sx/0zApL/xYB5NK83t0Ju/8fwX6w
106
+  qUBBjeLXz1mubgf7m2HQ6ragzLI9xpPcXHcl2PbYDT50ig7R5baHNK8FzUxyeKif
107
+  qOa56Mbx+C4zyqyi2+AHX2x1XVWfkhXuGip2sCA0HKalgqr5juWLZ/ci8rUlLLft
108
+  3BPQX1FpmL4I+HIyxsspLmQGPGwZVAqkd1xRX+BLKZJAQdlm/LdJaIvwMr4Glcx6
109
+  ZOe68QhHgzXCYsyV6gR9qstF2OvVuLa2mUc7EzYInFIFhXUdAAwmDqkuuLRdRQhf
110
+  Ur8nqQW33T0cG0GBUzgBI5YmSPJvTSzcPmeSyNVx2/Yb0pkuXtCw67oDcAsN4nW8
111
+  uls49E2RaiLJYsy5vPsX5aJNcAxw/CWLdadQ3ukviD/MDJbpTl4F52GOVYL6K4XH
112
+  g5TJjj7xzjmK3ldR/Kscg7HpCitQLGUYdgIsAFdspXf4aSIa68IjDrc5NsJZuMzc
113
+  PbVHrw7QYNfHY7VNdUlOVqH5lS3BAoHBANRqKrQXtnJmM006TCEJXdcN/5M685jz
114
+  +L4Ox0Rhrq8ROgcN5q/hjKb6kP/MccQ9voGQOl9TKEyinGNdTtyc/fuH7RNlQwpS
115
+  HT+vEzVEcrSe8UFs8c6oJnHFO72ylFcibFf56LvbI3L8BZXp7gPSPQkp5f1NWEZk
116
+  X5bUL4UNiOm0diltba/ofxywF0M9WGD00eqi0Q29JRlvun+355j06CENxRoonNZC
117
+  wk1evIxhhckP9zLjI2Ykb1hV6yzwPWtmyQKBwQDiVgru/B396KhzDhLl5AL+pBWA
118
+  GsfiCbmPLh6W6V5VzldB4+GlMRrJ4zSjZQ3/nvX5KepqjMn1N6LQpZQUI/YShCKE
119
+  mW0XMiAfbp2d23MRMjLD8L/bIoBHQOPkCaMjbmyDOlCagWakEvHJO/TieVgTmYk6
120
+  mtEYVjJFWI9OCNMAHdl8ovWr3p+8YbVZ8LLv5ZO/V1cIjczoNQ6p8LG/pPMTDLXM
121
+  ScN9a8z3f8LQLBHBlu0155xvt95PQLAon/x21kUCgcAvPVk36hoiQQZhw3hQ1JNx
122
+  E2TmanLobkHAiurYE11VA+DC1t2Z+fBc5la+/MnEWfL3P4srzgOlX3imRIcYWzXE
123
+  7crUyG1ray2kDxyXeRyFfN+srDzut8is/q81lfSVmEs+GY8f0DGHDfN0Dq1nXidC
124
+  1XWXqs7aANKdaZ0T2xm61+57ciG1wGAckjDqPEdecLQKmaEijBEnIgj5BH5WLwk8
125
+  6KIQGj4fDIPHzyzhj4LAX3ObdpZVzf6RR7JgsSEHtLkCgcBROW2dDC87MqZY++D+
126
+  TVBhz8LDgVjgHntQDc3+fGtVQcKAq+YLYU7qyrXWOWrHpGVDcK5mZHYJoVi1peY5
127
+  QBqL1I2KpoDGxT9P6GN6BgoKTsh3FsvTOVNtvrTJ3keEbJlWkrPgbrXGBeJtRC4C
128
+  pGdeSUg9FtgY8r4BsuFisLoAHbYyC008y5zpfusVBtNAUlQuY4qhUDoLzxafF/jB
129
+  /NEasgH/+SzFss0QuPHRwS7yGVaxdJfoY8TNDjrpqVhx0T0CgcEAvKG4UoWvT8gJ
130
+  pIeeAxxnv9yrMxgpntu4RXPDHgfX5tva6EaM3r3nLXjd9FVtlQ4cNBMhp9HNhS3a
131
+  dK+oEDcBysVxxfltlS2Bx0+gQf3WxgBCJwayKe3i/XCDza92EENgxTPmqB1LHiq5
132
+  2b5aOl2Y5fP0eX6UryxRc443c/ejMHw4lGwnno0qpRk9M9Ucqv5J96QCfAlBSQQS
133
+  gOG9cypL0kBWzCejn9W4av8HkM8Noqd7Tqul1onv/46OBaX51kt3
134
+  -----END RSA PRIVATE KEY-----
135
+...

+ 17
- 0
spyglass/examples/templates/site-definition.yaml.j2 View File

@@ -0,0 +1,17 @@
1
+---
2
+# High-level pegleg site definition file
3
+schema: pegleg/SiteDefinition/v1
4
+metadata:
5
+  schema: metadata/Document/v1
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+  # NEWSITE-CHANGEME: Replace with the site name
10
+  name: {{ data['region_name'] }}
11
+  storagePolicy: cleartext
12
+data:
13
+  # The type layer this site will delpoy with. Type layer is found in the
14
+  # aic-clcp-manifests repo.
15
+  site_type: {{ data['site_info']['sitetype'] }}
16
+...
17
+

+ 96
- 0
spyglass/examples/templates/software/charts/kubernetes/etcd.yaml.j2 View File

@@ -0,0 +1,96 @@
1
+---
2
+schema: armada/Chart/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: kubernetes-calico-etcd
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+    parentSelector:
10
+      name: kubernetes-calico-etcd-global
11
+    actions:
12
+      - method: merge
13
+        path: .
14
+  storagePolicy: cleartext
15
+  substitutions:
16
+{% set count = [0] %}
17
+{% for rack in data.baremetal.keys() %}
18
+{% for host in data["baremetal"][rack] %}
19
+{% if data["baremetal"][rack][host]["type"]  == 'controller' %}
20
+    - src:
21
+        schema: pegleg/CommonAddresses/v1
22
+        name: common-addresses
23
+        path: .masters[{{ count[0] }}].hostname
24
+      dest:
25
+        path: .values.nodes[{{ count[0] }}].name
26
+    - src:
27
+        schema: deckhand/Certificate/v1
28
+        name: calico-etcd-{{ host }}
29
+        path: .
30
+      dest:
31
+        path: .values.nodes[{{ count[0] }}].tls.client.cert
32
+    - src:
33
+        schema: deckhand/CertificateKey/v1
34
+        name: calico-etcd-{{ host }}
35
+        path: .
36
+      dest:
37
+        path: .values.nodes[{{ count[0] }}].tls.client.key
38
+    - src:
39
+        schema: deckhand/Certificate/v1
40
+        name: calico-etcd-{{ host }}
41
+        path: .
42
+      dest:
43
+        path: .values.nodes[{{ count[0] }}].tls.peer.cert
44
+    - src:
45
+        schema: deckhand/CertificateKey/v1
46
+        name: calico-etcd-{{ host }}-peer
47
+        path: .
48
+      dest:
49
+        path: .values.nodes[{{ count[0] }}].tls.peer.key
50
+
51
+    {% if count.append(count.pop() + 1) %}{% endif %} {# increment count by 1 #}
52
+
53
+{% endif %}
54
+{% endfor %}
55
+{% endfor %}
56
+
57
+{% for rack in data.baremetal.keys() %}
58
+{% for host in data["baremetal"][rack] %}
59
+{% if data["baremetal"][rack][host]["type"]  == 'genesis' %}
60
+    - src:
61
+        schema: pegleg/CommonAddresses/v1
62
+        name: common-addresses
63
+        path: .genesis.hostname
64
+      dest:
65
+        path: .values.nodes[{{ count[0] }}].name
66
+    - src:
67
+        schema: deckhand/Certificate/v1
68
+        name: calico-etcd-{{ host }}
69
+        path: .
70
+      dest:
71
+        path: .values.nodes[{{ count[0] }}].tls.client.cert
72
+    - src:
73
+        schema: deckhand/CertificateKey/v1
74
+        name: calico-etcd-{{ host }}
75
+        path: .
76
+      dest:
77
+        path: .values.nodes[{{ count[0] }}].tls.client.key
78
+    - src:
79
+        schema: deckhand/Certificate/v1
80
+        name: calico-etcd-{{ host }}-peer
81
+        path: .
82
+      dest:
83
+        path: .values.nodes[{{ count[0] }}].tls.peer.cert
84
+    - src:
85
+        schema: deckhand/CertificateKey/v1
86
+        name: calico-etcd-{{ host }}-peer
87
+        path: .
88
+      dest:
89
+        path: .values.nodes[{{ count[0] }}].tls.peer.key
90
+
91
+{% endif %}
92
+{% endfor %}
93
+{% endfor %}
94
+
95
+data: {}
96
+...

+ 92
- 0
spyglass/examples/templates/software/charts/kubernetes/etcd/etcd.yaml.j2 View File

@@ -0,0 +1,92 @@
1
+---
2
+schema: armada/Chart/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: kubernetes-etcd
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+    parentSelector:
10
+      name: kubernetes-etcd-global
11
+    actions:
12
+      - method: merge
13
+        path: .
14
+  storagePolicy: cleartext
15
+  substitutions:
16
+{% set count = [0] %}
17
+{% for rack in data.baremetal.keys() %}
18
+{% for host in data["baremetal"][rack] %}
19
+{% if data["baremetal"][rack][host]["type"]  == 'controller' %}
20
+    - src:
21
+        schema: pegleg/CommonAddresses/v1
22
+        name: common-addresses
23
+        path: .masters[{{ count[0] }}].hostname
24
+      dest:
25
+        path: .values.nodes[{{ count[0] }}].name
26
+    - src:
27
+        schema: deckhand/Certificate/v1
28
+        name: kubernetes-etcd-{{ host }}
29
+        path: .
30
+      dest:
31
+        path: .values.nodes[{{ count[0] }}].tls.client.cert
32
+    - src:
33
+        schema: deckhand/CertificateKey/v1
34
+        name: kubernetes-etcd-{{ host }}
35
+        path: .
36
+      dest:
37
+        path: .values.nodes[{{ count[0] }}].tls.client.key
38
+    - src:
39
+        schema: deckhand/Certificate/v1
40
+        name: kubernetes-etcd-{{ host }}-peer
41
+        path: .
42
+      dest:
43
+        path: .values.nodes[{{ count[0] }}].tls.peer.cert
44
+    - src:
45
+        schema: deckhand/CertificateKey/v1
46
+        name: kubernetes-etcd-{{ host }}-peer
47
+        path: .
48
+      dest:
49
+        path: .values.nodes[{{ count[0] }}].tls.peer.key
50
+    {% if count.append(count.pop() + 1) %}{% endif %} {# increment count by 1 #}
51
+{% endif %}
52
+{% endfor %}
53
+{% endfor %}
54
+{% for rack in data.baremetal.keys() %}
55
+{% for host in data["baremetal"][rack] %}
56
+{% if data["baremetal"][rack][host]["type"]  == 'genesis' %}
57
+    - src:
58
+        schema: pegleg/CommonAddresses/v1
59
+        name: common-addresses
60
+        path: .genesis.hostname
61
+      dest:
62
+        path: .values.nodes[{{ count[0] }}].name
63
+    - src:
64
+        schema: deckhand/Certificate/v1
65
+        name: kubernetes-etcd-genesis
66
+        path: .
67
+      dest:
68
+        path: .values.nodes[{{ count[0] }}].tls.client.cert
69
+    - src:
70
+        schema: deckhand/CertificateKey/v1
71
+        name: kubernetes-etcd-genesis
72
+        path: .
73
+      dest:
74
+        path: .values.nodes[{{ count[0] }}].tls.client.key
75
+    - src:
76
+        schema: deckhand/Certificate/v1
77
+        name: kubernetes-etcd-genesis-peer
78
+        path: .
79
+      dest:
80
+        path: .values.nodes[{{ count[0] }}].tls.peer.cert
81
+    - src:
82
+        schema: deckhand/CertificateKey/v1
83
+        name: kubernetes-etcd-genesis-peer
84
+        path: $
85
+      dest:
86
+        path: .values.nodes[{{ count[0] }}].tls.peer.key
87
+{% endif %}
88
+{% endfor %}
89
+{% endfor %}
90
+
91
+data: {}
92
+...

+ 28
- 0
spyglass/examples/templates/software/charts/kubernetes/ingress/ingress.yaml.j2 View File

@@ -0,0 +1,28 @@
1
+---
2
+schema: armada/Chart/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: ingress-kube-system
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+    parentSelector:
10
+      ingress: kube-system
11
+    actions:
12
+      - method: merge
13
+        path: .
14
+  storagePolicy: cleartext
15
+  substitutions:
16
+    - src:
17
+        schema: pegleg/CommonAddresses/v1
18
+        name: common-addresses
19
+        path: .ksn.bgp.ipv4.ingress_vip
20
+      dest:
21
+        path: .values.network.vip.addr
22
+data:
23
+  values:
24
+    network:
25
+      vip:
26
+        manage: true
27
+        interface: ingress0
28
+...

+ 16
- 0
spyglass/examples/templates/software/charts/osh-infra/osh-infra-logging/elasticsearch.yaml.j2 View File

@@ -0,0 +1,16 @@
1
+---
2
+schema: armada/Chart/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: elasticsearch
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+    parentSelector:
10
+      hosttype: elasticsearch-global
11
+    actions:
12
+      - method: merge
13
+        path: .
14
+  storagePolicy: cleartext
15
+data: {}
16
+...

+ 16
- 0
spyglass/examples/templates/software/charts/osh-infra/osh-infra-logging/fluent-logging.yaml View File

@@ -0,0 +1,16 @@
1
+---
2
+schema: armada/Chart/v1
3
+metadata:
4
+  schema: metadata/Document/v1
5
+  name: fluent-logging
6
+  layeringDefinition:
7
+    abstract: false
8
+    layer: site
9
+    parentSelector:
10
+      hosttype: fluent-logging-global