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 +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
|
+
![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
|
-
|
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:
|