Class: CLI

Inherits:
Object
  • Object
show all
Includes:
Commander::Methods
Defined in:
lib/cli.rb

Overview

rubocop:disable Metrics/ClassLength

Instance Method Summary collapse

Instance Method Details

#runObject

rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metric/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/BlockLength



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
103
104
105
106
107
108
109
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/cli.rb', line 15

def run
  program :name, 'cry - cryptopus cli'
  program :version, '1.1.0'
  program :description, 'CLI tool to manage Openshift Secrets via Cryptopus'
  program :help, 'Source Code', 'https://www.github.com/puzzle/ccli'
  program :help, 'Usage', 'cry [flags]'

  command :login do |c|
    c.syntax = 'cry login <credentials>'
    c.description = 'Logs in to the ccli'

    c.action do |args|
      token, url = (args)
      execute_action do
        session_adapter.update_session({ encoded_token: token, url: url })
        renew_auth_token

        # Test authentification by calling teams endpoint
        Team.all

        log_success 'Successfully logged in'
      end
    end
  end

  command :logout do |c|
    c.syntax = 'cry logout'
    c.description = 'Logs out of the ccli'

    c.action do
      execute_action do
        session_adapter.clear_session
        log_success 'Successfully logged out'
      end
    end
  end

  command :encryptable do |c|
    c.syntax = 'cry encryptable <id> [options]'
    c.description = 'Fetches an encryptable by the given id'
    c.option '--username', String, 'Only show the username of the user'
    c.option '--password', String, 'Only show the password of the user'

    c.action do |args, options|
      exit_with_error(:usage_error, 'id missing') if args.empty?
      execute_action do
        logger.info 'Fetching encryptable...'
        encryptable = Encryptable.find(args.first)
        out = encryptable.username if options.username
        out = encryptable.password if options.password
        puts out || encryptable.to_yaml
      end
    end
  end

  command :folder do |c|
    c.syntax = 'cry folder <id>'
    c.description = 'Selects the Cryptopus folder by id'

    c.action do |args|
      id = args.first
      exit_with_error(:usage_error, 'id missing') unless id
      exit_with_error(:usage_error, 'id invalid') unless id.match?(/(^\d{1,10}$)/)

      execute_action do
        session_adapter.update_session({ folder: id })

        log_success "Selected Folder with id: #{id}"
      end
    end
  end

  command :'ose-secret-pull' do |c|
    c.syntax = 'cry ose-secret-pull <secret-name>'
    c.summary = 'Pulls secret from Openshift to Cryptopus'
    c.description = "Pulls the Secret from Openshift and pushes them to Cryptopus.\n" \
                    'If a Cryptopus Account in the selected folder using the name ' \
                    "of the given secret is already present, it will be updated accordingly.\n" \
                    'If no name is given, it will pull all secrets inside the selected project.'

    c.action do |args|
      if args.length > 1
        exit_with_error(:usage_error,
                        'Only a single or no arguments are allowed')
      end

      execute_action({ secret_name: args.first }) do
        if args.empty?
          logger.info 'Fetching secrets...'
          OSESecret.all.each do |secret|
            logger.info "Saving secret #{secret.name}..."
            cryptopus_adapter.save_secret(secret)
            log_success "Saved secret #{secret.name} in Cryptopus"
          end
        elsif args.length == 1
          logger.info "Saving secret #{args.first}..."
          cryptopus_adapter.save_secret(OSESecret.find_by_name(args.first))
          log_success "Saved secret #{args.first} in Cryptopus"
        end
      end
    end
  end

  command :'ose-secret-push' do |c|
    c.syntax = 'cry ose-secret-push <secret-name>'
    c.summary = 'Pushes secret from Cryptopus to Openshift'
    c.description = 'Pushes the Secret to Openshift by retrieving it from Cryptopus first. ' \
                    'If a Secret in the selected Openshift project using the name ' \
                    'of the given name is already present, it will be updated accordingly.'

    c.action do |args|
      secret_name = args.first
      exit_with_error(:usage_error, 'Only one secret can be pushed') if args.length > 1
      execute_action({ secret_name: secret_name }) do
        secret_encryptables = if secret_name.nil?
                            logger.info 'Fetching all encryptables in folder...'
                            session_adapter.selected_folder.encryptables
                          else
                            logger.info "Fetching encryptable #{secret_name}..."
                            [cryptopus_adapter.find_encryptable_by_name(secret_name)]
                          end
        secret_encryptables.each do |encryptable|
          logger.info "Fetching secret #{encryptable.name}..."
          secret_encryptable = Encryptable.find(encryptable.id)
          logger.info "Inserting secret #{encryptable.name}..."
          ose_adapter.insert_secret(secret_encryptable.to_osesecret)
          log_success "Secret #{secret_encryptable.name} was successfully applied"
        end
      end
    end
  end

  command :'k8s-secret-pull' do |c|
    c.syntax = 'cry k8s-secret-pull <secret-name>'
    c.summary = 'Pulls secret from Kubectl to Cryptopus'
    c.description = "Pulls the Secret from Kubectl and pushes them to Cryptopus.\n" \
                    'If a Cryptopus Encryptable in the selected folder using the name ' \
                    "of the given secret is already present, it will be updated accordingly.\n" \
                    'If no name is given, it will pull all secrets inside the selected project.'

    c.action do |args|
      if args.length > 1
        TTY::Exit.exit_with(:usage_error,
                            'Only a single or no arguments are allowed')
      end

      execute_action({ secret_name: args.first }) do
        if args.empty?
          logger.info 'Fetching secrets...'
          K8SSecret.all.each do |secret|
            logger.info "Saving secret #{secret.name}..."
            cryptopus_adapter.save_secret(secret)
            log_success "Saved secret #{secret.name} in Cryptopus"
          end
        elsif args.length == 1
          logger.info "Saving secret #{args.first}..."
          cryptopus_adapter.save_secret(K8SSecret.find_by_name(args.first))
          log_success "Saved secret #{args.first} in Cryptopus"
        end
      end
    end
  end

  command :'k8s-secret-push' do |c|
    c.syntax = 'cry k8s-secret-push <secret-name>'
    c.summary = 'Pushes secret from Cryptopus to Kubectl'
    c.description = 'Pushes the Secret to Kubectl by retrieving it from Cryptopus first. ' \
                    'If a Secret in the selected Kubectl project using the name ' \
                    'of the given name is already present, it will be updated accordingly.'

    c.action do |args|
      secret_name = args.first
      exit_with_error(:usage_error, 'Only one secret can be pushed') if args.length > 1
      execute_action({ secret_name: secret_name }) do
        secret_encryptables = if secret_name.nil?
                            logger.info 'Fetching all encryptables in folder...'
                            session_adapter.selected_folder.encryptables
                          else
                            logger.info "Fetching encryptable #{secret_name}..."
                            [cryptopus_adapter.find_encryptable_by_name(secret_name)]
                          end
        secret_encryptables.each do |encryptable|
          secret_encryptable = Encryptable.find(encryptable.id)
          logger.info "Inserting secret #{encryptable.name}..."
          k8s_adapter.insert_secret(secret_encryptable.to_osesecret)
          log_success "Secret #{secret_encryptable.name} was successfully applied"
        end
      end
    end
  end

  command :teams do |c|
    c.syntax = 'cry teams'
    c.description = 'Lists all available teams'

    c.action do
      execute_action do
        logger.info 'Fetching teams...'
        teams = Team.all
        output = teams.map(&:render_list).join("\n")
        puts output
      end
    end
  end

  command :use do |c|
    c.syntax = 'cry use <team/folder>'
    c.description = 'Select the current folder'

    c.action do |args|
      team_name, folder_name = extract_use_args(args)
      execute_action({ team_name: team_name, folder_name: folder_name }) do
        logger.info "Looking for team #{team_name}..."
        selected_team = Team.find_by_name(team_name)
        raise TeamNotFoundError unless selected_team

        logger.info "Looking for folder #{folder_name}..."
        selected_folder = selected_team.folder_by_name(folder_name)
        raise FolderNotFoundError unless selected_folder

        session_adapter.update_session({ folder: selected_folder.id })
        log_success "Selected folder #{folder_name.downcase} in team #{team_name.downcase}"
      end
    end
  end

  run!
end