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) ⇒ 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
# 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)
  @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, signature_version: 'v4'}.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
  end)
end

Instance Attribute Details

#bucketObject (readonly)

Returns the value of attribute bucket.



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

def bucket
  @bucket
end

#kms_key_idObject (readonly)

Returns the value of attribute kms_key_id.



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

def kms_key_id
  @kms_key_id
end

#kms_key_id_accountObject (readonly)

Returns the value of attribute kms_key_id_account.



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

def 
  @kms_key_id_account
end

#kms_key_id_certificate_keyObject (readonly)

Returns the value of attribute kms_key_id_certificate_key.



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

def kms_key_id_certificate_key
  @kms_key_id_certificate_key
end

#prefixObject (readonly)

Returns the value of attribute prefix.



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

def prefix
  @prefix
end

#regionObject (readonly)

Returns the value of attribute region.



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

def region
  @region
end

#use_kmsObject (readonly)

Returns the value of attribute use_kms.



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

def use_kms
  @use_kms
end

Instance Method Details

#account_key_exist?Boolean

Returns:

  • (Boolean)


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

def 
  begin
    
  rescue NotExist
    return false
  else
    return true
  end
end

#get_account_keyObject



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

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



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

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



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

def get_current_certificate_version(common_name)
  certificate_current(common_name)
end

#list_certificate_versions(common_name) ⇒ Object



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

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



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

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:



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

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



67
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
# File 'lib/acmesmith/storages/s3.rb', line 67

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", true

  if generate_pkcs12?(cert)
    put.call pkcs12_key(cert.common_name, cert.version), "#{cert.pkcs12(@pkcs12_passphrase).to_der}\n", true, '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