launchdarkly_api_helper 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48a1fa66d19b0af509741df158d57e04cbcd379e1cc0f921bd8755bfd2b8bfd6
4
- data.tar.gz: 10fe7dcfb0fe90a797f874b56c2f99deecc0e69028e7d58fbd69c84f5b1e41b4
3
+ metadata.gz: f063313104693353f6dd3e18a6ecd69c5142b62eb3f072b08f96b8b51e9175e0
4
+ data.tar.gz: 1f83a4dc6665e8864605decdb1d265178232785d44cca584488533fe21bd4ce6
5
5
  SHA512:
6
- metadata.gz: 1349639032b66a4091b84d0188d0b5935dd5758aa5ab4eede29c57312972d57b1b648988dc135ceba8b82fd4c8425d451235436f7723b85da54945dcb8dc0ff4
7
- data.tar.gz: b1de7f7890f2f68d19b31936b789670aefab91b259676f5c2aa26d6aa093156fa0f9a13950640e95451d9f9153aa7180f7930818d9099a37c0317ab9c47eb327
6
+ metadata.gz: e9fadbf1588e1d429f3cf3d1bf9bcccf6b06bda032baa707970a65714321a970e8e5d8f952baa99be5115e4986564c45bbcfcc07034f829637522569e5fd9f15
7
+ data.tar.gz: b947d46ef24947acba122a57ce2e2c582af6342806e357de59864523ba4b8e78e9d81185dc6f51d4b183621d94b97d206840d020dc5226731db866ef77a25c7a
data/.rubocop.yml CHANGED
@@ -9,12 +9,21 @@ Style/StringLiteralsInInterpolation:
9
9
  Enabled: true
10
10
  EnforcedStyle: double_quotes
11
11
 
12
+ Style/OptionalBooleanParameter:
13
+ Enabled: false
14
+
12
15
  Layout/LineLength:
13
16
  Max: 120
14
17
 
15
18
  Metrics/MethodLength:
16
19
  Max: 100
17
20
 
21
+ Metrics/MethodName:
22
+ Max: 100
23
+
24
+ Metrics/ClassLength:
25
+ Max: 150
26
+
18
27
  Metrics/AbcSize:
19
28
  Enabled: false
20
29
 
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # LaunchdarklyApiHelper
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/launchdarkly_api_helper`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [LaunchDarklyApiHelper](https://rubygems.org/gems/launchdarkly_api_helper) provides you a way to access your [Launch Darkly](https://apidocs.launchdarkly.com/) account using [API token](https://app.launchdarkly.com/settings/authorization/tokens/new) to view, edit or delete them accordingly.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ![alt text](https://docs.launchdarkly.com/static/de107a76f0cd388da14d5bd650ec1f5c/b8471/settings-access-tokens-obscured-callout.png)
6
+
7
+ [Launch Darkly API Documentation](https://apidocs.launchdarkly.com/)
6
8
 
7
9
  ## Installation
8
10
 
@@ -16,7 +18,193 @@ If bundler is not being used to manage dependencies, install the gem by executin
16
18
 
17
19
  ## Usage
18
20
 
19
- TODO: Write usage instructions here
21
+ add `require 'launchdarkly_api_helper'` line at the beginning of your Ruby file
22
+
23
+ add `include LaunchdarklyApiHelper` line to access LaunchdarklyApiHelper module in gem _launchdarkly_api_helper_
24
+
25
+ To perform any operations such as add, remove, replace, move, copy, test you should have a working knowledge of [JSON Patch](https://datatracker.ietf.org/doc/html/rfc6902)
26
+
27
+ ```ruby
28
+ parameters:
29
+ access_token (*required): this token will be used to send all requests to LaunchDarkly (string)
30
+ log_file: all logs will be writeen to file 'launchdarkly.log' by default if no file name specified
31
+
32
+ # set your LD API token and log file to capture logs
33
+ def ld_access_token(access_token, log_file = 'launchdarkly.log')
34
+ # code ...
35
+ end
36
+ ```
37
+
38
+ [Get feature flag](https://apidocs.launchdarkly.com/tag/Feature-flags#operation/getFeatureFlag)
39
+
40
+ ```ruby
41
+ GET REQUEST
42
+ https://app.launchdarkly.com/api/v2/flags/default/developer_flag_for_regression
43
+
44
+ parameters:
45
+ env (*required): name of the environment for which you want to get the details (string)
46
+ flag (*required): name of the feature flag for which you want to get the details (string)
47
+
48
+ Here, 'developer_flag_for_regression' is the feature flag name and default is our Project name - eg. AmitSinghBisht
49
+ By default, this returns the configurations for all environments
50
+ You can filter environments with the env query parameter. For example, setting env=staging restricts the returned configurations to just the staging environment
51
+ https://app.launchdarkly.com/api/v2/flags/default/developer_flag_for_regression?env=staging
52
+
53
+ # this method will give you entire details about a flag for that particular environment
54
+ def ld_fetch_flag_details(env, flag)
55
+ # code ...
56
+ end
57
+
58
+ @return value (response of feature flag details):
59
+ response = "https://app.launchdarkly.com/api/v2/flags/default/#{flag}?env=#{env}" (string)
60
+ ```
61
+
62
+ ```ruby
63
+ Get toggle status feature flag
64
+
65
+ parameters:
66
+ env (*required): name of the environment for which you want to get the details (string)
67
+ flag (*required): name of the feature flag for which you want to get the details (string)
68
+
69
+ response = https://app.launchdarkly.com/api/v2/flags/default/developer_flag_for_regression?env=staging
70
+ grab the value of the ['environments'][env]['on'] obtained from the above response
71
+
72
+ # this method will return the status of the flag, whether it is on or off viz set to true or false
73
+ def ld_fetch_flag_toggle_status(env, flag)
74
+ # code ...
75
+ end
76
+
77
+ @return value (response of feature flag toggle status):
78
+ response = "https://app.launchdarkly.com/api/v2/flags/default/#{flag}?env=#{env}"
79
+ response['environments'][env]['on'] (boolean)
80
+ ```
81
+
82
+ ```ruby
83
+ Create a feature flag
84
+ https://apidocs.launchdarkly.com/tag/Feature-flags/#operation/postFeatureFlag
85
+
86
+ POST REQUEST
87
+ https://app.launchdarkly.com/api/v2/flags/default
88
+
89
+ Here, default is our Project name - eg. AmitSinghBisht
90
+
91
+ parameters:
92
+ key (*required): A unique key used to reference the feature flag in your code (string)
93
+ name (*required): A human-friendly name for the feature flag (string)
94
+ description: Description of the feature flag. Defaults to an empty string (string)
95
+ tags: Tags for the feature flag. Defaults to an empty array (Array of strings)
96
+ variations: An array of possible variations for the flag. The variation values must be unique. If omitted, two boolean variations of true and false will be used (Array of objects)
97
+
98
+ defaults
99
+ * onVariation (*required): The index, from the array of variations for this flag, of the variation to serve by default when targeting is on (integer)
100
+ * offVariation (*required): The index, from the array of variations for this flag, of the variation to serve by default when targeting is off (integer)
101
+
102
+ {
103
+ "key": "developer_flag_for_regression",
104
+ "name": "developer_flag_for_regression",
105
+ "description": "developer_flag_for_regression is created via regression api on 18_10_2022",
106
+ "tags": [
107
+ "created_via_regression_api_on_18_10_2022"
108
+ ],
109
+ "variations": [
110
+ {
111
+ "age": 10
112
+ },
113
+ {
114
+ "age": 20
115
+ }
116
+ ],
117
+ "defaults": {
118
+ "onVariation": 1,
119
+ "offVariation": 0
120
+ }
121
+ }
122
+
123
+ Above code will create a key 'developer_flag_for_regression' with name as 'developer_flag_for_regression' and description as 'developer_flag_for_regression is created via regression api on 18_10_2022'
124
+
125
+ Variations are provided while creating key, by default variation is a boolean value (true and false). once flag with a specific variation is created, its type cannot be modified later, hence choose your variation type smartly (Boolean, String, Number, JSON) In above example we are creating a flag with JSON type and its two values are 'age': 10 and 'age': 20
126
+
127
+ Also, variation has by default two values, and you must also define two variations while creating your own custom feature flag
128
+
129
+ Default will specify which variation to serve when flag is on or off. In above example when flag is turned on, '1' variation is served [Note: 0 and 1 are index position], so variations at first index ie variations[1] will be served when flag is turned on ie 'age': 20
130
+
131
+ # this method will create a new feature flag, NOTE: feature falg are created at global level and environment resides inside feature flag
132
+ def ld_create_flag(key, name = key, description = key, tags = ['created_via_regression_api'])
133
+ # code ...
134
+ end
135
+ ```
136
+
137
+ ```ruby
138
+ Update feature flag
139
+ https://apidocs.launchdarkly.com/tag/Feature-flags#operation/patchFeatureFlag
140
+
141
+ PATCH REQUEST
142
+ https://app.launchdarkly.com/api/v2/flags/default/developer_flag_for_regression
143
+
144
+ parameters:
145
+ env (*required): name of the environment for which you want to get the details (string)
146
+ flag (*required): name of the feature flag for which you want to get the details (string)
147
+ flag_value: status of the feature flag that you want to set either on (true) or off (false) (boolean)
148
+
149
+ Here, 'developer_flag_for_regression' is the flag key and default is our Project name - eg. AmitSinghBisht
150
+ You can update any parameter of feature flag using this method
151
+
152
+ # this method will be used to toggle status of feature flag either on / off for a particular environment
153
+ def ld_toggle_specific_environment(env, flag, flag_value = true)
154
+ # code ...
155
+ end
156
+
157
+ @return value (response of feature flag toggle status):
158
+ response = "https://app.launchdarkly.com/api/v2/flags/default/#{flag}?env=#{env}"
159
+ response['environments'][env]['on'] (boolean)
160
+ ```
161
+
162
+ ```ruby
163
+ Get status of feature flag
164
+ https://apidocs.launchdarkly.com/tag/Feature-flags#operation/patchFeatureFlag
165
+
166
+ def ld_toggle_variation_served(env, flag)
167
+ # code ...
168
+ end
169
+
170
+ @returns: [fetch_flag_toggle_status_response, feature_flag_variation_index_response, feature_flag_variation_value_response, feature_flag_variation_name_response]
171
+ @return parameter:
172
+ response = "https://app.launchdarkly.com/api/v2/flags/default/#{flag}?env=#{env}"
173
+ fetch_flag_toggle_status_response: response['environments'][env]['on'] (boolean)
174
+ feature_flag_variation_index_response: response (integer)
175
+ feature_flag_variation_value_response: response['variations'][feature_flag_variation_index_response]['value'] (object)
176
+ feature_flag_variation_name_response: response['variations'][feature_flag_variation_index_response]['name'] (string)
177
+ ```
178
+
179
+ ```ruby
180
+ def ld_rules_clauses_index(env, flag, clause_name)
181
+ # code ...
182
+ end
183
+ ```
184
+
185
+ ```ruby
186
+ def ld_get_values_from_clauses(env, flag, clause_name)
187
+ # code ...
188
+ end
189
+ ```
190
+
191
+ ```ruby
192
+ def ld_add_values_to_clause(env, flag, clause_name, clause_value)
193
+ # code ...
194
+ end
195
+ ```
196
+
197
+ ```ruby
198
+ def ld__remove_values_from_clause(env, flag, clause_name, clause_value)
199
+ # code ...
200
+ end
201
+ ```
202
+
203
+ ```ruby
204
+ def ld_delete_flag(flag)
205
+ # code ...
206
+ end
207
+ ```
20
208
 
21
209
  ## Development
22
210
 
@@ -21,4 +21,4 @@ REQUEST_CLASSES = {
21
21
  'code' => 204,
22
22
  'message' => 'No Content'
23
23
  }
24
- }.freeze
24
+ }.freeze
@@ -59,18 +59,18 @@ class LaunchdarklyApiHelperClass
59
59
  ld_request(:post, request_url, request_body)
60
60
  end
61
61
 
62
- def toggle_flag_for_specific_environment(env, flag, flag_value)
62
+ def toggle_specific_environment(env, flag, flag_value)
63
63
  request_url = "#{LAUNCH_DARKLY_FLAGS}/#{flag}"
64
64
  request_body = { 'op' => 'replace', 'path' => "/environments/#{env}/on", 'value' => flag_value }
65
65
  response_body = ld_request(:patch, request_url, [request_body])
66
66
  response_body['environments'][env]['on']
67
67
  end
68
68
 
69
- def feature_flag_variation_index(fetch_flag_toggle_status_response, fetch_flag_details_response)
70
- variations = fetch_flag_details_response['variations']
69
+ def feature_flag_variation_index(status_response, details_response)
70
+ variations = details_response['variations']
71
71
  value_at_index = -1
72
72
  variations.length.times do |index|
73
- next unless variations[index]['value'].eql? fetch_flag_toggle_status_response
73
+ next unless variations[index]['value'].eql? status_response
74
74
 
75
75
  value_at_index = index
76
76
  break
@@ -78,60 +78,81 @@ class LaunchdarklyApiHelperClass
78
78
  value_at_index
79
79
  end
80
80
 
81
- def feature_flag_variation_value(fetch_flag_details_response, feature_flag_variation_index_response)
82
- fetch_flag_details_response['variations'][feature_flag_variation_index_response]['value']
81
+ def feature_flag_variation_value(details_response, index_response)
82
+ details_response['variations'][index_response]['value']
83
83
  end
84
84
 
85
- def feature_flag_variation_name(fetch_flag_details_response, feature_flag_variation_index_response)
86
- fetch_flag_details_response['variations'][feature_flag_variation_index_response]['name']
85
+ def feature_flag_variation_name(details_response, index_response)
86
+ details_response['variations'][index_response]['name']
87
87
  end
88
88
 
89
- def toggle_variation_served_status(env, flag)
90
- fetch_flag_details_response = fetch_flag_details(env, flag)
91
- fetch_flag_toggle_status_response = fetch_flag_toggle_status(env, flag)
92
- feature_flag_variation_index_response = feature_flag_variation_index(fetch_flag_toggle_status_response, fetch_flag_details_response) # ['environments'][env]['fallthrough']['variation']
93
- feature_flag_variation_value_response = feature_flag_variation_value(fetch_flag_details_response, feature_flag_variation_index_response) # ['variations'][feature_flag_variation_index_response]['value']
94
- feature_flag_variation_name_response = feature_flag_variation_name(fetch_flag_details_response, feature_flag_variation_index_response)
95
- [fetch_flag_toggle_status_response, feature_flag_variation_index_response, feature_flag_variation_value_response, feature_flag_variation_name_response]
89
+ def ld_toggle_variation_served(env, flag)
90
+ details_response = fetch_flag_details(env, flag)
91
+ toggle_status_response = fetch_flag_toggle_status(env, flag)
92
+ variation_index_response = feature_flag_variation_index(toggle_status_response, details_response) # ['environments'][env]['fallthrough']['variation']
93
+ variation_value_response = feature_flag_variation_value(details_response, variation_index_response) # ['variations'][variation_index_response]['value']
94
+ variation_name_response = feature_flag_variation_name(details_response, variation_index_response)
95
+ [toggle_status_response, variation_index_response, variation_value_response, variation_name_response]
96
96
  end
97
97
 
98
- def search_value_in_hash(feature_flag_hash, attribute)
98
+ def search_rule_index_clause_index(clause_name)
99
+ rule_at_index = -1
100
+ clause_at_index = -1
101
+ @feature_flag_rules_list.length.times do |rule_index|
102
+ @feature_flag_clauses_list = @feature_flag_rules_list[rule_index]['clauses']
103
+ @feature_flag_clauses_list.length.times do |clause_index|
104
+ next unless @feature_flag_clauses_list[clause_index]['attribute'].eql? clause_name
105
+
106
+ rule_at_index = rule_index
107
+ clause_at_index = clause_index
108
+ break
109
+ end
110
+ end
111
+ [rule_at_index, clause_at_index]
112
+ end
113
+
114
+ def search_value_index(rule_at_index, clause_at_index, clause_value)
99
115
  value_at_index = -1
100
- feature_flag_hash.length.times do |index|
101
- next unless feature_flag_hash[index].to_s.include? attribute.to_s
116
+ @feature_flag_values_list = @feature_flag_rules_list[rule_at_index]['clauses'][clause_at_index]['values']
117
+ @feature_flag_values_list.length.times do |value_index|
118
+ next unless @feature_flag_values_list[value_index].eql? clause_value
102
119
 
103
- value_at_index = index
120
+ value_at_index = value_index
104
121
  break
105
122
  end
106
123
  value_at_index
107
124
  end
108
125
 
109
- def feature_flag_rules_clauses_index(flag, attribute, env = ENV['PROFILE'])
110
- @feature_flag_response = fetch_flag(flag, env)
111
- feature_flag_env = @feature_flag_response['environments'][env]
112
- @feature_flag_env_rules = feature_flag_env['rules']
113
- rule_index = search_value_in_hash(@feature_flag_env_rules, attribute)
114
- @feature_flag_env_rules_clauses = @feature_flag_env_rules[rule_index]['clauses']
115
- clause_index = search_value_in_hash(@feature_flag_env_rules_clauses, attribute)
116
- [rule_index, clause_index]
126
+ def rules_clauses_index(env, flag, clause_name)
127
+ feature_flag_response = fetch_flag_details(env, flag)
128
+ @feature_flag_rules_list = feature_flag_response['environments'][env]['rules']
129
+ search_rule_index_clause_index(clause_name)
117
130
  end
118
131
 
119
- def feature_flag_add_values_to_rules(flag, attribute, value, env = ENV['PROFILE'])
120
- @flag = flag
121
- @attribute = attribute
122
- @value = value
123
- @rule_index, @clause_index = feature_flag_rules_clauses_index(flag, attribute)
132
+ def get_values_from_clauses(env, flag, clause_name)
133
+ rule_at_index, clause_at_index = feature_flag_rules_clauses_index(env, flag, clause_name)
134
+ @feature_flag_rules_list[rule_at_index]['clauses'][clause_at_index]['values']
135
+ end
136
+
137
+ def add_values_to_clause(env, flag, clause_name, clause_value)
138
+ rule_at_index, clause_at_index = feature_flag_rules_clauses_index(env, flag, clause_name)
124
139
  request_url = "#{LAUNCH_DARKLY_FLAGS}/#{flag}"
125
- request_body = { 'op' => 'add', 'path' => "/environments/#{env}/rules/#{@rule_index}/clauses/#{@clause_index}/values/0", 'value' => value }
140
+ request_body = { 'op' => 'add', 'path' => "/environments/#{env}/rules/#{rule_at_index}/clauses/#{clause_at_index}/values/0", 'value' => clause_value }
126
141
  ld_request(:patch, request_url, [request_body])
127
142
  end
128
143
 
129
- def feature_flag_remove_values_to_rules(flag = @flag, attribute = @attribute, value = @value, env = ENV['PROFILE'])
130
- @rule_index, @clause_index = feature_flag_rules_clauses_index(flag, attribute, env = ENV['PROFILE']) unless flag || attribute
131
- feature_flag_env_rules_clauses_values = @feature_flag_env_rules_clauses[@clause_index]['values']
132
- value_index = search_value_in_hash(feature_flag_env_rules_clauses_values, value)
144
+ def remove_values_from_clause(env, flag, clause_name, clause_value)
145
+ rule_at_index, clause_at_index = feature_flag_rules_clauses_index(env, flag, clause_name)
146
+ value_at_index = search_value_index(rule_at_index, clause_at_index, clause_value)
147
+ puts "value_index: #{value_at_index}"
133
148
  request_url = "#{LAUNCH_DARKLY_FLAGS}/#{flag}"
134
- request_body = { 'op': 'test', 'path': "/environments/#{env}/rules/#{@rule_index}/clauses/#{@clause_index}/values/#{value_index}", 'value': value }, { 'op' => 'remove', 'path' => "/environments/#{env}/rules/#{@rule_index}/clauses/#{@clause_index}/values/#{value_index}" }
149
+ request_body = { 'op' => 'test', 'path' => "/environments/#{env}/rules/#{rule_at_index}/clauses/#{clause_at_index}/values/#{value_at_index}", 'value' => clause_value },
150
+ { 'op' => 'remove', 'path' => "/environments/#{env}/rules/#{rule_at_index}/clauses/#{clause_at_index}/values/#{value_at_index}" }
135
151
  ld_request(:patch, request_url, request_body)
136
152
  end
153
+
154
+ def delete_flag(flag)
155
+ request_url = "#{LAUNCH_DARKLY_FLAGS}/#{flag}"
156
+ ld_request(:delete, request_url)
157
+ end
137
158
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LaunchdarklyApiHelper
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -135,8 +135,8 @@ module LaunchdarklyApiHelper
135
135
  # == Here, 'developer_flag_for_regression' is the flag key and default is our Project name - Browserstack
136
136
  # == You can update any parameter of feature flag using this method
137
137
 
138
- def ld_toggle_flag_for_specific_environment(env, flag, flag_value = true)
139
- @launchdarkly_helper.toggle_flag_for_specific_environment(env, flag, flag_value)
138
+ def ld_toggle_specific_environment(env, flag, flag_value = true)
139
+ @launchdarkly_helper.toggle_specific_environment(env, flag, flag_value)
140
140
  end
141
141
 
142
142
  # == Get status of feature flag
@@ -144,12 +144,27 @@ module LaunchdarklyApiHelper
144
144
  #
145
145
  # [fetch_flag_toggle_status_response, feature_flag_variation_index_response, feature_flag_variation_value_response, feature_flag_variation_name_response]
146
146
 
147
- def ld_toggle_variation_served_status(env, flag)
148
- @launchdarkly_helper.toggle_variation_served_status(env, flag)
147
+ def ld_toggle_variation_served(env, flag)
148
+ @launchdarkly_helper.ld_toggle_variation_served(env, flag)
149
149
  end
150
150
 
151
- def delete_flag(flag)
152
- request_url = "#{LAUNCH_DARKLY_FLAGS}/#{flag}"
153
- ld_request(:delete, request_url)
151
+ def ld_rules_clauses_index(env, flag, clause_name)
152
+ @launchdarkly_helper.rules_clauses_index(env, flag, clause_name)
153
+ end
154
+
155
+ def ld_get_values_from_clauses(env, flag, clause_name)
156
+ @launchdarkly_helper.get_values_from_clauses(env, flag, clause_name)
157
+ end
158
+
159
+ def ld_add_values_to_clause(env, flag, clause_name, clause_value)
160
+ @launchdarkly_helper.add_values_to_clause(env, flag, clause_name, clause_value)
161
+ end
162
+
163
+ def ld__remove_values_from_clause(env, flag, clause_name, clause_value)
164
+ @launchdarkly_helper.remove_values_from_clause(env, flag, clause_name, clause_value)
165
+ end
166
+
167
+ def ld_delete_flag(flag)
168
+ @launchdarkly_helper.delete_flag(flag)
154
169
  end
155
170
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: launchdarkly_api_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - amit-singh-bisht
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-18 00:00:00.000000000 Z
11
+ date: 2022-11-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Write a longer description or delete this line.
14
14
  email: