Class: Fastlane::SecretsManagerStorage::Storage
- Inherits:
-
Match::Storage::Interface
- Object
- Match::Storage::Interface
- Fastlane::SecretsManagerStorage::Storage
- Defined in:
- lib/fastlane/plugin/secrets_manager_storage/storage.rb
Instance Attribute Summary collapse
-
#api_key ⇒ Object
readonly
Returns the value of attribute api_key.
-
#api_key_path ⇒ Object
readonly
Returns the value of attribute api_key_path.
-
#git_url ⇒ Object
readonly
Returns the value of attribute git_url.
-
#path_prefix ⇒ Object
readonly
Returns the value of attribute path_prefix.
-
#readonly ⇒ Object
readonly
Returns the value of attribute readonly.
-
#region ⇒ Object
readonly
Returns the value of attribute region.
-
#tags ⇒ Object
readonly
Returns the value of attribute tags.
-
#team_id ⇒ Object
readonly
Returns the value of attribute team_id.
-
#team_name ⇒ Object
readonly
Returns the value of attribute team_name.
-
#username ⇒ Object
readonly
Returns the value of attribute username.
Class Method Summary collapse
Instance Method Summary collapse
- #api_token ⇒ Object
- #create_or_update_secret(current_file, secret_name) ⇒ Object
- #currently_used_team_id ⇒ Object
- #delete_files(files_to_delete: [], custom_message: nil) ⇒ Object
- #delete_secret(secret_name) ⇒ Object
- #download ⇒ Object
- #generate_matchfile_content(template: nil) ⇒ Object
-
#human_readable_description ⇒ Object
Returns a short string describing + identifying the current storage backend.
-
#initialize(path_prefix: nil, tags: {}, region: nil, username: nil, readonly: nil, team_id: nil, team_name: nil, api_key_path: nil, api_key: nil) ⇒ Storage
constructor
A new instance of Storage.
- #list_files(file_name: "", file_ext: "") ⇒ Object
-
#prefixed_working_directory ⇒ Object
To make debugging easier, we have a custom exception here.
- #skip_docs ⇒ Object
- #upload_files(files_to_upload: [], custom_message: nil) ⇒ Object
Constructor Details
#initialize(path_prefix: nil, tags: {}, region: nil, username: nil, readonly: nil, team_id: nil, team_name: nil, api_key_path: nil, api_key: nil) ⇒ Storage
Returns a new instance of Storage.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 44 def initialize( path_prefix: nil, tags: {}, region: nil, username: nil, readonly: nil, team_id: nil, team_name: nil, api_key_path: nil, api_key: nil ) @path_prefix = path_prefix @tags = @region = region || ENV["AWS_REGION"] @username = username @readonly = readonly @team_id = team_id @team_name = team_name @api_key_path = api_key_path @api_key = api_key @client = Aws::SecretsManager::Client.new(region: region) UI.("Initializing match for AWS Secrets Manager at #{@path_prefix} in #{@region}") end |
Instance Attribute Details
#api_key ⇒ Object (readonly)
Returns the value of attribute api_key.
19 20 21 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 19 def api_key @api_key end |
#api_key_path ⇒ Object (readonly)
Returns the value of attribute api_key_path.
18 19 20 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 18 def api_key_path @api_key_path end |
#git_url ⇒ Object (readonly)
Returns the value of attribute git_url.
13 14 15 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 13 def git_url @git_url end |
#path_prefix ⇒ Object (readonly)
Returns the value of attribute path_prefix.
10 11 12 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 10 def path_prefix @path_prefix end |
#readonly ⇒ Object (readonly)
Returns the value of attribute readonly.
15 16 17 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 15 def readonly @readonly end |
#region ⇒ Object (readonly)
Returns the value of attribute region.
12 13 14 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 12 def region @region end |
#tags ⇒ Object (readonly)
Returns the value of attribute tags.
11 12 13 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 11 def @tags end |
#team_id ⇒ Object (readonly)
Returns the value of attribute team_id.
16 17 18 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 16 def team_id @team_id end |
#team_name ⇒ Object (readonly)
Returns the value of attribute team_name.
17 18 19 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 17 def team_name @team_name end |
#username ⇒ Object (readonly)
Returns the value of attribute username.
14 15 16 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 14 def username @username end |
Class Method Details
.configure(params) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 21 def self.configure(params) if params[:git_url].to_s.length > 0 UI.important("Looks like you still define a `git_url` somewhere, even though") UI.important("you use AWS Secrets Manager. You can remove the `git_url`") UI.important("from your Matchfile and Fastfile") UI.("The above is just a warning, fastlane will continue as usual now...") end return( self.new( path_prefix: params[:secrets_manager_path_prefix], tags: params[:secrets_manager_tags], region: params[:secrets_manager_region], username: params[:username], readonly: params[:readonly], team_id: params[:team_id], team_name: params[:team_name], api_key_path: params[:api_key_path], api_key: params[:api_key], ) ) end |
Instance Method Details
#api_token ⇒ Object
136 137 138 139 140 141 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 136 def api_token api_token = Spaceship::ConnectAPI::Token.from(hash: self.api_key, filepath: self.api_key_path) api_token ||= Spaceship::ConnectAPI.token return api_token end |
#create_or_update_secret(current_file, secret_name) ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 189 def create_or_update_secret(current_file, secret_name) full_secret_path = generate_secret_path(secret_name) = (current_file) begin @client.describe_secret(secret_id: full_secret_path) UI.verbose("Secret '#{secret_name}' already exists, updating...") @client.put_secret_value( secret_id: full_secret_path, secret_binary: IO.binread(current_file), ) unless .empty? @client.tag_resource( secret_id: full_secret_path, tags: convert_hash_to_array_of_key_values(), ) end rescue Aws::SecretsManager::Errors::ResourceNotFoundException UI.verbose("Secret '#{secret_name}' doesn't exist, creating...") @client.create_secret( name: full_secret_path, secret_binary: File.open(current_file, "rb").read, tags: convert_hash_to_array_of_key_values(.merge()), ) end end |
#currently_used_team_id ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 118 def currently_used_team_id if self.readonly # In readonly mode, we still want to see if the user provided a team_id # see `prefixed_working_directory` comments for more details return self.team_id else if self.team_id.to_s.empty? UI.user_error!( "The `team_id` option is required. fastlane cannot automatically determine portal team id via the App Store Connect API (yet)", ) end spaceship = ::Match::SpaceshipEnsure.new(self.username, self.team_id, self.team_name, api_token) return spaceship.team_id end end |
#delete_files(files_to_delete: [], custom_message: nil) ⇒ Object
168 169 170 171 172 173 174 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 168 def delete_files(files_to_delete: [], custom_message: nil) files_to_delete.each do |current_file| secret_name = current_file.delete_prefix(self.working_directory + "/") delete_secret(secret_name) end end |
#delete_secret(secret_name) ⇒ Object
215 216 217 218 219 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 215 def delete_secret(secret_name) @client.delete_secret({ secret_id: secret_name, recovery_window_in_days: 7 }) rescue Aws::SecretsManager::Errors::ResourceNotFoundException UI.verbose("Secret '#{secret_name}' doesn't exist, skipping...") end |
#download ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 87 def download return if @working_directory self.working_directory = Dir.mktmpdir next_token = nil secret_names = [] with_aws_authentication_error_handling do loop do resp = @client.list_secrets( { next_token: next_token, filters: [{ key: "name", values: [@path_prefix] }] }, ) resp.secret_list.each { |secret| secret_names << secret.name } next_token = resp.next_token break if next_token.nil? end secret_names.each do |name| secret = @client.get_secret_value({ secret_id: name }) filename = File.join(self.working_directory, name.delete_prefix(self.path_prefix)) FileUtils.mkdir_p(File.dirname(filename)) IO.binwrite(filename, secret.secret_binary) end end UI.verbose( "Successfully downloaded all Secrets from AWS Secrets Manager to #{self.working_directory}", ) end |
#generate_matchfile_content(template: nil) ⇒ Object
184 185 186 187 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 184 def generate_matchfile_content(template: nil) # Will implement once I figure out how to have a plugin with `match` commands raise "Not Implemented" end |
#human_readable_description ⇒ Object
Returns a short string describing + identifying the current storage backend. This will be printed when nuking a storage
145 146 147 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 145 def human_readable_description "AWS Secrets Manager Storage [#{self.path_prefix}]" end |
#list_files(file_name: "", file_ext: "") ⇒ Object
180 181 182 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 180 def list_files(file_name: "", file_ext: "") Dir[File.join(working_directory, self.team_id, "**", file_name, "*.#{file_ext}")] end |
#prefixed_working_directory ⇒ Object
To make debugging easier, we have a custom exception here
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 70 def prefixed_working_directory # We fall back to "*", which means certificates and profiles # from all teams that use this bucket would be installed. This is not ideal, but # unless the user provides a `team_id`, we can't know which one to use # This only happens if `readonly` is activated, and no `team_id` was provided @_folder_prefix ||= currently_used_team_id if @_folder_prefix.nil? # We use a `@_folder_prefix` variable, to keep state between multiple calls of this # method, as the value won't change. This way the warning is only printed once UI.important( "Looks like you run `match` in `readonly` mode, and didn't provide a `team_id`. This will still work, however it is recommended to provide a `team_id` in your Appfile or Matchfile", ) @_folder_prefix = "*" end return File.join(working_directory, @_folder_prefix) end |
#skip_docs ⇒ Object
176 177 178 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 176 def skip_docs true end |
#upload_files(files_to_upload: [], custom_message: nil) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/fastlane/plugin/secrets_manager_storage/storage.rb', line 149 def upload_files(files_to_upload: [], custom_message: nil) # `files_to_upload` is an array of files that need to be uploaded to AWS Secrets Manager # Those doesn't mean they're new, it might just be they're changed # Either way, we'll upload them using the same technique files_to_upload.each do |current_file| # Go from # "/var/folders/px/bz2kts9n69g8crgv4jpjh6b40000gn/T/d20181026-96528-1av4gge/profiles/development/Development_me.mobileprovision" # to # "profiles/development/Development_me.mobileprovision" # # We also remove the trailing `/` secret_name = current_file.delete_prefix(self.working_directory) UI.verbose("Uploading '#{secret_name}' to AWS Secrets Manager...") create_or_update_secret(current_file, secret_name) end end |