launchdarkly_api_helper 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/README.md +191 -3
- data/lib/launchdarkly_api_helper/constants.rb +1 -1
- data/lib/launchdarkly_api_helper/launchdarkly_api_helper_class.rb +59 -38
- data/lib/launchdarkly_api_helper/version.rb +1 -1
- data/lib/launchdarkly_api_helper.rb +22 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f063313104693353f6dd3e18a6ecd69c5142b62eb3f072b08f96b8b51e9175e0
|
4
|
+
data.tar.gz: 1f83a4dc6665e8864605decdb1d265178232785d44cca584488533fe21bd4ce6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
5
|
+

|
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
|
-
|
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
|
|
@@ -59,18 +59,18 @@ class LaunchdarklyApiHelperClass
|
|
59
59
|
ld_request(:post, request_url, request_body)
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
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(
|
70
|
-
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?
|
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(
|
82
|
-
|
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(
|
86
|
-
|
85
|
+
def feature_flag_variation_name(details_response, index_response)
|
86
|
+
details_response['variations'][index_response]['name']
|
87
87
|
end
|
88
88
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
[
|
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
|
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
|
-
|
101
|
-
|
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 =
|
120
|
+
value_at_index = value_index
|
104
121
|
break
|
105
122
|
end
|
106
123
|
value_at_index
|
107
124
|
end
|
108
125
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
120
|
-
|
121
|
-
@
|
122
|
-
|
123
|
-
|
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/#{
|
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
|
130
|
-
|
131
|
-
|
132
|
-
value_index
|
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'
|
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
|
@@ -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
|
139
|
-
@launchdarkly_helper.
|
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
|
148
|
-
@launchdarkly_helper.
|
147
|
+
def ld_toggle_variation_served(env, flag)
|
148
|
+
@launchdarkly_helper.ld_toggle_variation_served(env, flag)
|
149
149
|
end
|
150
150
|
|
151
|
-
def
|
152
|
-
|
153
|
-
|
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.
|
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-
|
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:
|