Class: Conjur::Conjurize::Script

Inherits:
Object
  • Object
show all
Defined in:
lib/conjur/conjurize/script.rb

Overview

generates a shell script to conjurize a host

Constant Summary collapse

COOKBOOK_RELEASES_URL =
"https://api.github.com/repos/conjur-cookbooks/conjur/releases".freeze
HEADER =
<<-HEADER.freeze
#!/bin/sh
set -e

# Implementation note: 'tee' is used as a sudo-friendly 'cat' to populate a file with the contents provided below.
HEADER

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Script

Returns a new instance of Script.



42
43
44
# File 'lib/conjur/conjurize/script.rb', line 42

def initialize options
  @options = options
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



46
47
48
# File 'lib/conjur/conjurize/script.rb', line 46

def options
  @options
end

Class Method Details

.generate(configuration, options) ⇒ Object



73
74
75
# File 'lib/conjur/conjurize/script.rb', line 73

def self.generate configuration, options
  new(options).generate configuration
end

.identity(configuration) ⇒ Object



116
117
118
119
120
121
122
# File 'lib/conjur/conjurize/script.rb', line 116

def self.identity configuration
  """
    machine #{configuration['appliance_url']}/authn
    login host/#{configuration['id']}
    password #{configuration['api_key']}
  """
end

.latest_conjur_cookbook_releaseObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/conjur/conjurize/script.rb', line 20

def self.latest_conjur_cookbook_release
  json = JSON.parse open(COOKBOOK_RELEASES_URL).read
  tarballs = tarballs_of_releases json

  latest = tarballs.first
  selected = tarballs.find { |release| !release[1].empty? }

  if selected != latest
    warn "WARNING: Latest cookbook release (#{latest.first}) does not "\
        "contain a valid package. Falling back to #{selected.first}."
  end

  selected[1].first
end

.rc(configuration) ⇒ Object



106
107
108
109
110
111
112
113
114
# File 'lib/conjur/conjurize/script.rb', line 106

def self.rc configuration
  [
    "account: #{configuration['account']}",
    "appliance_url: #{configuration['appliance_url']}",
    "cert_file: /etc/conjur-#{configuration['account']}.pem",
    "netrc_path: /etc/conjur.identity",
    "plugins: []"
  ].join "\n"
end

.tarballs_of_releases(releases) ⇒ Object



10
11
12
13
14
15
16
17
18
# File 'lib/conjur/conjurize/script.rb', line 10

def self.tarballs_of_releases releases
  releases.map do |release|
    assets = release["assets"].select do |asset|
      asset["name"] =~ /conjur-v\d.\d.\d.tar.gz/
    end

    [release["name"], assets.map { |asset| asset["browser_download_url"] }]
  end
end

Instance Method Details

#chef_executableObject



85
86
87
# File 'lib/conjur/conjurize/script.rb', line 85

def chef_executable
  options[:"chef-executable"] || "chef-solo"
end

#chef_scriptObject



97
98
99
100
101
102
103
104
# File 'lib/conjur/conjurize/script.rb', line 97

def chef_script
  @chef_script ||= [
    ("curl -L https://www.opscode.com/chef/install.sh | " + sudo["bash"] \
      if install_chef?),
    (sudo["#{chef_executable} --recipe-url #{conjur_cookbook_url} " \
        "-o #{conjur_run_list}"] if run_chef?)
  ].join "\n"
end

#configure_conjur(configuration) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/conjur/conjurize/script.rb', line 124

def configure_conjur configuration
  [
    write_file("/etc/conjur.conf", Script.rc(configuration)),
    write_file(
      "/etc/conjur-#{configuration['account']}.pem",
      configuration["certificate"]
    ),
    write_file(
      "/etc/conjur.identity",
      Script.identity(configuration),
      mode: 0600
    )
  ].join "\n"
end

#conjur_cookbook_urlObject



89
90
91
# File 'lib/conjur/conjurize/script.rb', line 89

def conjur_cookbook_url
  options[:"conjur-cookbook-url"] || Script.latest_conjur_cookbook_release
end

#conjur_run_listObject



93
94
95
# File 'lib/conjur/conjurize/script.rb', line 93

def conjur_run_list
  options[:"conjur-run-list"] || "conjur"
end

#generate(configuration) ⇒ Object



139
140
141
142
143
144
145
146
147
148
# File 'lib/conjur/conjurize/script.rb', line 139

def generate configuration
  fail "No 'id' field in host JSON" unless configuration["id"]
  fail "No 'api_key' field in host JSON" unless configuration["api_key"]

  [
    HEADER,
    configure_conjur(configuration),
    chef_script
  ].join("\n")
end

#install_chef?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/conjur/conjurize/script.rb', line 77

def install_chef?
  run_chef? && !options[:"chef-executable"]
end

#run_chef?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/conjur/conjurize/script.rb', line 81

def run_chef?
  options.values_at(:ssh, :"conjur-run-list").any?
end

#set_mode(path, mode) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/conjur/conjurize/script.rb', line 65

def set_mode path, mode
  mode = mode.to_s(8) if mode.respond_to? :to_int
  [
    [sudo["touch"], path].join(" "),
    [sudo["chmod"], mode, path].join(" ")
  ].join("\n")
end

#sudoObject



48
49
50
# File 'lib/conjur/conjurize/script.rb', line 48

def sudo
  @sudo ||= options["sudo"] ? ->(x) { "sudo -n #{x}" } : ->(x) { x }
end

#write_file(path, content, options = {}) ⇒ Object

Generate a piece of shell to write to a file

Parameters:

  • path (String)

    absolute path to write to

  • content (String)

    contents to write

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :mode (String, Fixnum)

    mode to apply to the file



56
57
58
59
60
61
62
63
# File 'lib/conjur/conjurize/script.rb', line 56

def write_file path, content, options = {}
  [
    ((mode = options[:mode]) && set_mode(path, mode)),
    [sudo["tee"], path, "> /dev/null << EOF"].join(" "),
    content.strip,
    "EOF\n"
  ].compact.join("\n")
end