Modernise mysql LWRPs
authorTom Hughes <tom@compton.nu>
Wed, 22 Nov 2017 18:07:29 +0000 (18:07 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 22 Nov 2017 18:07:29 +0000 (18:07 +0000)
cookbooks/mysql/libraries/mysql.rb
cookbooks/mysql/providers/database.rb [deleted file]
cookbooks/mysql/providers/user.rb [deleted file]
cookbooks/mysql/resources/database.rb
cookbooks/mysql/resources/user.rb

index 7c45022..516c38a 100644 (file)
@@ -1,8 +1,8 @@
 require "chef/mixin/shell_out"
 require "rexml/document"
 
-class Chef
-  class MySQL
+module OpenStreetMap
+  module MySQL
     include Chef::Mixin::ShellOut
 
     USER_PRIVILEGES = [
@@ -20,7 +20,7 @@ class Chef
       :execute, :event, :trigger
     ].freeze
 
-    def execute(options)
+    def mysql_execute(options)
       # Create argument array
       args = []
 
@@ -55,7 +55,7 @@ class Chef
 
     def query(sql, options = {})
       # Run the query
-      result = execute(options.merge(:command => sql, :xml => true))
+      result = mysql_execute(options.merge(:command => sql, :xml => true))
 
       # Parse the output
       document = REXML::Document.new(result.stdout)
@@ -84,8 +84,8 @@ class Chef
       records
     end
 
-    def users
-      @users ||= query("SELECT * FROM user").each_with_object({}) do |user, users|
+    def mysql_users
+      @mysql_users ||= query("SELECT * FROM user").each_with_object({}) do |user, users|
         name = "'#{user[:user]}'@'#{user[:host]}'"
 
         users[name] = USER_PRIVILEGES.each_with_object({}) do |privilege, privileges|
@@ -94,15 +94,15 @@ class Chef
       end
     end
 
-    def databases
-      @databases ||= query("SHOW databases").each_with_object({}) do |database, databases|
+    def mysql_databases
+      @mysql_databases ||= query("SHOW databases").each_with_object({}) do |database, databases|
         databases[database[:database]] = {
           :permissions => {}
         }
       end
 
       query("SELECT * FROM db").each do |record|
-        database = @databases[record[:db]]
+        database = @mysql_databases[record[:db]]
 
         next unless database
 
@@ -113,10 +113,10 @@ class Chef
         end
       end
 
-      @databases
+      @mysql_databases
     end
 
-    def canonicalise_user(user)
+    def mysql_canonicalise_user(user)
       local, host = user.split("@")
 
       host ||= "%"
@@ -127,7 +127,7 @@ class Chef
       "#{local}@#{host}"
     end
 
-    def privilege_name(privilege)
+    def mysql_privilege_name(privilege)
       case privilege
       when :grant
         "GRANT OPTION"
diff --git a/cookbooks/mysql/providers/database.rb b/cookbooks/mysql/providers/database.rb
deleted file mode 100644 (file)
index 0e7e909..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# Cookbook Name:: mysql
-# Provider:: mysql_database
-#
-# Copyright 2013, OpenStreetMap Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-use_inline_resources
-
-def load_current_resource
-  @mysql = Chef::MySQL.new
-
-  @current_resource = Chef::Resource::MysqlDatabase.new(new_resource.name)
-  @current_resource.database(new_resource.database)
-  if (mysql_database = @mysql.databases[@current_resource.database])
-    @current_resource.permissions(mysql_database[:permissions])
-  end
-  @current_resource
-end
-
-action :create do
-  unless @mysql.databases.include?(new_resource.database)
-    converge_by("create #{new_resource}") do
-      Chef::Log.info("Creating #{new_resource}")
-      @mysql.execute(:command => "CREATE DATABASE `#{new_resource.database}`")
-    end
-  end
-
-  new_permissions = Hash[new_resource.permissions.collect do |user, privileges|
-    [@mysql.canonicalise_user(user), privileges]
-  end]
-
-  @current_resource.permissions.each_key do |user|
-    next if new_permissions[user]
-
-    converge_by("revoke all for #{user} on #{new_resource}") do
-      Chef::Log.info("Revoking all for #{user} on #{new_resource}")
-      @mysql.execute(:command => "REVOKE ALL ON `#{new_resource.database}`.* FROM #{user}")
-    end
-  end
-
-  new_permissions.each do |user, new_privileges|
-    current_privileges = @current_resource.permissions[user] || {}
-    new_privileges = Array(new_privileges)
-
-    if new_privileges.include?(:all)
-      new_privileges |= (Chef::MySQL::DATABASE_PRIVILEGES - [:grant])
-    end
-
-    Chef::MySQL::DATABASE_PRIVILEGES.each do |privilege|
-      if new_privileges.include?(privilege)
-        unless current_privileges.include?(privilege)
-          converge_by("grant #{privilege} for #{user} on mysql database #{new_resource}") do
-            Chef::Log.info("Granting #{privilege} for #{user} on mysql database #{new_resource}")
-            @mysql.execute(:command => "GRANT #{@mysql.privilege_name(privilege)} ON `#{new_resource.database}`.* TO #{user}")
-          end
-        end
-      elsif current_privileges.include?(privilege)
-        converge_by("revoke #{privilege} for #{user} on #{new_resource}") do
-          Chef::Log.info("Revoking #{privilege} for #{user} on #{new_resource}")
-          @mysql.execute(:command => "REVOKE #{@mysql.privilege_name(privilege)} ON `#{new_resource.database}`.* FROM #{user}")
-        end
-      end
-    end
-  end
-end
-
-action :drop do
-  if @mysql.databases.include?(new_resource.database)
-    converge_by("drop #{new_resource}") do
-      Chef::Log.info("Dropping #{new_resource}")
-      @mysql.execute(:command => "DROP DATABASE `#{new_resource.database}`")
-    end
-  end
-end
diff --git a/cookbooks/mysql/providers/user.rb b/cookbooks/mysql/providers/user.rb
deleted file mode 100644 (file)
index c2f5e58..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Cookbook Name:: mysql
-# Provider:: mysql_user
-#
-# Copyright 2013, OpenStreetMap Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-use_inline_resources
-
-def load_current_resource
-  @mysql = Chef::MySQL.new
-
-  @current_resource = Chef::Resource::MysqlUser.new(new_resource.name)
-  @current_resource.user(new_resource.user)
-  if (mysql_user = @mysql.users[@current_resource.user])
-    Chef::MySQL::USER_PRIVILEGES.each do |privilege|
-      @current_resource.send(privilege, mysql_user[privilege])
-    end
-  end
-  @current_resource
-end
-
-action :create do
-  user = @mysql.canonicalise_user(new_resource.user)
-  password = new_resource.password ? "IDENTIFIED BY '#{new_resource.password}'" : ""
-
-  unless @mysql.users.include?(user)
-    converge_by("create #{new_resource}") do
-      Chef::Log.info("Creating #{new_resource}")
-      @mysql.execute(:command => "CREATE USER #{user} #{password}")
-    end
-  end
-
-  Chef::MySQL::USER_PRIVILEGES.each do |privilege|
-    next if new_resource.send(privilege) == @current_resource.send(privilege)
-
-    if new_resource.send(privilege)
-      converge_by("grant #{privilege} for #{new_resource}") do
-        Chef::Log.info("Granting #{privilege} for #{new_resource}")
-        @mysql.execute(:command => "GRANT #{@mysql.privilege_name(privilege)} ON *.* TO #{user}")
-      end
-    else
-      converge_by("revoke #{privilege} for #{new_resource}") do
-        Chef::Log.info("Revoking #{privilege} for #{new_resource}")
-        @mysql.execute(:command => "REVOKE #{@mysql.privilege_name(privilege)} ON *.* FROM #{user}")
-      end
-    end
-  end
-end
-
-action :drop do
-  user = @mysql.canonicalise_user(new_resource.user)
-
-  if @mysql.users.include?(user)
-    converge_by("drop #{new_resource}") do
-      Chef::Log.info("Dropping #{new_resource}")
-      @mysql.execute(:command => "DROP USER #{user}")
-    end
-  end
-end
index 60236d8..1cb8136 100644 (file)
 # limitations under the License.
 #
 
-actions :create, :drop
 default_action :create
 
-attribute :database, :kind_of => String, :name_attribute => true
-attribute :permissions, :kind_of => Hash, :default => {}
+property :database, :kind_of => String, :name_attribute => true
+property :permissions, :kind_of => Hash, :default => {}
+
+action :create do
+  unless mysql_databases.include?(new_resource.database)
+    converge_by("create #{new_resource}") do
+      Chef::Log.info("Creating #{new_resource}")
+      mysql_execute(:command => "CREATE DATABASE `#{new_resource.database}`")
+    end
+  end
+
+  current_permissions = mysql_databases[new_resource.database]&.dig(:permissions) || {}
+
+  new_permissions = Hash[new_resource.permissions.collect do |user, privileges|
+    [mysql_canonicalise_user(user), privileges]
+  end]
+
+  current_permissions.each_key do |user|
+    next if new_permissions[user]
+
+    converge_by("revoke all for #{user} on #{new_resource}") do
+      Chef::Log.info("Revoking all for #{user} on #{new_resource}")
+      mysql_execute(:command => "REVOKE ALL ON `#{new_resource.database}`.* FROM #{user}")
+    end
+  end
+
+  new_permissions.each do |user, new_privileges|
+    current_privileges = current_permissions[user] || {}
+    new_privileges = Array(new_privileges)
+
+    if new_privileges.include?(:all)
+      new_privileges |= (OpenStreetMap::MySQL::DATABASE_PRIVILEGES - [:grant])
+    end
+
+    OpenStreetMap::MySQL::DATABASE_PRIVILEGES.each do |privilege|
+      if new_privileges.include?(privilege)
+        unless current_privileges.include?(privilege)
+          converge_by("grant #{privilege} for #{user} on mysql database #{new_resource}") do
+            Chef::Log.info("Granting #{privilege} for #{user} on mysql database #{new_resource}")
+            mysql_execute(:command => "GRANT #{mysql_privilege_name(privilege)} ON `#{new_resource.database}`.* TO #{user}")
+          end
+        end
+      elsif current_privileges.include?(privilege)
+        converge_by("revoke #{privilege} for #{user} on #{new_resource}") do
+          Chef::Log.info("Revoking #{privilege} for #{user} on #{new_resource}")
+          mysql_execute(:command => "REVOKE #{mysql_privilege_name(privilege)} ON `#{new_resource.database}`.* FROM #{user}")
+        end
+      end
+    end
+  end
+end
+
+action :drop do
+  if mysql_databases.include?(new_resource.database)
+    converge_by("drop #{new_resource}") do
+      Chef::Log.info("Dropping #{new_resource}")
+      mysql_execute(:command => "DROP DATABASE `#{new_resource.database}`")
+    end
+  end
+end
+
+action_class do
+  include OpenStreetMap::MySQL
+end
index 45436c7..329778c 100644 (file)
 # limitations under the License.
 #
 
-actions :create, :drop
 default_action :create
 
-attribute :user, :kind_of => String, :name_attribute => true
-attribute :password, :kind_of => String
+property :user, :kind_of => String, :name_attribute => true
+property :password, :kind_of => String
 
-Chef::MySQL::USER_PRIVILEGES.each do |privilege|
-  attribute privilege, :default => false
+OpenStreetMap::MySQL::USER_PRIVILEGES.each do |privilege|
+  property privilege, :default => false
+end
+
+action :create do
+  user = mysql_canonicalise_user(new_resource.user)
+  password = new_resource.password ? "IDENTIFIED BY '#{new_resource.password}'" : ""
+
+  unless mysql_users.include?(user)
+    converge_by("create #{new_resource}") do
+      Chef::Log.info("Creating #{new_resource}")
+      mysql_execute(:command => "CREATE USER #{user} #{password}")
+    end
+  end
+
+  current_privileges = mysql_users.fetch(new_resource.user, {})
+
+  new_privileges = Hash[OpenStreetMap::MySQL::USER_PRIVILEGES.collect do |privilege|
+    [privilege, new_resource.send(privilege)]
+  end]
+
+  new_privileges.each do |privilege, new_enabled|
+    old_enabled = current_privileges.fetch(privilege, false)
+
+    if new_enabled && !old_enabled
+      converge_by("grant #{privilege} for #{new_resource}") do
+        Chef::Log.info("Granting #{privilege} for #{new_resource}")
+        mysql_execute(:command => "GRANT #{mysql_privilege_name(privilege)} ON *.* TO #{user}")
+      end
+    elsif old_enabled && !new_enabled
+      converge_by("revoke #{privilege} for #{new_resource}") do
+        Chef::Log.info("Revoking #{privilege} for #{new_resource}")
+        mysql_execute(:command => "REVOKE #{mysql_privilege_name(privilege)} ON *.* FROM #{user}")
+      end
+    end
+  end
+end
+
+action :drop do
+  user = mysql_canonicalise_user(new_resource.user)
+
+  if mysql_users.include?(user)
+    converge_by("drop #{new_resource}") do
+      Chef::Log.info("Dropping #{new_resource}")
+      mysql_execute(:command => "DROP USER #{user}")
+    end
+  end
+end
+
+action_class do
+  include OpenStreetMap::MySQL
 end