Class: Acmesmith::Storages::S3

Inherits:
Base
  • Object
show all
Defined in:
lib/acmesmith/storages/s3.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(aws_access_key: nil, bucket:, prefix: nil, region:, use_kms: true, kms_key_id: nil, kms_key_id_account: nil, kms_key_id_certificate_key: nil, pkcs12_passphrase: nil, pkcs12_common_names: nil, endpoint: nil) ⇒ S3

Returns a new instance of S3.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/acmesmith/storages/s3.rb', line 10

def initialize(aws_access_key: nil, bucket:, prefix: nil, region:, use_kms: true, kms_key_id: nil, kms_key_id_account: nil, kms_key_id_certificate_key: nil, pkcs12_passphrase: nil, pkcs12_common_names: nil, endpoint: nil)
  @region = region
  @bucket = bucket
  @prefix = prefix
  if @prefix && !@prefix.end_with?('/')
    @prefix += '/'
  end

  @pkcs12_passphrase = pkcs12_passphrase
  @pkcs12_common_names = pkcs12_common_names

  @use_kms = use_kms
  @kms_key_id = kms_key_id
  @kms_key_id_account = 
  @kms_key_id_certificate_key = kms_key_id_certificate_key

  @s3 = Aws::S3::Client.new({region: region}.tap do |opt| 
    opt[:credentials] = Aws::Credentials.new(aws_access_key['access_key_id'], aws_access_key['secret_access_key'], aws_access_key['session_token']) if aws_access_key
    opt[:endpoint] = endpoint if endpoint
  end)
end

Instance Attribute Details

#bucketObject (readonly)

Returns the value of attribute bucket.



32
33
34
# File 'lib/acmesmith/storages/s3.rb', line 32

def bucket
  @bucket
end

#kms_key_idObject (readonly)

Returns the value of attribute kms_key_id.



32
33
34
# File 'lib/acmesmith/storages/s3.rb', line 32

def kms_key_id
  @kms_key_id
end

#kms_key_id_accountObject (readonly)

Returns the value of attribute kms_key_id_account.



32
33
34
# File 'lib/acmesmith/storages/s3.rb', line 32

def 
  @kms_key_id_account
end

#kms_key_id_certificate_keyObject (readonly)

Returns the value of attribute kms_key_id_certificate_key.



32
33
34
# File 'lib/acmesmith/storages/s3.rb', line 32

def kms_key_id_certificate_key
  @kms_key_id_certificate_key
end

#prefixObject (readonly)

Returns the value of attribute prefix.



32
33
34
# File 'lib/acmesmith/storages/s3.rb', line 32

def prefix
  @prefix
end

#regionObject (readonly)

Returns the value of attribute region.



32
33
34
# File 'lib/acmesmith/storages/s3.rb', line 32

def region
  @region
end

#use_kmsObject (readonly)

Returns the value of attribute use_kms.



32
33
34
# File 'lib/acmesmith/storages/s3.rb', line 32

def use_kms
  @use_kms
end

Instance Method Details

#account_key_exist?Boolean

Returns:

  • (Boolean)


41
42
43
44
45
46
47
48
49
# File 'lib/acmesmith/storages/s3.rb', line 41

def 
  begin
    
  rescue NotExist
    return false
  else
    return true
  end
end

#get_account_keyObject



34
35
36
37
38
39
# File 'lib/acmesmith/storages/s3.rb', line 34

def 
  obj = @s3.get_object(bucket: bucket, key: )
  AccountKey.new obj.body.read
rescue Aws::S3::Errors::NoSuchKey
  raise NotExist.new("Account key doesn't exist")
end

#get_certificate(common_name, version: 'current') ⇒ Object



105
106
107
108
109
110
111
112
113
114
# File 'lib/acmesmith/storages/s3.rb', line 105

def get_certificate(common_name, version: 'current')
  version = certificate_current(common_name) if version == 'current'

  certificate = @s3.get_object(bucket: bucket, key: certificate_key(common_name, version)).body.read
  chain = @s3.get_object(bucket: bucket, key: chain_key(common_name, version)).body.read
  private_key = @s3.get_object(bucket: bucket, key: private_key_key(common_name, version)).body.read
  Certificate.new(certificate, chain, private_key)
rescue Aws::S3::Errors::NoSuchKey
  raise NotExist.new("Certificate for #{common_name.inspect} of #{version} version doesn't exist")
end

#get_current_certificate_version(common_name) ⇒ Object



140
141
142
# File 'lib/acmesmith/storages/s3.rb', line 140

def get_current_certificate_version(common_name)
  certificate_current(common_name)
end

#list_certificate_versions(common_name) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/acmesmith/storages/s3.rb', line 128

def list_certificate_versions(common_name)
  cert_ver_prefix = "#{prefix}certs/#{common_name}/"
  @s3.list_objects(
    bucket: bucket,
    delimiter: '/',
    prefix: cert_ver_prefix,
  ).each.flat_map do |page|
    regexp = /\A#{Regexp.escape(cert_ver_prefix)}/
    page.common_prefixes.map { |_| _.prefix.sub(regexp, '').sub(/\/.+\z/, '').sub(/\/\z/, '') }.uniq
  end.reject { |_| _ == 'current' }
end

#list_certificatesObject



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/acmesmith/storages/s3.rb', line 116

def list_certificates
  certs_prefix = "#{prefix}certs/"
  @s3.list_objects(
    bucket: bucket,
    delimiter: '/',
    prefix: certs_prefix,
  ).each.flat_map do |page|
    regexp = /\A#{Regexp.escape(certs_prefix)}/
    page.common_prefixes.map { |_| _.prefix.sub(regexp, '').sub(/\/.+\z/, '').sub(/\/\z/, '') }.uniq
  end
end

#put_account_key(key, passphrase = nil) ⇒ Object

Raises:



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/acmesmith/storages/s3.rb', line 51

def (key, passphrase = nil)
  raise AlreadyExist if 
  params = {
    bucket: bucket,
    key: ,
    body: key.export(passphrase),
    content_type: 'application/x-pem-file',
  }
  if use_kms
    params[:server_side_encryption] = 'aws:kms'
    key_id =  || kms_key_id
    params[:ssekms_key_id] = key_id if key_id
  end

  @s3.put_object(params)
end

#put_certificate(cert, passphrase = nil, update_current: true) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/acmesmith/storages/s3.rb', line 68

def put_certificate(cert, passphrase = nil, update_current: true)
  h = cert.export(passphrase)

  put = -> (key, body, kms, content_type = 'application/x-pem-file') do
    params = {
      bucket: bucket,
      key: key,
      body: body,
      content_type: content_type,
    }
    if kms
      params[:server_side_encryption] = 'aws:kms'
      key_id = kms_key_id_certificate_key || kms_key_id
      params[:ssekms_key_id] = key_id if key_id
    end
    @s3.put_object(params)
  end

  put.call certificate_key(cert.common_name, cert.version), "#{h[:certificate].rstrip}\n", false
  put.call chain_key(cert.common_name, cert.version), "#{h[:chain].rstrip}\n", false
  put.call fullchain_key(cert.common_name, cert.version), "#{h[:fullchain].rstrip}\n", false
  put.call private_key_key(cert.common_name, cert.version), "#{h[:private_key].rstrip}\n", use_kms

  if generate_pkcs12?(cert)
    put.call pkcs12_key(cert.common_name, cert.version), "#{cert.pkcs12(@pkcs12_passphrase).to_der}\n", use_kms, 'application/x-pkcs12'
  end

  if update_current
    @s3.put_object(
      bucket: bucket,
      key: certificate_current_key(cert.common_name),
      content_type: 'text/plain',
      body: cert.version,
    )
  end
end