Completed
Push — epic/2.0.0 ( 6299a3...0f9568 )
by Steven
19:22 queued 08:17
created

Mongodb.get_mongod_conf_file()   A

Complexity

Conditions 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 2
dl 0
loc 8
rs 9.4285
1
require 'yaml'
2
require 'json'
3
class Puppet::Provider::Mongodb < Puppet::Provider
4
5
  # Without initvars commands won't work.
6
  initvars
7
  commands :mongo => 'mongo'
8
9
  # Optional defaults file
10
  def self.mongorc_file
11
    if File.file?("#{Facter.value(:root_home)}/.mongorc.js")
12
      "load('#{Facter.value(:root_home)}/.mongorc.js'); "
13
    else
14
      nil
15
    end
16
  end
17
18
  def mongorc_file
19
    self.class.mongorc_file
20
  end
21
22
  def self.get_mongod_conf_file
23
    if File.exists? '/etc/mongod.conf'
24
      file = '/etc/mongod.conf'
25
    else
26
      file = '/etc/mongodb.conf'
27
    end
28
    file
29
  end
30
31
  def self.get_conn_string
32
    file = get_mongod_conf_file
33
    # The mongo conf is probably a key-value store, even though 2.6 is
34
    # supposed to use YAML, because the config template is applied
35
    # based on $::mongodb::globals::version which is the user will not
36
    # necessarily set. This attempts to get the port from both types of
37
    # config files.
38
    config = YAML.load_file(file)
39
    if config.kind_of?(Hash) # Using a valid YAML file for mongo 2.6
40
      bindip = config['net.bindIp']
41
      port = config['net.port']
42
      shardsvr = config['sharding.clusterRole']
43
      confsvr = config['sharding.clusterRole']
44
    else # It has to be a key-value config file
45
      config = {}
46
      File.readlines(file).collect do |line|
47
         k,v = line.split('=')
48
         config[k.rstrip] = v.lstrip.chomp if k and v
49
      end
50
      bindip = config['bind_ip']
51
      port = config['port']
52
      shardsvr = config['shardsvr']
53
      confsvr = config['confsvr']
54
    end
55
56
    if bindip
57
      first_ip_in_list = bindip.split(',').first
58
      if first_ip_in_list.eql? '0.0.0.0'
59
        ip_real = '127.0.0.1'
60
      else
61
        ip_real = first_ip_in_list
62
      end
63
    end
64
65
    if port
66
      port_real = port
67
    elsif !port and (confsvr.eql? 'configsvr' or confsvr.eql? 'true')
68
      port_real = 27019
69
    elsif !port and (shardsvr.eql? 'shardsvr' or shardsvr.eql? 'true')
70
      port_real = 27018
71
    else
72
      port_real = 27017
73
    end
74
75
    "#{ip_real}:#{port_real}"
76
  end
77
78
  def self.db_ismaster
79
    cmd_ismaster = 'printjson(db.isMaster())'
80
    if mongorc_file
81
        cmd_ismaster = mongorc_file + cmd_ismaster
82
    end
83
    out = mongo(['admin', '--quiet', '--host', get_conn_string, '--eval', cmd_ismaster])
84
    out.gsub!(/ObjectId\(([^)]*)\)/, '\1')
85
    out.gsub!(/ISODate\((.+?)\)/, '\1 ')
86
    out.gsub!(/^Error\:.+/, '')
87
    res = JSON.parse out
88
89
    return res['ismaster']
90
  end
91
92
  def db_ismaster
93
    self.class.db_ismaster
94
  end
95
96
  def self.auth_enabled
97
    auth_enabled = false
98
    file = get_mongod_conf_file
99
    config = YAML.load_file(file)
100
    if config.kind_of?(Hash)
101
      auth_enabled = config['security.authorization']
102
    else # It has to be a key-value store
103
      config = {}
104
      File.readlines(file).collect do |line|
105
        k,v = line.split('=')
106
        config[k.rstrip] = v.lstrip.chomp if k and v
107
      end
108
      auth_enabled = config['auth']
109
    end
110
    return auth_enabled
111
  end
112
113
  # Mongo Command Wrapper
114
  def self.mongo_eval(cmd, db = 'admin', retries = 10, host = nil)
115
    retry_count = retries
116
    retry_sleep = 3
117
    if mongorc_file
118
        cmd = mongorc_file + cmd
119
    end
120
121
    out = nil
122
    retry_count.times do |n|
123
      begin
124
        if host
125
          out = mongo([db, '--quiet', '--host', host, '--eval', cmd])
126
        else
127
          out = mongo([db, '--quiet', '--host', get_conn_string, '--eval', cmd])
128
        end
129
      rescue => e
130
        Puppet.debug "Request failed: '#{e.message}' Retry: '#{n}'"
131
        sleep retry_sleep
132
        next
133
      end
134
      break
135
    end
136
137
    if !out
138
      raise Puppet::ExecutionFailure, "Could not evalute MongoDB shell command: #{cmd}"
139
    end
140
141
    out.gsub!(/ObjectId\(([^)]*)\)/, '\1')
142
    out.gsub!(/^Error\:.+/, '')
143
    out
144
  end
145
146
  def mongo_eval(cmd, db = 'admin', retries = 10, host = nil)
147
    self.class.mongo_eval(cmd, db, retries, host)
148
  end
149
150
  # Mongo Version checker
151
  def self.mongo_version
152
    @@mongo_version ||= self.mongo_eval('db.version()')
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using a class variable like @@mongo_version is generally not recommended; did you consider
using an class instance variable instead?
Loading history...
153
  end
154
155
  def mongo_version
156
    self.class.mongo_version
157
  end
158
159
  def self.mongo_24?
160
    v = self.mongo_version
161
    ! v[/^2\.4\./].nil?
162
  end
163
164
  def mongo_24?
165
    self.class.mongo_24?
166
  end
167
168
end
169