Browse Source

Import plugin's code

Change-Id: Ic93c9f6f322d443ec60f8e39231b71b967267e3a
Ivan Zinoviev 1 year ago
parent
commit
87d4536613
39 changed files with 1705 additions and 0 deletions
  1. 176
    0
      LICENSE
  2. 54
    0
      README.md
  3. 2
    0
      deployment_scripts/puppet/manifests/controller.pp
  4. 2
    0
      deployment_scripts/puppet/manifests/mysql.pp
  5. 2
    0
      deployment_scripts/puppet/manifests/neutron.pp
  6. 2
    0
      deployment_scripts/puppet/manifests/nova.pp
  7. 2
    0
      deployment_scripts/puppet/manifests/pacemaker.pp
  8. 2
    0
      deployment_scripts/puppet/manifests/service.pp
  9. 10
    0
      deployment_scripts/puppet/modules/dns_update/files/PKG-INFO
  10. 1
    0
      deployment_scripts/puppet/modules/dns_update/files/README.md
  11. 41
    0
      deployment_scripts/puppet/modules/dns_update/files/db_setup.py
  12. 164
    0
      deployment_scripts/puppet/modules/dns_update/files/dnsupdater-failover
  13. 29
    0
      deployment_scripts/puppet/modules/dns_update/files/etc/dns-updater.conf
  14. 224
    0
      deployment_scripts/puppet/modules/dns_update/files/ocf/DnsUpdater
  15. 79
    0
      deployment_scripts/puppet/modules/dns_update/files/openstack-dns-updater
  16. 19
    0
      deployment_scripts/puppet/modules/dns_update/files/openstack-dns-updater.conf
  17. 0
    0
      deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/__init__.py
  18. 18
    0
      deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/dns-db-cleaner.py
  19. 157
    0
      deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/openstack-dns-updater.py
  20. 0
    0
      deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/__init__.py
  21. 48
    0
      deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/cfg.py
  22. 215
    0
      deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/db_lib.py
  23. 78
    0
      deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/dns_lib.py
  24. 4
    0
      deployment_scripts/puppet/modules/dns_update/files/requirements.txt
  25. 14
    0
      deployment_scripts/puppet/modules/dns_update/files/setup.cfg
  26. 5
    0
      deployment_scripts/puppet/modules/dns_update/files/setup.py
  27. 107
    0
      deployment_scripts/puppet/modules/dns_update/manifests/controller.pp
  28. 1
    0
      deployment_scripts/puppet/modules/dns_update/manifests/init.pp
  29. 25
    0
      deployment_scripts/puppet/modules/dns_update/manifests/mysql.pp
  30. 31
    0
      deployment_scripts/puppet/modules/dns_update/manifests/neutron.pp
  31. 19
    0
      deployment_scripts/puppet/modules/dns_update/manifests/nova.pp
  32. 38
    0
      deployment_scripts/puppet/modules/dns_update/manifests/pacemaker.pp
  33. 16
    0
      deployment_scripts/puppet/modules/dns_update/manifests/service.pp
  34. 64
    0
      deployment_tasks.yaml
  35. 19
    0
      environment_config.yaml
  36. 36
    0
      metadata.yaml
  37. 0
    0
      repositories/centos/.gitkeep
  38. 0
    0
      repositories/ubuntu/.gitkeep
  39. 1
    0
      tasks.yaml

+ 176
- 0
LICENSE View File

@@ -0,0 +1,176 @@
1
+
2
+                                 Apache License
3
+                           Version 2.0, January 2004
4
+                        http://www.apache.org/licenses/
5
+
6
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+   1. Definitions.
9
+
10
+      "License" shall mean the terms and conditions for use, reproduction,
11
+      and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+      "Licensor" shall mean the copyright owner or entity authorized by
14
+      the copyright owner that is granting the License.
15
+
16
+      "Legal Entity" shall mean the union of the acting entity and all
17
+      other entities that control, are controlled by, or are under common
18
+      control with that entity. For the purposes of this definition,
19
+      "control" means (i) the power, direct or indirect, to cause the
20
+      direction or management of such entity, whether by contract or
21
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+      outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+      "You" (or "Your") shall mean an individual or Legal Entity
25
+      exercising permissions granted by this License.
26
+
27
+      "Source" form shall mean the preferred form for making modifications,
28
+      including but not limited to software source code, documentation
29
+      source, and configuration files.
30
+
31
+      "Object" form shall mean any form resulting from mechanical
32
+      transformation or translation of a Source form, including but
33
+      not limited to compiled object code, generated documentation,
34
+      and conversions to other media types.
35
+
36
+      "Work" shall mean the work of authorship, whether in Source or
37
+      Object form, made available under the License, as indicated by a
38
+      copyright notice that is included in or attached to the work
39
+      (an example is provided in the Appendix below).
40
+
41
+      "Derivative Works" shall mean any work, whether in Source or Object
42
+      form, that is based on (or derived from) the Work and for which the
43
+      editorial revisions, annotations, elaborations, or other modifications
44
+      represent, as a whole, an original work of authorship. For the purposes
45
+      of this License, Derivative Works shall not include works that remain
46
+      separable from, or merely link (or bind by name) to the interfaces of,
47
+      the Work and Derivative Works thereof.
48
+
49
+      "Contribution" shall mean any work of authorship, including
50
+      the original version of the Work and any modifications or additions
51
+      to that Work or Derivative Works thereof, that is intentionally
52
+      submitted to Licensor for inclusion in the Work by the copyright owner
53
+      or by an individual or Legal Entity authorized to submit on behalf of
54
+      the copyright owner. For the purposes of this definition, "submitted"
55
+      means any form of electronic, verbal, or written communication sent
56
+      to the Licensor or its representatives, including but not limited to
57
+      communication on electronic mailing lists, source code control systems,
58
+      and issue tracking systems that are managed by, or on behalf of, the
59
+      Licensor for the purpose of discussing and improving the Work, but
60
+      excluding communication that is conspicuously marked or otherwise
61
+      designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+      "Contributor" shall mean Licensor and any individual or Legal Entity
64
+      on behalf of whom a Contribution has been received by Licensor and
65
+      subsequently incorporated within the Work.
66
+
67
+   2. Grant of Copyright License. Subject to the terms and conditions of
68
+      this License, each Contributor hereby grants to You a perpetual,
69
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+      copyright license to reproduce, prepare Derivative Works of,
71
+      publicly display, publicly perform, sublicense, and distribute the
72
+      Work and such Derivative Works in Source or Object form.
73
+
74
+   3. Grant of Patent License. Subject to the terms and conditions of
75
+      this License, each Contributor hereby grants to You a perpetual,
76
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+      (except as stated in this section) patent license to make, have made,
78
+      use, offer to sell, sell, import, and otherwise transfer the Work,
79
+      where such license applies only to those patent claims licensable
80
+      by such Contributor that are necessarily infringed by their
81
+      Contribution(s) alone or by combination of their Contribution(s)
82
+      with the Work to which such Contribution(s) was submitted. If You
83
+      institute patent litigation against any entity (including a
84
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+      or a Contribution incorporated within the Work constitutes direct
86
+      or contributory patent infringement, then any patent licenses
87
+      granted to You under this License for that Work shall terminate
88
+      as of the date such litigation is filed.
89
+
90
+   4. Redistribution. You may reproduce and distribute copies of the
91
+      Work or Derivative Works thereof in any medium, with or without
92
+      modifications, and in Source or Object form, provided that You
93
+      meet the following conditions:
94
+
95
+      (a) You must give any other recipients of the Work or
96
+          Derivative Works a copy of this License; and
97
+
98
+      (b) You must cause any modified files to carry prominent notices
99
+          stating that You changed the files; and
100
+
101
+      (c) You must retain, in the Source form of any Derivative Works
102
+          that You distribute, all copyright, patent, trademark, and
103
+          attribution notices from the Source form of the Work,
104
+          excluding those notices that do not pertain to any part of
105
+          the Derivative Works; and
106
+
107
+      (d) If the Work includes a "NOTICE" text file as part of its
108
+          distribution, then any Derivative Works that You distribute must
109
+          include a readable copy of the attribution notices contained
110
+          within such NOTICE file, excluding those notices that do not
111
+          pertain to any part of the Derivative Works, in at least one
112
+          of the following places: within a NOTICE text file distributed
113
+          as part of the Derivative Works; within the Source form or
114
+          documentation, if provided along with the Derivative Works; or,
115
+          within a display generated by the Derivative Works, if and
116
+          wherever such third-party notices normally appear. The contents
117
+          of the NOTICE file are for informational purposes only and
118
+          do not modify the License. You may add Your own attribution
119
+          notices within Derivative Works that You distribute, alongside
120
+          or as an addendum to the NOTICE text from the Work, provided
121
+          that such additional attribution notices cannot be construed
122
+          as modifying the License.
123
+
124
+      You may add Your own copyright statement to Your modifications and
125
+      may provide additional or different license terms and conditions
126
+      for use, reproduction, or distribution of Your modifications, or
127
+      for any such Derivative Works as a whole, provided Your use,
128
+      reproduction, and distribution of the Work otherwise complies with
129
+      the conditions stated in this License.
130
+
131
+   5. Submission of Contributions. Unless You explicitly state otherwise,
132
+      any Contribution intentionally submitted for inclusion in the Work
133
+      by You to the Licensor shall be under the terms and conditions of
134
+      this License, without any additional terms or conditions.
135
+      Notwithstanding the above, nothing herein shall supersede or modify
136
+      the terms of any separate license agreement you may have executed
137
+      with Licensor regarding such Contributions.
138
+
139
+   6. Trademarks. This License does not grant permission to use the trade
140
+      names, trademarks, service marks, or product names of the Licensor,
141
+      except as required for reasonable and customary use in describing the
142
+      origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+   7. Disclaimer of Warranty. Unless required by applicable law or
145
+      agreed to in writing, Licensor provides the Work (and each
146
+      Contributor provides its Contributions) on an "AS IS" BASIS,
147
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+      implied, including, without limitation, any warranties or conditions
149
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+      PARTICULAR PURPOSE. You are solely responsible for determining the
151
+      appropriateness of using or redistributing the Work and assume any
152
+      risks associated with Your exercise of permissions under this License.
153
+
154
+   8. Limitation of Liability. In no event and under no legal theory,
155
+      whether in tort (including negligence), contract, or otherwise,
156
+      unless required by applicable law (such as deliberate and grossly
157
+      negligent acts) or agreed to in writing, shall any Contributor be
158
+      liable to You for damages, including any direct, indirect, special,
159
+      incidental, or consequential damages of any character arising as a
160
+      result of this License or out of the use or inability to use the
161
+      Work (including but not limited to damages for loss of goodwill,
162
+      work stoppage, computer failure or malfunction, or any and all
163
+      other commercial damages or losses), even if such Contributor
164
+      has been advised of the possibility of such damages.
165
+
166
+   9. Accepting Warranty or Additional Liability. While redistributing
167
+      the Work or Derivative Works thereof, You may choose to offer,
168
+      and charge a fee for, acceptance of support, warranty, indemnity,
169
+      or other liability obligations and/or rights consistent with this
170
+      License. However, in accepting such obligations, You may act only
171
+      on Your own behalf and on Your sole responsibility, not on behalf
172
+      of any other Contributor, and only if You agree to indemnify,
173
+      defend, and hold each Contributor harmless for any liability
174
+      incurred by, or claims asserted against, such Contributor by reason
175
+      of your accepting any such warranty or additional liability.
176
+

+ 54
- 0
README.md View File

@@ -0,0 +1,54 @@
1
+DNS Update Plugin for Fuel
2
+=======================
3
+
4
+Overview
5
+--------------
6
+
7
+DNS Update plugin for Fuel extends Mirantis OpenStack functionality by adding
8
+support for configurable dns servers in murano virtual machines via notifications.
9
+
10
+Compatible Fuel versions
11
+--------------
12
+
13
+9.0
14
+
15
+User Guide
16
+-------------
17
+
18
+1. Create an environment.
19
+2. Enable the plugin on the Settings/Other tab of the Fuel web UI and fill in form
20
+    fields:
21
+3. Deploy the environment.
22
+
23
+DNS Update plugin installation
24
+---------------------------
25
+
26
+To install DNS Update plugin, follow these steps:
27
+
28
+1. Download the plugin from
29
+    [Fuel Plugins Catalog](https://software.mirantis.com/fuel-plugins)
30
+
31
+2. Copy the plugin on already installed Fuel Master node; ssh can be used for
32
+    that. If you do not have the Fuel Master node yet, see
33
+    [Quick Start Guide](https://software.mirantis.com/quick-start/):
34
+
35
+        # scp dns-update-1.0-1.0.0-0.noarch.rpm root@<Fuel_master_ip>:/tmp
36
+
37
+3. Log into the Fuel Master node. Install the plugin:
38
+
39
+        # cd /tmp
40
+        # fuel plugins --install fuel-plugin-dns-update-1.0-1.0.0-0.noarch.rpm
41
+
42
+4. Check if the plugin was installed successfully:
43
+
44
+        # fuel plugins
45
+        id | name                   | version | package_version
46
+        ---|------------------------|---------|----------------
47
+        1  | fuel-plugin-dns-update | 1.0.1   | 4.0.0
48
+
49
+Requirements
50
+------------
51
+
52
+| Requirement                      | Version/Comment |
53
+|:---------------------------------|:----------------|
54
+| Mirantis OpenStack compatibility | 9.0             |

+ 2
- 0
deployment_scripts/puppet/manifests/controller.pp View File

@@ -0,0 +1,2 @@
1
+include dns_update::controller
2
+notice('MODULAR: fuel-plugin-dns-update/controller.pp')

+ 2
- 0
deployment_scripts/puppet/manifests/mysql.pp View File

@@ -0,0 +1,2 @@
1
+include dns_update::mysql
2
+notice('MODULAR: fuel-plugin-dns-update/mysql.pp')

+ 2
- 0
deployment_scripts/puppet/manifests/neutron.pp View File

@@ -0,0 +1,2 @@
1
+include dns_update::neutron
2
+notice('MODULAR: fuel-plugin-dns-update/neutron.pp')

+ 2
- 0
deployment_scripts/puppet/manifests/nova.pp View File

@@ -0,0 +1,2 @@
1
+include dns_update::nova
2
+notice('MODULAR: fuel-plugin-dns-update/nova.pp')

+ 2
- 0
deployment_scripts/puppet/manifests/pacemaker.pp View File

@@ -0,0 +1,2 @@
1
+include dns_update::pacemaker
2
+notice('MODULAR: fuel-plugin-dns-update/pacemaker.pp')

+ 2
- 0
deployment_scripts/puppet/manifests/service.pp View File

@@ -0,0 +1,2 @@
1
+include dns_update::service
2
+notice('MODULAR: fuel-plugin-dns-update/service.pp')

+ 10
- 0
deployment_scripts/puppet/modules/dns_update/files/PKG-INFO View File

@@ -0,0 +1,10 @@
1
+Metadata-Version: 1.0
2
+Name: os_dns_updater
3
+Version: 0.0.2
4
+Summary: listen to nova RabbitMQ events and update dns records
5
+Home-page: UNKNOWN
6
+Author: Sberbank Technology
7
+Author-email: UNKNOWN
8
+License: UNKNOWN
9
+Description: service to register virtual machines in dns
10
+Platform: UNKNOWN

+ 1
- 0
deployment_scripts/puppet/modules/dns_update/files/README.md View File

@@ -0,0 +1 @@
1
+# openstack-dns-updater

+ 41
- 0
deployment_scripts/puppet/modules/dns_update/files/db_setup.py View File

@@ -0,0 +1,41 @@
1
+#!/usr/bin/env python
2
+
3
+#define db schema
4
+
5
+from sqlalchemy import MetaData, create_engine
6
+from sqlalchemy import Table, Column, ForeignKey
7
+from sqlalchemy import String, Integer, DateTime, Text
8
+
9
+from os_dns_updater.utils.cfg import DNS_CONF
10
+
11
+dbcred = DNS_CONF["db_user"]+":"+DNS_CONF["db_password"]
12
+dbaddr = "mysql://"+dbcred+"@localhost/"+DNS_CONF["db_name"]
13
+dbengine = create_engine(dbaddr)
14
+dbmeta = MetaData()
15
+
16
+#create empty db manually or fuel plugin
17
+
18
+def init_tables():
19
+    db_instance = Table("instance", dbmeta,
20
+          Column("id", Integer, primary_key=True),
21
+          Column("ip", String(20)),
22
+          Column("name", String(90)),
23
+          Column("uuid", String(40)),
24
+          Column("state", String(90)),
25
+          Column("dns_domain", String(90)),
26
+          Column("created_at", DateTime),
27
+          Column("updated_at", DateTime),
28
+          Column("deleted_at", DateTime)
29
+    )
30
+    db_event = Table("event", dbmeta,
31
+          #will be used for synchronization
32
+          Column("id", Integer, primary_key=True),
33
+          Column("fk_instance_id", Integer, ForeignKey("instance.id")),
34
+          Column("type", String(24)),#enum
35
+          Column("description", String(90)),
36
+          Column("date", DateTime)
37
+    )
38
+    dbmeta.drop_all(dbengine)
39
+    dbmeta.create_all(dbengine)
40
+
41
+init_tables()

+ 164
- 0
deployment_scripts/puppet/modules/dns_update/files/dnsupdater-failover View File

@@ -0,0 +1,164 @@
1
+#!/bin/sh
2
+#
3
+#
4
+#   dnsupdater-failover OCF RA. Does nothing but wait a few seconds, can be
5
+#   configured to fail occassionally.
6
+#
7
+# Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Bree
8
+#                    All Rights Reserved.
9
+#
10
+# This program is free software; you can redistribute it and/or modify
11
+# it under the terms of version 2 of the GNU General Public License as
12
+# published by the Free Software Foundation.
13
+#
14
+# This program is distributed in the hope that it would be useful, but
15
+# WITHOUT ANY WARRANTY; without even the implied warranty of
16
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
+#
18
+# Further, this software is distributed without any warranty that it is
19
+# free of the rightful claim of any third person regarding infringement
20
+# or the like.  Any license provided herein, whether implied or
21
+# otherwise, applies only to this software file.  Patent licenses, if
22
+# any, provided herein do not apply to combinations of this program with
23
+# other software, or any other product whatsoever.
24
+#
25
+# You should have received a copy of the GNU General Public License
26
+# along with this program; if not, write the Free Software Foundation,
27
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
28
+#
29
+
30
+#######################################################################
31
+# Initialization:
32
+
33
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
34
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
35
+
36
+#######################################################################
37
+
38
+meta_data() {
39
+    cat <<END
40
+<?xml version="1.0"?>
41
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
42
+<resource-agent name="dnsupdater-failover" version="0.9">
43
+<version>1.0</version>
44
+<longdesc lang="en">
45
+Failover ocf script for sbrf dns-updater
46
+</longdesc>
47
+<shortdesc lang="en">ocf for dnsupdater</shortdesc>
48
+<parameters>
49
+<parameter name="state" unique="1">
50
+<longdesc lang="en">
51
+Location to store the resource state in.
52
+</longdesc>
53
+<shortdesc lang="en">State file</shortdesc>
54
+<content type="string" default="${HA_RSCTMP}/dnsupdater-failover-${OCF_RESOURCE_INSTANCE}.state" />
55
+</parameter>
56
+<parameter name="fake" unique="0">
57
+<longdesc lang="en">
58
+Fake attribute that can be changed to cause a reload
59
+</longdesc>
60
+<shortdesc lang="en">Fake attribute that can be changed to cause a reload</shortdesc>
61
+<content type="string" default="dnsupdater-failover" />
62
+</parameter>
63
+</parameters>
64
+<actions>
65
+<action name="start"        timeout="20" />
66
+<action name="stop"         timeout="20" />
67
+<action name="monitor"      timeout="20" interval="10" depth="0" />
68
+<action name="reload"       timeout="20" />
69
+<action name="migrate_to"   timeout="20" />
70
+<action name="migrate_from" timeout="20" />
71
+<action name="meta-data"    timeout="5" />
72
+<action name="validate-all"   timeout="20" />
73
+</actions>
74
+</resource-agent>
75
+END
76
+}
77
+
78
+#######################################################################
79
+
80
+dnsupdaterfailover_usage() {
81
+    cat <<END
82
+usage: $0 {start|stop|monitor|migrate_to|migrate_from|validate-all|meta-data}
83
+Expects to have a fully populated OCF RA-compliant environment set.
84
+END
85
+}
86
+
87
+dnsupdaterfailover_start() {
88
+    dnsupdater-failover_monitor
89
+    /usr/bin/python /usr/lib/python2.7/dist-packages/os_dns_updater/openstack-dns-updater.py
90
+    if [ $? =  $OCF_SUCCESS ]; then
91
+        return $OCF_SUCCESS
92
+    fi
93
+    touch ${OCF_RESKEY_state}
94
+}
95
+
96
+dnsupdaterfailover_stop() {
97
+    dnsupdater-failover_monitor
98
+    if [ $? =  $OCF_SUCCESS ]; then
99
+        rm ${OCF_RESKEY_state}
100
+    fi
101
+    return $OCF_SUCCESS
102
+}
103
+
104
+dnsupdaterfailover_monitor() {
105
+    # Monitor _MUST!_ differentiate correctly between running
106
+    # (SUCCESS), failed (ERROR) or _cleanly_ stopped (NOT RUNNING).
107
+    # That is THREE states, not just yes/no.
108
+
109
+    if [ -f ${OCF_RESKEY_state} ]; then
110
+        return $OCF_SUCCESS
111
+    fi
112
+    if false ; then
113
+        return $OCF_ERR_GENERIC
114
+    fi
115
+
116
+    if ! ocf_is_probe && [ "$__OCF_ACTION" = "monitor" ]; then
117
+        # set exit string only when NOT_RUNNING occurs during an actual monitor operation.
118
+        ocf_exit_reason "No process state file found"
119
+    fi
120
+    return $OCF_NOT_RUNNING
121
+}
122
+
123
+dnsupdaterfailover_validate() {
124
+    # Is the state directory writable?
125
+    state_dir=`dirname "$OCF_RESKEY_state"`
126
+    touch "$state_dir/$$"
127
+    if [ $? != 0 ]; then
128
+        ocf_exit_reason "State file \"$OCF_RESKEY_state\" is not writable"
129
+        return $OCF_ERR_ARGS
130
+    fi
131
+    rm "$state_dir/$$"
132
+
133
+    return $OCF_SUCCESS
134
+}
135
+
136
+: ${OCF_RESKEY_state=${HA_RSCTMP}/dnsupdater-failover-${OCF_RESOURCE_INSTANCE}.state}
137
+: ${OCF_RESKEY_fake="dnsupdaterfailover"}
138
+
139
+case $__OCF_ACTION in
140
+meta-data)      meta_data
141
+                exit $OCF_SUCCESS
142
+                ;;
143
+start)          dnsupdaterfailover_start;;
144
+stop)           dnsupdaterfailover_stop;;
145
+monitor)        dnsupdaterfailover_monitor;;
146
+migrate_to)     ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} to ${OCF_RESKEY_CRM_meta_migrate_target}."
147
+                dnsupdaterfailover_stop
148
+                ;;
149
+migrate_from)   ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} from ${OCF_RESKEY_CRM_meta_migrate_source}."
150
+                dnsupdaterfailover_start
151
+                ;;
152
+reload)         ocf_log info "Reloading ${OCF_RESOURCE_INSTANCE} ..."
153
+                ;;
154
+validate-all)   dnsupdaterfailover_validate;;
155
+usage|help)     dnsupdaterfailover_usage
156
+                exit $OCF_SUCCESS
157
+                ;;
158
+*)              dnsupdaterfailover_usage
159
+                exit $OCF_ERR_UNIMPLEMENTED
160
+                ;;
161
+esac
162
+rc=$?
163
+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
164
+exit $rc

+ 29
- 0
deployment_scripts/puppet/modules/dns_update/files/etc/dns-updater.conf View File

@@ -0,0 +1,29 @@
1
+[DEFAULT]
2
+debug=False
3
+#networks=
4
+#region=
5
+
6
+## AMQP configuration parameters
7
+#exchanges=nova,neutron
8
+#routing_key=notifications.info
9
+#queue_name=dns_updater-test
10
+#amqp_hosts=
11
+#failover_strategy=round-robin
12
+#amqp_user=nova
13
+#amqp_password=
14
+#event_create=compute.instance.create.end
15
+#event_delete=compute.instance.delete.start
16
+
17
+## DNS configuration parameters
18
+#nameserver=127.0.0.1
19
+#domain=vm.example.net
20
+#ttl=1
21
+#dns_keyfile='/etc/os_dns_updater/example.key'
22
+
23
+##db created at setup
24
+#db_name=
25
+#db_user=
26
+#db_password=
27
+
28
+#maxcounter=4095
29
+#insttime=120

+ 224
- 0
deployment_scripts/puppet/modules/dns_update/files/ocf/DnsUpdater View File

@@ -0,0 +1,224 @@
1
+#!/bin/sh
2
+#
3
+#
4
+#   DnsUpdater OCF RA. Does nothing but wait a few seconds, can be
5
+#   configured to fail occassionally.
6
+#
7
+# Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Brée
8
+#                    All Rights Reserved.
9
+#
10
+# This program is free software; you can redistribute it and/or modify
11
+# it under the terms of version 2 of the GNU General Public License as
12
+# published by the Free Software Foundation.
13
+#
14
+# This program is distributed in the hope that it would be useful, but
15
+# WITHOUT ANY WARRANTY; without even the implied warranty of
16
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
+#
18
+# Further, this software is distributed without any warranty that it is
19
+# free of the rightful claim of any third person regarding infringement
20
+# or the like.  Any license provided herein, whether implied or
21
+# otherwise, applies only to this software file.  Patent licenses, if
22
+# any, provided herein do not apply to combinations of this program with
23
+# other software, or any other product whatsoever.
24
+#
25
+# You should have received a copy of the GNU General Public License
26
+# along with this program; if not, write the Free Software Foundation,
27
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
28
+#
29
+
30
+#######################################################################
31
+# Initialization:
32
+
33
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
34
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
35
+: ${OCF_FUEL_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/fuel}
36
+. ${OCF_FUEL_FUNCTIONS_DIR}/ocf-fuel-funcs
37
+
38
+#######################################################################
39
+
40
+# Fill in some defaults if no values are specified
41
+
42
+OCF_RESKEY_binary_default="openstack-dns-updater.py"
43
+#OCF_RESKEY_config_default="/etc/aodh/aodh.conf"
44
+#OCF_RESKEY_user_default="aodh"
45
+OCF_RESKEY_pid_default="${HA_RSCTMP}/${__SCRIPT_NAME}/${__SCRIPT_NAME}.pid"
46
+
47
+: ${HA_LOGTAG="ocf-dns-updater"}
48
+: ${HA_LOGFACILITY="daemon"}
49
+: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}
50
+#: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}}
51
+#: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}}
52
+: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}
53
+
54
+#######################################################################
55
+
56
+usage() {
57
+    cat <<UEND
58
+        usage: $0 (start|stop|status)
59
+
60
+        $0 manages an OpenStack DnsUpdater Service process as an HA resource
61
+
62
+        The 'start' operation starts the service.
63
+        The 'stop' operation stops the service.
64
+        The 'status' operation reports whether the service is running
65
+
66
+UEND
67
+}
68
+
69
+meta_data() {
70
+    cat <<END
71
+<?xml version="1.0"?>
72
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
73
+<resource-agent name="DnsUpdater">
74
+<version>1.0</version>
75
+
76
+<longdesc lang="en">
77
+sample dnsupdater resource
78
+</longdesc>
79
+<shortdesc lang="en">Example stateless resource agent</shortdesc>
80
+<parameters>
81
+<parameter name="pid" unique="0" required="0">
82
+<longdesc lang="en">
83
+The pid file to use for this OpenStack Aodh Evaluator Service (aodh-evaluator) instance
84
+</longdesc>
85
+<shortdesc lang="en">OpenStack Aodh Evaluator Service (aodh-evaluator) pid file</shortdesc>
86
+<content type="string" default="${OCF_RESKEY_pid_default}" />
87
+</parameter>
88
+
89
+</parameters>
90
+
91
+<actions>
92
+<action name="start" timeout="20" />
93
+<action name="stop" timeout="20" />
94
+<action name="status" timeout="20" />
95
+</actions>
96
+</resource-agent>
97
+END
98
+}
99
+
100
+#######################################################################
101
+
102
+dnsupdater_validate() {
103
+    local rc
104
+
105
+    return ${OCF_SUCCESS}
106
+}
107
+
108
+dnsupdater_status() {
109
+    local pid
110
+    local rc
111
+
112
+    # check and make PID file dir
113
+    local PID_DIR="$( dirname ${OCF_RESKEY_pid} )"
114
+    if [ ! -d "${PID_DIR}" ] ; then
115
+        ocf_log debug "Create pid file dir: ${PID_DIR}"
116
+        mkdir -p "${PID_DIR}"
117
+        chmod 755 "${PID_DIR}"
118
+    fi
119
+
120
+    if [ ! -f $OCF_RESKEY_pid ]; then
121
+        ocf_log info "DnsUpdater is not running"
122
+        return $OCF_NOT_RUNNING
123
+    else
124
+        pid=`cat $OCF_RESKEY_pid`
125
+    fi
126
+
127
+    if [ -n "${pid}" ]; then
128
+        ocf_run -warn kill -s 0 $pid
129
+        rc=$?
130
+    else
131
+        ocf_log err "PID file ${OCF_RESKEY_pid} is empty!"
132
+        return $OCF_ERR_GENERIC
133
+    fi
134
+
135
+    if [ $rc -eq 0 ]; then
136
+        return $OCF_SUCCESS
137
+    else
138
+        ocf_log info "Old PID file found, but DnsUpdater not running"
139
+        return $OCF_NOT_RUNNING
140
+    fi
141
+}
142
+
143
+dnsupdater_monitor() {
144
+    local rc
145
+    local pid
146
+
147
+    dnsupdater_status
148
+    rc=$?
149
+
150
+    # If status returned anything but success, return that immediately
151
+    if [ $rc -ne $OCF_SUCCESS ]; then
152
+        return $rc
153
+    fi
154
+
155
+    ocf_log debug "OpenStack DnsUpdater monitor succeeded"
156
+    return $OCF_SUCCESS
157
+}
158
+
159
+dnsupdater_start() {
160
+    dnsupdater_status
161
+    rc=$?
162
+    if [ $rc -eq $OCF_SUCCESS ]; then
163
+        ocf_log info "OpenStack DnsUpdater is already running"
164
+        return $OCF_SUCCESS
165
+    fi
166
+
167
+    /usr/bin/python /usr/lib/python2.7/dist-packages/os_dns_updater/openstack-dns-updater.py >> /dev/null 2>&1 & echo $! > $OCF_RESKEY_pid
168
+    ocf_log debug "Create pid file: ${OCF_RESKEY_pid} with content $(cat ${OCF_RESKEY_pid})"
169
+    # Spin waiting for the server to come up.
170
+    while true; do
171
+    dnsupdater_monitor
172
+    rc=$?
173
+    [ $rc -eq $OCF_SUCCESS ] && break
174
+    if [ $rc -ne $OCF_NOT_RUNNING ]; then
175
+        ocf_log err "OpenStack DnsUpdater start failed"
176
+        exit $OCF_ERR_GENERIC
177
+    fi
178
+    sleep 1
179
+    done
180
+
181
+    ocf_log info "OpenStack DnsUpdater started"
182
+    return $OCF_SUCCESS
183
+}
184
+
185
+dnsupdater_stop() {
186
+    local rc
187
+    local shutdown_timeout=15
188
+    if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then
189
+        shutdown_timeout=$(( ($OCF_RESKEY_CRM_meta_timeout/1000) ))
190
+    fi
191
+
192
+    dnsupdater_status
193
+    rc="${?}"
194
+    if [ "${rc}" -eq "${OCF_NOT_RUNNING}" ]; then
195
+        ocf_log info "OpenStack DnsUpdater (${OCF_RESKEY_binary}) already stopped"
196
+        return "${OCF_SUCCESS}"
197
+    fi
198
+
199
+    proc_stop "${OCF_RESKEY_pid}" "${OCF_RESKEY_binary}" $shutdown_timeout
200
+    return "${?}"
201
+}
202
+
203
+#######################################################################
204
+
205
+case "$1" in
206
+  meta-data) meta_data
207
+                exit $OCF_SUCCESS;;
208
+  usage|help) usage
209
+                exit $OCF_SUCCESS;;
210
+esac
211
+
212
+# Anything except meta-data and help must pass validation
213
+dnsupdater_validate || exit $?
214
+
215
+# What kind of method was invoked?
216
+case "$1" in
217
+  start) dnsupdater_start;;
218
+  stop) dnsupdater_stop;;
219
+  status) dnsupdater_status;;
220
+  monitor) dnsupdater_monitor;;
221
+  validate-all) ;;
222
+  *) usage
223
+        exit $OCF_ERR_UNIMPLEMENTED;;
224
+esac

+ 79
- 0
deployment_scripts/puppet/modules/dns_update/files/openstack-dns-updater View File

@@ -0,0 +1,79 @@
1
+#! /bin/sh
2
+### BEGIN INIT INFO
3
+# Provides:          skeleton
4
+# Required-Start:    $remote_fs $syslog
5
+# Required-Stop:     $remote_fs $syslog
6
+# Default-Start:     2 3 4 5
7
+# Default-Stop:      0 1 6
8
+# Short-Description: Example initscript
9
+# Description:       This file should be used to construct scripts to be
10
+#                    placed in /etc/init.d.
11
+### END INIT INFO
12
+
13
+# Do NOT "set -e"
14
+
15
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
16
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
17
+DIR=/usr/lib/python2.7/dist-packages/os_dns_updater
18
+DESC="Description of the service"
19
+DAEMON_NAME=openstack-dns-updater
20
+DAEMON="/usr/bin/python $DIR/openstack-dns-updater.py"
21
+DAEMON_ARGS=""
22
+PIDFILE=/var/run/$DAEMON_NAME.pid
23
+
24
+. /lib/lsb/init-functions
25
+
26
+# Function that starts the daemon/service
27
+#
28
+do_start()
29
+{
30
+        logger "DEBUG: entered start function"
31
+        log_daemon_msg "Starting openstack-dns-updater"
32
+        start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --startas $DAEMON
33
+        ret=$?
34
+        logger "DEBUG: return code: $ret"
35
+        logger "DEBUG: vars: pidfile - $PIDFILE daemon - $DAEMON"
36
+        log_end_msg $?
37
+}
38
+
39
+do_stop()
40
+{
41
+#AP_RET=1 - running
42
+#AP_RET=0 - not running
43
+       if [ -f $PIDFILE ];
44
+       then
45
+          AP_RET=1
46
+       else
47
+          AP_RET=0
48
+       fi
49
+
50
+       if [ $AP_RET = 0 ];
51
+       then
52
+        log_daemon_msg "Openstack-dns-updater daemon is already stopped"
53
+        exit 0
54
+       elif [ $AP_RET = 1 ];
55
+       then
56
+        log_daemon_msg "Stopping openstack-dns-updater"
57
+        start-stop-daemon --stop --signal 2 --pidfile $PIDFILE --retry 10
58
+        rm -f $PIDFILE
59
+        log_end_msg $?
60
+       fi
61
+}
62
+
63
+case "$1" in
64
+  start|stop)
65
+       do_${1}
66
+       ;;
67
+  restart|reload|force-reload)
68
+       do_stop
69
+       do_start
70
+       ;;
71
+  status)
72
+    status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit 3
73
+    ;;
74
+  *)
75
+    #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
76
+    echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
77
+    exit 1
78
+    ;;
79
+esac

+ 19
- 0
deployment_scripts/puppet/modules/dns_update/files/openstack-dns-updater.conf View File

@@ -0,0 +1,19 @@
1
+# openstack-dns-updater.upstart - run DNS updater script
2
+
3
+description "OpenStack DNS Updater"
4
+
5
+start on runlevel [2345]
6
+stop on runlevel [!2345]
7
+
8
+respawn
9
+respawn limit 10 5
10
+umask 022
11
+
12
+# The following is not needed when using /usr/bin/python
13
+# expect fork
14
+
15
+# /var/log/upstart/openstack-dns-updater.log should be empty
16
+# Logs to /var/log/nova/dns-updater.log
17
+console log
18
+
19
+exec /usr/bin/python /usr/lib/python2.7/dist-packages/os_dns_updater/openstack-dns-updater.py

+ 0
- 0
deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/__init__.py View File


+ 18
- 0
deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/dns-db-cleaner.py View File

@@ -0,0 +1,18 @@
1
+#!/usr/bin/env python
2
+# module to clear db every hour_of_day
3
+import time, datetime
4
+from os_dns_updater.utils import db_lib
5
+from os_dns_updater.utils.cfg import DNS_CONF
6
+from os_dns_updater.utils.cfg import LOG_FILE
7
+
8
+import logging as log
9
+
10
+log_level = log.DEBUG if (DNS_CONF["debug"] == "True") else log.INFO
11
+log.basicConfig(filename=LOG_FILE, level=log_level,
12
+                format="%(levelname)s %(asctime)s %(message)s")
13
+
14
+while 1:
15
+    hour_of_day = datetime.datetime.timetuple(datetime.datetime.now())[3]
16
+    if hour_of_day == 21:
17
+        db_lib.check_and_clear()
18
+    time.sleep(3599)

+ 157
- 0
deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/openstack-dns-updater.py View File

@@ -0,0 +1,157 @@
1
+#!/usr/bin/env python
2
+
3
+# module to work with rabbitmq (main)
4
+
5
+#TODO!!! delete old records on time
6
+from kombu import BrokerConnection
7
+from kombu import Exchange
8
+from kombu import Queue
9
+from kombu.mixins import ConsumerMixin
10
+
11
+from os_dns_updater.utils import dns_lib
12
+from os_dns_updater.utils import db_lib
13
+from os_dns_updater.utils.cfg import LOG_FILE, DNS_CONF
14
+
15
+import json
16
+import logging as log
17
+
18
+log_level = log.DEBUG if (DNS_CONF["debug"] == "True") else log.INFO
19
+log.basicConfig(filename=LOG_FILE, level=log_level,
20
+                format="%(levelname)s %(name)s %(asctime)s %(message)s")
21
+
22
+class DnsUpdater(ConsumerMixin):
23
+
24
+    def __init__(self, connection):
25
+        log.debug("service started with configuration:")
26
+        log.debug(str(json.dumps(DNS_CONF,indent=4,separators=(",",":"))))
27
+        log.debug("initialize rabbit")
28
+        self.connection = connection
29
+        return
30
+
31
+
32
+    def get_consumers(self, consumer, channel):
33
+        consumers = []
34
+        exchanges = DNS_CONF["exchanges"]
35
+        exchanges = exchanges.split(",")
36
+        for exch in exchanges:
37
+            exchange = Exchange(exch, type="topic", durable=False)
38
+            queue = Queue(DNS_CONF["queue_name"], exchange,
39
+                routing_key=DNS_CONF["routing_key"],
40
+                durable=False, auto_delete=True, no_ack=True)
41
+            consumers.append(consumer(queue, callbacks=[self.on_message]))
42
+        return consumers
43
+
44
+    def on_message(self, body, message):
45
+        try:
46
+            res = self._handle_message(body)
47
+        except Exception as e:
48
+            log.error(repr(e))
49
+
50
+
51
+    def _handle_message(self, body):
52
+        events = [DNS_CONF["event_create"],DNS_CONF["event_delete"]]
53
+        v_key='oslo.message'
54
+        if isinstance(body,dict):
55
+            if v_key in body:
56
+                log.debug("received message in v2 format")
57
+                rdict=dict(body)
58
+                jbody = rdict.get(v_key)
59
+                if isinstance(jbody,str) or isinstance(jbody,unicode):
60
+                    msgbody = json.loads(jbody)
61
+                else:
62
+                    msgbody = dict(jbody)
63
+            else:
64
+                log.debug("received message in v1 format")
65
+                msgbody = dict(body)
66
+            log.debug(str(json.dumps(msgbody,indent=4,separators=(",",":"))))
67
+        else:
68
+            log.warning("incorrect data type in oslo message: {}".format(type(body)))
69
+            return False
70
+        if ('event_type' in msgbody) and  ('payload' in msgbody):
71
+            event_type = msgbody["event_type"]
72
+            payload = msgbody["payload"]
73
+        else:
74
+            log.warning("unexpected message: {}".format(msgbody))
75
+            return False
76
+        if event_type in events:
77
+            if "metadata" in payload:
78
+                if "use_dns" in payload["metadata"]:
79
+                    use_dns = (payload["metadata"]["use_dns"] == "yes")
80
+                else:
81
+                    log.debug("no dns metadata for event {}".format(event_type))
82
+                    return False
83
+            else:
84
+                log.debug("No metadata for event {}".format(event_type))
85
+                return False
86
+        else:
87
+            log.debug("event type ignored: {}".format(event_type))
88
+            return False
89
+        if use_dns:
90
+            nova_hostname = payload["hostname"]
91
+            nova_os_id = payload["instance_id"]
92
+            if event_type == DNS_CONF["event_create"]:
93
+                if not len(payload["fixed_ips"]):
94
+                    log.warning("instance with no network")
95
+                    return False
96
+                #always use first interface (todo change this)
97
+                nova_ip = payload["fixed_ips"][0]["address"]
98
+                netname = payload["fixed_ips"][0]["label"]
99
+                if netname not in DNS_CONF["networks"]:
100
+                    log.warning("dns will not be used for {}".format(netname))
101
+                    return False
102
+                if "message" in payload:
103
+                    if payload["message"] == "Success":
104
+                        log.debug("Instance successfully created")
105
+                    else:
106
+                        log.warning("Error creating instance")
107
+                        return False
108
+                else:
109
+                    log.warning("unknown instance state")
110
+                lookup_addr = dns_lib.lookup_hostname(nova_hostname)
111
+                if lookup_addr == nova_ip:
112
+                    log.warning("Instance already has address : {}".format(nova_ip))
113
+                    log.warning("Nothing to do for instance {}".format(nova_hostname))
114
+                elif lookup_addr is not None:
115
+                    log.error("Instance has different address: {}".format(lookup_addr))
116
+                    log.error("Refused to add instance: {}".format(nova_hostname))
117
+                    return False
118
+                dns_lib.add_hostname(nova_hostname, nova_ip)
119
+                assigned_addr = dns_lib.lookup_hostname(nova_hostname)
120
+                if assigned_addr is None:
121
+                    log.error("Dns server denied request for instance: {}".format(nova_hostname))
122
+                    return False
123
+                else:
124
+                    log.info("Instance added to dns: {} {}".format(nova_hostname, assigned_addr))
125
+                    #db_lib.create_instance(nova_hostname, nova_ip, nova_os_id)
126
+            if event_type == DNS_CONF["event_delete"]:
127
+                lookup_addr = dns_lib.lookup_hostname(nova_hostname)
128
+                if lookup_addr is not None:
129
+                    dns_lib.del_hostname(nova_hostname)
130
+                    #db_lib.delete_instance(nova_hostname, nova_os_id)
131
+                else:
132
+                    log.warning("instance {} not found in dns".format(nova_hostname))
133
+                    log.warning("nothing to do")
134
+                    return False
135
+            log.info("event of type {} processed".format(event_type))
136
+            return True
137
+        else:
138
+            log.debug("Instance will not use dns for {}".format(event_type))
139
+            return False
140
+
141
+if __name__ == "__main__":
142
+    amqp_hosts = DNS_CONF["amqp_hosts"].split(",")
143
+    BROKER_LIST = []
144
+    amqp_user = DNS_CONF["amqp_user"]
145
+    amqp_password = DNS_CONF["amqp_password"]
146
+    fs = DNS_CONF["failover_strategy"]
147
+    for amqp_host in amqp_hosts:
148
+        broker_uri = "amqp://{}:{}@{}//".format(amqp_user,amqp_password,amqp_host)
149
+        BROKER_LIST.append(broker_uri)
150
+    log.info("Connecting to broker {}".format(BROKER_LIST))
151
+    with BrokerConnection(BROKER_LIST, failover_strategy=fs ) as connection:
152
+        try:
153
+            DnsUpdater(connection).run()
154
+        except Exception, e:
155
+            log.error(repr(e))
156
+
157
+#TODO use oslo for config, log, db(?), messaging(?)

+ 0
- 0
deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/__init__.py View File


+ 48
- 0
deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/cfg.py View File

@@ -0,0 +1,48 @@
1
+#!/usr/bin/env python
2
+
3
+from ConfigParser import SafeConfigParser
4
+
5
+LOG_FILE = "/var/log/dns-updater.log"
6
+CONF_PATH = "/etc/os_dns_updater/dns-updater.conf"
7
+
8
+conflist = [
9
+    "debug",
10
+    "db_name",
11
+    "db_user",
12
+    "db_password",
13
+    "exchanges",
14
+    "queue_name",
15
+    "routing_key",
16
+    "event_create",
17
+    "event_delete",
18
+    "amqp_user",
19
+    "amqp_password",
20
+    "amqp_hosts",
21
+    "failover_strategy",
22
+    "domain",
23
+    "networks",
24
+    "region",
25
+    "dns_keyfile",
26
+    "nameserver",
27
+    "ttl",
28
+    "maxcounter",
29
+    "insttime"
30
+]
31
+
32
+def _parse_config(confname, conflist):
33
+    config = SafeConfigParser()
34
+    try:
35
+        config.read(confname)
36
+    except Exception as e:
37
+        pass
38
+    cf =  {}
39
+    for item in conflist:
40
+        try:
41
+            value = config.get("DEFAULT", item)
42
+        except Exception as e:
43
+            value = None
44
+        cf[item] = value
45
+    return cf
46
+
47
+DNS_CONF = _parse_config(CONF_PATH,conflist)
48
+#TODO use neutron port update events

+ 215
- 0
deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/db_lib.py View File

@@ -0,0 +1,215 @@
1
+#!/usr/bin/env python
2
+
3
+# module to work with db
4
+
5
+from sqlalchemy import MetaData, create_engine
6
+from sqlalchemy import Column
7
+from sqlalchemy import String, Integer, DateTime
8
+from sqlalchemy.orm import sessionmaker, scoped_session
9
+from sqlalchemy.ext.declarative import declarative_base
10
+
11
+from os_dns_updater.utils.cfg import DNS_CONF
12
+from os_dns_updater.utils.cfg import LOG_FILE
13
+
14
+import re
15
+import time
16
+import datetime
17
+import dateutil.relativedelta as timedelta
18
+import hashlib
19
+import logging as log
20
+
21
+log_level = log.DEBUG if (DNS_CONF["debug"] == "True") else log.INFO
22
+log.basicConfig(filename=LOG_FILE, level=log_level,
23
+                format="%(levelname)s %(asctime)s %(message)s")
24
+
25
+MAX_INST = int(DNS_CONF["maxcounter"]) # max number of instances of type in tenant
26
+if not MAX_INST:
27
+    MAX_INST = 4095
28
+DBTTL = int(DNS_CONF["insttime"]) #time to store old data in db (state!=added)
29
+if not DBTTL:
30
+    DBTTL = 90
31
+
32
+dbcred = DNS_CONF["db_user"]+":"+DNS_CONF["db_password"]
33
+dbaddr = "mysql://"+dbcred+"@localhost/"+DNS_CONF["db_name"]
34
+dbengine = create_engine(dbaddr, pool_recycle=120)
35
+dbmeta = MetaData()
36
+Base = declarative_base()
37
+
38
+class Instance(Base):
39
+    __tablename__ = "instance"
40
+    id = Column(Integer, primary_key=True)
41
+    ip = Column(String(20))
42
+    name = Column(String(90))
43
+    dns_domain = Column(String(90))
44
+    uuid = Column(String(40))
45
+    state = Column(String(40))
46
+    created_at = Column(DateTime)
47
+    updated_at = Column(DateTime)
48
+    deleted_at = Column(DateTime)
49
+
50
+    def __init__(self, name, uuid, ip):
51
+        self.ip = ip
52
+        self.name = name
53
+        self.uuid = uuid
54
+        self.created_at = datetime.datetime.now()
55
+
56
+#class Event(Base):
57
+#    __tablename__ = "event"
58
+#    id = Column(Integer, primary_key=True)
59
+#    def __init__(self):
60
+#        pass
61
+
62
+Base.metadata.create_all(dbengine)
63
+
64
+def check_and_clear():
65
+    Session = scoped_session(sessionmaker(bind=dbengine))
66
+    dbsession = Session()
67
+    log.info("db check_and_clear started with options {} {}".format(MAX_INST,DBTTL))
68
+    oldtime = datetime.datetime.today() - timedelta.relativedelta(days=DBTTL)
69
+    log.info("looking for unregistered records older than {}".format(oldtime))
70
+    inst = dbsession.query(Instance).filter(
71
+                            Instance.state != 'added',
72
+                            Instance.created_at <= oldtime
73
+                            ).delete()
74
+    try:
75
+        dbsession.commit()
76
+        log.info("{} records removed from db".format(len(inst)))
77
+    except Exception as e:
78
+        log.error(repr(e))
79
+        dbsession.rollback()
80
+    dbsession.bind.dispose()
81
+    Session.remove()
82
+
83
+def create_instance(iname, ip, uuid):
84
+    Session = scoped_session(sessionmaker(bind=dbengine))
85
+    dbsession = Session()
86
+    inst = dbsession.query(Instance).filter(
87
+                            Instance.name == iname,
88
+                            Instance.state != 'added').first()
89
+    if not inst:
90
+        log.warning("instance {} was not found in db".format(iname))
91
+        new_inst = Instance(iname, uuid, ip)
92
+        dbsession.add(new_inst)
93
+        new_inst.state = 'added'
94
+        new_inst.dns_domain = DNS_CONF["domain"]
95
+    else:
96
+        inst.state = 'added'
97
+        inst.dns_domain = DNS_CONF["domain"]
98
+        inst.uuid = uuid
99
+        inst.ip = ip
100
+        inst.updated_at = datetime.datetime.now()
101
+    try:
102
+        dbsession.commit()
103
+    except Exception as e:
104
+        log.error(repr(e))
105
+        dbsession.rollback()
106
+    dbsession.bind.dispose()
107
+    Session.remove()
108
+
109
+
110
+def delete_instance(iname, uuid):
111
+    Session = scoped_session(sessionmaker(bind=dbengine))
112
+    dbsession = Session()
113
+    inst = dbsession.query(Instance).filter(Instance.name == iname).first()
114
+    if not inst:
115
+        log.warning("instance {} was not found in db".format(iname))
116
+    else:
117
+        inst.state = 'deleted'
118
+        inst.deleted_at = datetime.datetime.now()
119
+        try:
120
+            dbsession.commit()
121
+        except Exception as e:
122
+            log.error(repr(e))
123
+            dbsession.rollback()
124
+    dbsession.bind.dispose()
125
+    Session.remove()
126
+
127
+def generate_name(fqn, pname, dname):
128
+    fqn = str(fqn)
129
+    log.info("generating instance name for: {} {} {}".format(fqn,pname,dname))
130
+    app = fqn.rsplit('.',1)[-1]
131
+    app = app[:3]
132
+    name = pname.split('-')[0]
133
+    name = name[:9]
134
+    pat = re.compile(r'^\D\d+')
135
+    if pat.search(name) is None:
136
+        name = 'None'
137
+        log.warning("incorrect project name {}".format(pname))
138
+    patt = "{}-{}-{}".format(DNS_CONF['region'],name,app)
139
+    try:
140
+        instnumber = num_from_patt(patt)
141
+    except:
142
+        instnumber = rstr(5)
143
+    res = "{}-{}".format(patt,instnumber)
144
+    return res
145
+
146
+def num_from_patt(patt):
147
+    patt1 = patt + '%'
148
+    Session = scoped_session(sessionmaker(bind=dbengine))
149
+    dbsession = Session()
150
+    instances = dbsession.query(Instance).filter(
151
+         Instance.name.like(patt1)).all()
152
+    nums = []
153
+    if not instances:
154
+        log.debug("new instance of type {}".format(patt))
155
+        res = 1
156
+    else:
157
+        res = 0
158
+        for inst in instances:
159
+            log.debug("found instance {}".format(inst.name))
160
+            d = inst.name
161
+            d = d.split('-')[3]
162
+            d = int(d,16)
163
+            nums.append(d)
164
+    if not len(nums):
165
+        res = 1
166
+    else:
167
+        rlist = list(set(range(1,MAX_INST)) - set(nums))
168
+        res = rlist[0]
169
+        log.debug("found new number: {}".format(res))
170
+    res = str(hex(res))[2:]
171
+    if len(res) == 1:
172
+        res = '00'+res
173
+    if len(res) == 2:
174
+        res = '0'+res
175
+
176
+    new_inst = Instance("{}-{}".format(patt,res), '', '')
177
+    dbsession.add(new_inst)
178
+    new_inst.state = 'reserved'
179
+    new_inst.dns_domain = DNS_CONF["domain"]
180
+    try:
181
+        dbsession.commit()
182
+    except Exception as e:
183
+        dbsession.rollback()
184
+    dbsession.bind.dispose()
185
+    Session.remove()
186
+    return res
187
+
188
+
189
+def rstr(i):
190
+    #random string of length i
191
+    h = hashlib.sha1()
192
+    h.update(str(time.time()*10000))
193
+    rs = h.hexdigest()[:i]
194
+    return rs
195
+
196
+#unused right now:
197
+
198
+def instance_exists(iname):
199
+    Session = scoped_session(sessionmaker(bind=dbengine))
200
+    dbsession = Session()
201
+    inst = dbsession.query(Instance).filter(
202
+         Instance.name==iname,
203
+         Instance.state!='deleted',
204
+         Instance.dns_domain==DNS_CONF['domain']).first()
205
+    if not inst:
206
+        log.debug("instance {} was not found in db".format(iname))
207
+        res = False
208
+    else:
209
+        res = True
210
+    dbsession.bind.dispose()
211
+    Session.remove()
212
+    return res
213
+
214
+def update_instance():
215
+    pass

+ 78
- 0
deployment_scripts/puppet/modules/dns_update/files/os_dns_updater/utils/dns_lib.py View File

@@ -0,0 +1,78 @@
1
+#!/usr/bin/env python
2
+
3
+# module to work with dns
4
+
5
+import dns.resolver
6
+import dns.reversename
7
+import dns.query
8
+import dns.zone
9
+import dns.exception
10
+import dns.name
11
+from subprocess import Popen, PIPE
12
+import logging as log
13
+
14
+from os_dns_updater.utils.cfg import LOG_FILE
15
+from os_dns_updater.utils.cfg import DNS_CONF
16
+
17
+log_level = log.DEBUG if (DNS_CONF["debug"] == "True") else log.INFO
18
+log.basicConfig(filename=LOG_FILE, level=log_level,
19
+                format="%(levelname)s %(asctime)s %(message)s")
20
+
21
+
22
+NSUPDATE_ADD = "\
23
+server {nameserver}\n\
24
+update add {hostname} {ttl} A {hostaddr}\n\
25
+send"
26
+
27
+NSUPDATE_DEL = "\
28
+server {nameserver}\n\
29
+update delete {hostname} A\n\
30
+send"
31
+
32
+def dns_zone_to_text(dnsconf=DNS_CONF):
33
+    z = dns.zone.from_xfr(dns.query.xfr(dnsconf["nameserver"],dnsconf["domain"]))
34
+    names = z.nodes.keys()
35
+    names.sort()
36
+    res = []
37
+    for n in names:
38
+        res.append(z[n].to_text(n))
39
+    log.info("dns zone loaded{}".format(res))
40
+    return res
41
+
42
+def lookup_hostname(name,dnsconf=DNS_CONF):
43
+    try:
44
+        resolv = dns.resolver.Resolver(configure=False)
45
+        log.debug("initialize resolver")
46
+        resolv.nameservers.append(dnsconf["nameserver"])
47
+        resolv.domain = dns.name.from_text(dnsconf["domain"])
48
+        resolv.search.append(dns.name.from_text(dnsconf["domain"]))
49
+        log.debug("resolver {} {}".format(dnsconf["nameserver"],dnsconf["domain"]))
50
+        try:
51
+            answer = resolv.query(name)
52
+            addr = answer.rrset[0]
53
+            log.info("lookup host {} at {}".format(name, addr))
54
+        except dns.exception.DNSException as e:#handle nxdomain - not an error
55
+            log.info("instance not found: {}".format(repr(e)))
56
+            addr = None
57
+    except dns.exception.DNSException as e:
58
+        log.error(repr(e))
59
+        addr = None
60
+    return addr
61
+
62
+def dns_update(hostname, script, hostaddr=""):
63
+        hostname = hostname + "." + DNS_CONF["domain"]
64
+        p = Popen(["/usr/bin/nsupdate", "-k", DNS_CONF["dns_keyfile"]], stdin=PIPE)
65
+        inp = script.format(
66
+            nameserver=DNS_CONF["nameserver"],
67
+            hostname=hostname, ttl=DNS_CONF["ttl"], hostaddr=hostaddr)
68
+        p.communicate(input=inp)
69
+
70
+def add_hostname(name, ip):
71
+    log.info("adding to dns {} {}".format(name, ip))
72
+    dns_update(name, NSUPDATE_ADD, ip)
73
+
74
+def del_hostname(name):
75
+    log.info("deleting from dns {}".format(name))
76
+    dns_update(name, NSUPDATE_DEL)
77
+
78
+#TODO always use dnspython do not use subprocess

+ 4
- 0
deployment_scripts/puppet/modules/dns_update/files/requirements.txt View File

@@ -0,0 +1,4 @@
1
+requests>=2.0.0
2
+dnspython>=1.12.0
3
+kombu>=3.0.2
4
+SQLAlchemy>=1.0.12

+ 14
- 0
deployment_scripts/puppet/modules/dns_update/files/setup.cfg View File

@@ -0,0 +1,14 @@
1
+[metadata]
2
+name = os_dns_updater
3
+description = service to register virtual machines in dns
4
+summary = listen to nova RabbitMQ events and update dns records
5
+author = Sberbank Technology
6
+
7
+[files]
8
+packages = os_dns_updater
9
+
10
+[global]
11
+setup-hooks = pbr.hooks.setup_hook
12
+
13
+[pbr]
14
+warnerrors = True

+ 5
- 0
deployment_scripts/puppet/modules/dns_update/files/setup.py View File

@@ -0,0 +1,5 @@
1
+import setuptools
2
+
3
+# all other params will be taken from setup.cfg
4
+setuptools.setup(packages=setuptools.find_packages(),
5
+                 setup_requires=['pbr>=1.8'], pbr=True)

+ 107
- 0
deployment_scripts/puppet/modules/dns_update/manifests/controller.pp View File

@@ -0,0 +1,107 @@
1
+class dns_update::controller {
2
+$plugin_hash      = hiera('fuel-plugin-dns-update')
3
+$amqp_hosts = hiera('amqp_hosts')
4
+$net1 = $plugin_hash['net1']
5
+$net2 = $plugin_hash['net2']
6
+$dns_key_hash=$plugin_hash['dns_key']
7
+$dns_key=$dns_key_hash['content']
8
+$rabbit_hash = hiera_hash('rabbit')
9
+$amqp_user = $rabbit_hash['user']
10
+$amqp_password = $rabbit_hash['password']
11
+$node_hash = hiera('node')
12
+$node_net = $node_hash['network_roles']
13
+$node_management = $node_net['management']
14
+$dnsupdate_mysql_exist = inline_template("<% if File.exist?('/tmp/dnsupdate-mysql.lock') -%>true<% end -%>")
15
+
16
+if $management_vip == $service_endpoint { #in case of local keystone
17
+  $region='RegionOne'
18
+}
19
+else { #in case of detach keystone
20
+  $region=hiera(region)
21
+}
22
+
23
+Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' }
24
+
25
+file {'os_dns_updater':
26
+         path => '/tmp/os_dns_updater',
27
+         source => 'puppet:///modules/dns_update/',
28
+         recurse => 'true',
29
+       }
30
+
31
+package {'python-pip':
32
+  ensure => 'installed',
33
+}
34
+
35
+package {'python-dnspython':
36
+  ensure => 'installed',
37
+}
38
+
39
+package {'python-pymysql':
40
+  ensure => 'installed'
41
+}
42
+package {'pycrypto':
43
+  ensure => 'installed',
44
+  provider => 'pip',
45
+}
46
+  file {'/etc/os_dns_updater':
47
+         ensure => 'directory',
48
+       }
49
+  if $dnsupdate_mysql_exist != 'true' {
50
+     exec {"install dns_updater":
51
+          command  => "pip install -e /tmp/os_dns_updater/",
52
+          require  => File['os_dns_updater'],
53
+     }
54
+  }
55
+  file {'openstack-dns-updater.conf':
56
+         path => '/etc/os_dns_updater/dns-updater.conf',
57
+         source => 'puppet:///modules/dns_update/etc/dns-updater.conf',
58
+         require => File['/etc/os_dns_updater'],
59
+       }
60
+  file {'example.key':
61
+         path => '/etc/os_dns_updater/exaple.key',
62
+         content => $dns_key,
63
+         require => File['/etc/os_dns_updater'],
64
+       }
65
+file_line { "vm networks configuration":
66
+    path => "/etc/os_dns_updater/dns-updater.conf",
67
+    line => "networks=$net1,$net2",
68
+    match => "networks=.*",
69
+    require => File['openstack-dns-updater.conf'],
70
+}
71
+file_line { "region configuration":
72
+    path => "/etc/os_dns_updater/dns-updater.conf",
73
+    line => "region=$region",
74
+    match => "region=.*",
75
+    require => File['openstack-dns-updater.conf'],
76
+}
77
+file_line { "amqp host configuration":
78
+    path => "/etc/os_dns_updater/dns-updater.conf",
79
+    line => "amqp_hosts=$amqp_hosts",
80
+    match => "amqp_hosts=.*",
81
+    require => File['openstack-dns-updater.conf'],
82
+}
83
+file_line { "amqp password configuration":
84
+    path => "/etc/os_dns_updater/dns-updater.conf",
85
+    line => "amqp_password=$amqp_password",
86
+    match => "amqp_password=.*",
87
+    require => File['openstack-dns-updater.conf'],
88
+}
89
+file_line { "amqp user configuration":
90
+    path => "/etc/os_dns_updater/dns-updater.conf",
91
+    line => "amqp_user=$amqp_user",
92
+    match => "amqp_user=.*",
93
+    require => File['openstack-dns-updater.conf'],
94
+}
95
+
96
+  file {'added module to dist-packages':
97
+         path => '/usr/lib/python2.7/dist-packages/os_dns_updater',
98
+         source => '/tmp/os_dns_updater/os_dns_updater',
99
+         recurse => 'true',       
100
+       }
101
+File['os_dns_updater']->
102
+Package['python-pip']->
103
+Package['python-pymysql']->
104
+Package['pycrypto']->
105
+File['/etc/os_dns_updater']
106
+
107
+}

+ 1
- 0
deployment_scripts/puppet/modules/dns_update/manifests/init.pp View File

@@ -0,0 +1 @@
1
+class dns_update {}

+ 25
- 0
deployment_scripts/puppet/modules/dns_update/manifests/mysql.pp View File

@@ -0,0 +1,25 @@
1
+class dns_update::mysql {
2
+    $mysql_hash = hiera_hash('mysql')
3
+    $mysql_pass = $mysql_hash['root_password']
4
+    Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' }
5
+    $dnsupdate_mysql_exist = inline_template("<% if File.exist?('/tmp/dnsupdate-mysql.lock') -%>true<% end -%>")
6
+
7
+    if $dnsupdate_mysql_exist != 'true' {
8
+    exec {"create dns_updater database":
9
+           command => "mysql --host=localhost --user=root --password=$mysql_pass -e 'create database dnsupdate;'",
10
+         } ->
11
+    exec {"create dns_updater user":
12
+           command => "mysql --host=localhost --user=root --password=$mysql_pass -e 'create user \"dnsupdate\"@\"%\" identified by \"ai2o3nvsjS3cvm\";'",
13
+         } ->
14
+    exec {"grant privileges to dns_updater user":
15
+           command => "mysql --host=localhost --user=root --password=$mysql_pass -e 'grant all privileges on dnsupdate.* to \"dnsupdate\"@\"%\";'",
16
+         } ->
17
+    exec {"create tables":
18
+         command => "python /tmp/os_dns_updater/db_setup.py",
19
+    } ->
20
+    file {"/tmp/dnsupdate-mysql.lock":
21
+           path => "/tmp/dnsupdate-mysql.lock",
22
+           ensure => "file",
23
+    }
24
+   }
25
+}

+ 31
- 0
deployment_scripts/puppet/modules/dns_update/manifests/neutron.pp View File

@@ -0,0 +1,31 @@
1
+class dns_update::neutron {
2
+
3
+Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' }
4
+$neutron_adv_con=hiera('neutron_advanced_configuration')
5
+$ha=$neutron_adv_con['dhcp_agent_ha']
6
+$neutron_dhcp_exist = inline_template("<% if File.exist?('/etc/init.d/neutron-dhcp-agent') -%>true<% end -%>")
7
+
8
+  neutron_config {
9
+       "DEFAULT/dns_domain": value => "vm.example.net";
10
+  }
11
+  if $neutron_dhcp_exist == "true" {
12
+     neutron_dhcp_agent_config {
13
+          "DEFAULT/dhcp_domain": value => "vm.example.net";
14
+     }
15
+     if ($ha == true) {
16
+        exec{"neutron-dhcp-agent crm restart":
17
+              command => "crm resource restart clone_neutron-dhcp-agent",
18
+        }
19
+        Neutron_config <||> ~> Exec['neutron-dhcp-agent crm restart']
20
+        Neutron_dhcp_agent_config <||> ~> Exec['neutron-dhcp-agent crm restart']
21
+     }
22
+     elsif ($ha == false) {
23
+        exec{"neutron-dhcp-agent service restart":
24
+              command => "service neutron-dhcp-agent restart",
25
+        }
26
+        Neutron_config <||> ~> Exec['neutron-dhcp-agent service restart']
27
+        Neutron_dhcp_agent_config <||> ~> Exec['neutron-dhcp-agent service restart']
28
+     }
29
+  }
30
+Neutron_config <||> ~> service { 'neutron-server': }
31
+}

+ 19
- 0
deployment_scripts/puppet/modules/dns_update/manifests/nova.pp View File

@@ -0,0 +1,19 @@
1
+class dns_update::nova {
2
+
3
+  $nova_compute_exist = inline_template("<% if File.exist?('/etc/init.d/nova-compute') -%>true<% end -%>")
4
+  $nova_api_exist = inline_template("<% if File.exist?('/etc/init.d/nova-api') -%>true<% end -%>")
5
+
6
+  nova_config {
7
+    "DEFAULT/dhcp_domain": value => "vm.example.net";
8
+  }
9
+
10
+  if $nova_compute_exist == "true"
11
+  {
12
+    Nova_config <||> ~> service { 'nova-compute': }
13
+  }
14
+
15
+  if $nova_api_exist == "true"
16
+  {
17
+    Nova_config <||> ~> service { 'nova-api': }
18
+  }
19
+}

+ 38
- 0
deployment_scripts/puppet/modules/dns_update/manifests/pacemaker.pp View File

@@ -0,0 +1,38 @@
1
+class dns_update::pacemaker {
2
+Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' }
3
+$operations = {
4
+    'monitor' => {'interval' => '5s', 'timeout' => '30s' },
5
+    'start'   => {'interval' => '0s', timeout => '30s' },
6
+    'stop'   => {'interval' => '0s', timeout => '30s' }
7
+}
8
+
9
+file {'DnsUpdater':
10
+         path => '/usr/lib/ocf/resource.d/fuel/DnsUpdater',
11
+         source => '/tmp/os_dns_updater/ocf/DnsUpdater',
12
+       }
13
+
14
+pacemaker::service { "DnsUpdater":
15
+   primitive_class => 'ocf',
16
+   primitive_provider => 'fuel',
17
+   primitive_type => 'DnsUpdater',
18
+   operations => $operations,
19
+   use_handler => false,
20
+   complex_type => 'clone',
21
+}
22
+
23
+service { "DnsUpdater":
24
+   ensure => running,
25
+   name => 'DnsUpdater',
26
+   enable => true,
27
+   provider => 'pacemaker'
28
+}
29
+
30
+exec {"Cleanup resources":
31
+   command => "crm resource cleanup clone_p_DnsUpdater",
32
+}
33
+
34
+File['DnsUpdater'] ->
35
+Service['DnsUpdater'] ->
36
+Exec['Cleanup resources']
37
+
38
+}

+ 16
- 0
deployment_scripts/puppet/modules/dns_update/manifests/service.pp View File

@@ -0,0 +1,16 @@
1
+class dns_update::service {
2
+
3
+Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' }
4
+
5
+  file {'init openstack-dns-updater.conf':
6
+         path => '/etc/init/openstack-dns-updater.conf',
7
+         source => '/tmp/os_dns_updater/openstack-dns-updater.conf',
8
+       }
9
+
10
+exec{"start openstack-dns-updater":
11
+     command => "service openstack-dns-updater start",
12
+     require => File['init openstack-dns-updater.conf'],
13
+     returns => [0,1],
14
+}
15
+
16
+}

+ 64
- 0
deployment_tasks.yaml View File

@@ -0,0 +1,64 @@
1
+- id: fp-dns-update-controller
2
+  role: ['primary-controller','controller']
3
+  version: 2.0.0
4
+  type: puppet
5
+  parameters:
6
+    puppet_manifest: puppet/manifests/controller.pp
7
+    puppet_modules: puppet/modules:/etc/puppet/modules
8
+    timeout: 360
9
+  requires: ['post_deployment_start']
10
+  required_for: ['post_deployment_end']
11
+- id: fp-dns-update-mysql
12
+  role: ['primary-controller']
13
+  version: 2.0.0
14
+  type: puppet
15
+  parameters:
16
+    puppet_manifest: puppet/manifests/mysql.pp 
17
+    puppet_modules: puppet/modules:/etc/puppet/modules
18
+    timeout: 360
19
+  requires: ['post_deployment_start','fp-dns-update-controller']
20
+  required_for: ['post_deployment_end']
21
+- id: fp-dns-update-service
22
+  role: ['primary-controller','controller']
23
+  version: 2.0.0
24
+  type: puppet
25
+  cross-depends:
26
+    - name: fp-dns-update-controller
27
+      role: 'controller'
28
+  parameters:
29
+    puppet_manifest: puppet/manifests/service.pp
30
+    puppet_modules: puppet/modules:/etc/puppet/modules
31
+    timeout: 360
32
+  requires: ['post_deployment_start','fp-dns-update-mysql']
33
+  required_for: ['post_deployment_end']
34
+- id: fp-dns-update-nova
35
+  role: ['primary-controller','controller','compute']
36
+  version: 2.0.0
37
+  type: puppet
38
+  parameters:
39
+    puppet_manifest: puppet/manifests/nova.pp
40
+    puppet_modules: puppet/modules:/etc/puppet/modules
41
+    timeout: 360
42
+  requires: ['post_deployment_start']
43
+  required_for: ['post_deployment_end']
44
+- id: fp-dns-update-neutron
45
+  role: ['primary-controller','controller','primary-network-node','network-node']
46
+  version: 2.0.0
47
+  type: puppet
48
+  parameters:
49
+    puppet_manifest: puppet/manifests/neutron.pp
50
+    puppet_modules: puppet/modules:/etc/puppet/modules
51
+    timeout: 360
52
+  requires: ['post_deployment_start']
53
+  required_for: ['post_deployment_end']
54
+- id: fp-dns-update-pacemaker
55
+  role: ['primary-controller','controller']
56
+  version: 2.0.0
57
+  type: puppet
58
+  parameters:
59
+    puppet_manifest: puppet/manifests/pacemaker.pp
60
+    puppet_modules: puppet/modules:/etc/puppet/modules
61
+    timeout: 360
62
+  requires: ['fp-dns-update-mysql','fp-dns-update-service']
63
+  required_for: ['post_deployment_end']
64
+

+ 19
- 0
environment_config.yaml View File

@@ -0,0 +1,19 @@
1
+attributes:
2
+  metadata:
3
+    group: 'other'
4
+  net1:
5
+    type: "text"
6
+    weight: 10
7
+    value: ""
8
+    label: "Net1 Network name"
9
+  net2:
10
+    type: "text"
11
+    weight: 11
12
+    value: ""
13
+    label: "Net2 Network name"
14
+  dns_key:
15
+    type: "file"
16
+    weight: 12
17
+    value: ""
18
+    label: "Key for DNS server"
19
+

+ 36
- 0
metadata.yaml View File

@@ -0,0 +1,36 @@
1
+# Plugin name
2
+name: fuel-plugin-dns-update
3
+title: DNS Update plugin
4
+# Plugin version
5
+version: 0.2.3
6
+# Description
7
+description: Enables custom dns servers
8
+# Required fuel version
9
+fuel_version: ['9.0']
10
+# Groups
11
+groups: []
12
+# Licenses
13
+licenses: ['Apache License, Version 2.0']
14
+# Homepage
15
+homepage: https://github.com/openstack/fuel-plugin-dns-updater
16
+# Authors
17
+authors: ['Ivan Zinoviev <zinoviev.ii@gmail.com>']
18
+# Change `false` to `true` if the plugin can be installed in the environment
19
+# after the deployment.
20
+is_hotpluggable: true
21
+
22
+# The plugin is compatible with releases in the list
23
+releases:
24
+  - os: ubuntu
25
+    version: liberty-8.0
26
+    mode: ['ha']
27
+    deployment_scripts_path: deployment_scripts/
28
+    repository_path: repositories/ubuntu
29
+  - os: ubuntu
30
+    version: mitaka-9.0
31
+    mode: ['ha']
32
+    deployment_scripts_path: deployment_scripts/
33
+    repository_path: repositories/ubuntu
34
+
35
+# Version of plugin package
36
+package_version: '4.0.0'

+ 0
- 0
repositories/centos/.gitkeep View File


+ 0
- 0
repositories/ubuntu/.gitkeep View File


+ 1
- 0
tasks.yaml View File

@@ -0,0 +1 @@
1
+[]

Loading…
Cancel
Save