Class: PicsolveDockerBuilder::Composer::Requirements::Postgres

Inherits:
Base
  • Object
show all
Defined in:
lib/picsolve_docker_builder/composer/requirements/postgres.rb

Overview

Postgres db requirements

Instance Attribute Summary

Attributes inherited from Base

#config, #name

Instance Method Summary collapse

Methods inherited from Base

#container, #create_secret, #delete_secret, #gen_password, #get_secret, #initialize, #kubernetes, #namespace, #stage

Methods included from Base

#base_dir, #config, #config_file, #config_path, #config_paths, #create_logger, #default_config, #log, #read_config, #validate_config

Constructor Details

This class inherits a constructor from PicsolveDockerBuilder::Composer::Requirements::Base

Instance Method Details

#admin_connObject



71
72
73
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 71

def admin_conn
  @admin_conn ||= create_admin_conn
end

#admin_conn_closeObject



75
76
77
78
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 75

def admin_conn_close
  admin_conn.close
  @admin_conn = nil
end

#admin_postgres_secretObject

get administrative postgres secrets



161
162
163
164
165
166
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 161

def admin_postgres_secret
  return @admin_postgres_secret unless @admin_postgres_secret.nil?
  @admin_postgres_secret = get_secret('postgres')
  @admin_postgres_secret.update('dbname' => 'postgres')
  @admin_postgres_secret
end

#cleanup_postgres_databaseObject

cleanup postgres database



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 81

def cleanup_postgres_database
  dbname = admin_conn.escape_string(user_and_db_name)

  begin
    sql = "DROP DATABASE \"#{dbname}\";"
    admin_conn.exec sql
    log.info "removed database #{user_and_db_name}"
  rescue
    log.warn "removing database #{user_and_db_name} failed"
  end

  begin
    sql = "DROP USER \"#{dbname}\";"
    admin_conn.exec sql
    log.info "removed user #{user_and_db_name}"
  rescue
    log.warn "removing user #{user_and_db_name} failed"
  end

  begin
    delete_secret user_and_db_name
    log.info "removed secret #{user_and_db_name}"
  rescue
    log.warn "removing secret #{user_and_db_name} failed"
  end
end

#create_admin_connObject



61
62
63
64
65
66
67
68
69
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 61

def create_admin_conn
  admin_secret = admin_postgres_secret.clone
  admin_secret['host'] = '127.0.0.1'
  admin_secret['port'] = forward.local_port
  log.info 'open postgres connection to ' \
    "#{admin_secret['host']}:#{admin_secret['port']}" \
    " with user #{admin_secret['user']}"
  PG::Connection.open(admin_secret)
end

#create_postgres_database(container_secret) ⇒ Object

create postgres database rubocop:disable Metrics/MethodLength



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 110

def create_postgres_database(container_secret)
  log.info "Create database #{user_and_db_name}"

  user = admin_conn.escape_string(container_secret['user'])
  password = admin_conn.escape_string(container_secret['password'])
  name = admin_conn.escape_string(container_secret['name'])

  # create user
  admin_conn.exec(
    "CREATE USER \"#{user}\" " \
    "WITH PASSWORD '#{password}'"
  )

  # create db
  admin_conn.exec(
    "CREATE DATABASE \"#{name}\""
  )

  # grant all rights to the user and the aws user
  admin_conn.exec("
    GRANT ALL PRIVILEGES ON DATABASE \"#{name}\" to \"#{user}\";
    GRANT ALL PRIVILEGES ON DATABASE \"#{name}\" to \"rds_superuser\";
  ")

  admin_conn_close

  admin_secret = admin_postgres_secret.clone
  admin_secret['dbname'] = name
  admin_secret['user'] = user
  admin_secret['password'] = password
  conn = PG::Connection.open(admin_secret)

  conn.exec("
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES
    ON TABLES TO \"#{user}\";
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES
    ON TABLES TO \"rds_superuser\";
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES
    ON SEQUENCES TO \"#{user}\";
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES
    ON SEQUENCES TO \"rds_superuser\";
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES
    ON FUNCTIONS TO \"#{user}\";
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES
    ON FUNCTIONS TO \"rds_superuser\";
  ")
  conn.close
end

#create_postgres_secretObject

create a new postgres secret and create the according database



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 42

def create_postgres_secret
  log.info "Create secret for #{user_and_db_name} database"
  container_secret = {
    'name' => user_and_db_name,
    'user' => user_and_db_name,
    'password' => gen_password,
    'host' => admin_postgres_secret['host'],
    'port' => admin_postgres_secret['port']
  }
  create_postgres_database(
    container_secret
  )
  create_secret(
    user_and_db_name,
    container_secret
  )
  container_secret
end

#environmentObject



185
186
187
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 185

def environment
  environment_secret
end

#environment_secretObject



176
177
178
179
180
181
182
183
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 176

def environment_secret
  postgres_secret.map do |key, value|
    {
      'name'  => "#{name.upcase}_#{key.upcase}",
      'value' => value
    }
  end
end

#forwardObject

ssh port forward



32
33
34
35
36
37
38
39
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 32

def forward
  return @forward unless @forward.nil?
  @forward = ssh_forward(
    admin_postgres_secret['host'],
    admin_postgres_secret['port'].to_i
  )
  @forward
end

#postgres_secretObject

get postgres secret for current container



23
24
25
26
27
28
29
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 23

def postgres_secret
  get_secret(user_and_db_name)
rescue KubeException => e
  raise e unless e.message.match(/not found/)
  log.info "Secret for #{user_and_db_name} database not found"
  create_postgres_secret
end

#postgres_secret_nameObject



172
173
174
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 172

def postgres_secret_name
  "postgres-#{user_and_db_name}"
end

#ssh_forward(host, port) ⇒ Object



12
13
14
15
16
17
18
19
20
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 12

def ssh_forward(host, port)
  @ssh = PicsolveDockerBuilder::Helpers::SshConnection.new(
    ssh_host: kubernetes.host,
    ssh_port: kubernetes.port
  )
  forward = @ssh.forward(host, port)
  @ssh.start
  forward
end

#user_and_db_nameObject



168
169
170
# File 'lib/picsolve_docker_builder/composer/requirements/postgres.rb', line 168

def user_and_db_name
  "#{stage}-#{container.name}-#{name}"
end